mirror of
https://github.com/featurebasedb/featurebase.git
synced 2026-08-28 10:54:59 +00:00
* Add kafka support to CLI (fbsql) This commit adds the ability to provide a `--kafka-config` command line argument referncing a toml file to configure kafka. * Move "Molecula Consumer" message to the logger; hide it in basic mode * Fold decimal(scale) into kafka.source-type * Build fbsql with cgo in docker for CI * Re-organize the fbsql kafka config and setup. Allow field config to use the table schema if no fields provided. * Display timestamp fields with format RFC3339Nano * remove kafkaRunner (no longer used) * Fix cli/batch test (and make sure it's not excluded from CI) The logic in our Makefile was exluding from tests any package with `/batch` in the package name. This excluded `/cli/batch`, which is not good. This commit changes the exclusion logic to include the `/v3` portion of the package name, so `/v3/batch`. * Rename Basic() to SetBasic()
136 lines
2.7 KiB
Go
136 lines
2.7 KiB
Go
package cli
|
|
|
|
import (
|
|
"fmt"
|
|
"io"
|
|
"os"
|
|
"strings"
|
|
)
|
|
|
|
// query is a collection of queryParts which, when applied together, make up an
|
|
// executable SQL query.
|
|
type query []queryPart
|
|
|
|
func (q query) String() string {
|
|
var sb strings.Builder
|
|
for i := range q {
|
|
sb.WriteString(q[i].String())
|
|
if i < len(q)-1 {
|
|
sb.WriteRune('\n')
|
|
}
|
|
}
|
|
return sb.String()
|
|
}
|
|
|
|
// Reader returns the query as an io.Reader so that it can be passed to, for
|
|
// example, http.Post().
|
|
func (q query) Reader() io.Reader {
|
|
readers := make([]io.Reader, 0, len(q))
|
|
for i := range q {
|
|
readers = append(readers, q[i].Reader())
|
|
}
|
|
return io.MultiReader(readers...)
|
|
}
|
|
|
|
// queryPart is an interface representing anything which can use to build up a
|
|
// query.
|
|
type queryPart interface {
|
|
fmt.Stringer
|
|
Reader() io.Reader
|
|
}
|
|
|
|
func newRawQuery(s string) query {
|
|
return []queryPart{
|
|
newPartRaw(s),
|
|
}
|
|
}
|
|
|
|
// ////////////////////////////////////////////////////////////////////////////
|
|
// raw
|
|
// ////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Ensure type implements interface.
|
|
var _ queryPart = (*partRaw)(nil)
|
|
|
|
type partRaw struct {
|
|
raw string
|
|
}
|
|
|
|
func newPartRaw(s string) *partRaw {
|
|
return &partRaw{
|
|
raw: s,
|
|
}
|
|
}
|
|
|
|
func (p *partRaw) Reader() io.Reader {
|
|
return strings.NewReader(p.raw + "\n")
|
|
}
|
|
|
|
func (p *partRaw) String() string {
|
|
return p.raw
|
|
}
|
|
|
|
// ////////////////////////////////////////////////////////////////////////////
|
|
// file
|
|
// ////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Ensure type implements interface.
|
|
var _ queryPart = (*partFile)(nil)
|
|
|
|
type partFile struct {
|
|
file *os.File
|
|
}
|
|
|
|
func newPartFile(f *os.File) *partFile {
|
|
return &partFile{
|
|
file: f,
|
|
}
|
|
}
|
|
|
|
func (p *partFile) Reader() io.Reader {
|
|
return p.file
|
|
}
|
|
|
|
func (p *partFile) String() string {
|
|
return fmt.Sprintf("[file: %s]", p.file.Name())
|
|
}
|
|
|
|
// ////////////////////////////////////////////////////////////////////////////
|
|
// batch file
|
|
// ////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Ensure type implements interface.
|
|
var _ queryPart = (*partBatchFile)(nil)
|
|
|
|
type partBatchFile struct {
|
|
file *os.File
|
|
}
|
|
|
|
func (p *partBatchFile) Reader() io.Reader {
|
|
return p.file
|
|
}
|
|
|
|
func (p *partBatchFile) String() string {
|
|
return p.file.Name()
|
|
}
|
|
|
|
// ////////////////////////////////////////////////////////////////////////////
|
|
// terminator (i.e. ";")
|
|
// ////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Ensure type implements interface.
|
|
var _ queryPart = (*partTerminator)(nil)
|
|
|
|
type partTerminator struct{}
|
|
|
|
func newPartTerminator() *partTerminator {
|
|
return &partTerminator{}
|
|
}
|
|
|
|
func (p *partTerminator) Reader() io.Reader {
|
|
return nil
|
|
}
|
|
|
|
func (p *partTerminator) String() string {
|
|
return terminationChar
|
|
}
|