featurebase/cli/parts.go
Travis Turner 7a7bb0c928
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.
2023-03-06 13:31:15 -06:00

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
}