mirror of
https://github.com/featurebasedb/featurebase.git
synced 2026-09-07 17:15:56 +00:00
Fold decimal(scale) into kafka.source-type
This commit is contained in:
parent
634553d3c3
commit
6107ddef47
3 changed files with 68 additions and 18 deletions
|
|
@ -381,9 +381,14 @@ func (cmd *Command) setupConfig() error {
|
|||
return errors.Wrap(err, "cleaning config")
|
||||
}
|
||||
|
||||
flds, err := kafka.ConfigToFields(cfg)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "getting fields from config")
|
||||
}
|
||||
|
||||
cmd.kafkaRunner = kafka.NewRunner(
|
||||
cleanCfg,
|
||||
batch.NewSQLBatcher(cmd, kafka.ConfigToFields(cfg)),
|
||||
batch.NewSQLBatcher(cmd, flds),
|
||||
cmd.Stderr,
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ import (
|
|||
)
|
||||
|
||||
type Config struct {
|
||||
Hosts []string `mapstructure:"hosts" help: "Kafka hosts."`
|
||||
Hosts []string `mapstructure:"hosts" help:"Kafka hosts."`
|
||||
Group string `mapstructure:"group" help:"Kafka group."`
|
||||
Topics []string `mapstructure:"topics" help:"Kafka topics to read from."`
|
||||
|
||||
|
|
@ -38,15 +38,9 @@ type ConfigForIDK struct {
|
|||
|
||||
type Field struct {
|
||||
Name string `mapstructure:"name"`
|
||||
Type string `mapstructure:"type"`
|
||||
SourceType string `mapstructure:"source-type"`
|
||||
SourcePath []string `mapstructure:"source-path"`
|
||||
PrimaryKey bool `mapstructure:"primary-key"`
|
||||
|
||||
Options FieldOptions `mapstructure:"options"`
|
||||
}
|
||||
|
||||
type FieldOptions struct {
|
||||
Scale int64 `mapstructure:"scale"`
|
||||
}
|
||||
|
||||
// ValidateConfig validates the config is usable.
|
||||
|
|
@ -104,7 +98,7 @@ func ConvertConfig(c Config) (ConfigForIDK, error) {
|
|||
foundPK = true
|
||||
}
|
||||
|
||||
typ, err := dax.BaseTypeFromString(fld.Type)
|
||||
typ, quals, err := dax.SplitFieldType(fld.SourceType)
|
||||
if err != nil {
|
||||
return out, errors.Wrap(err, "getting base type")
|
||||
}
|
||||
|
|
@ -123,7 +117,10 @@ func ConvertConfig(c Config) (ConfigForIDK, error) {
|
|||
case dax.BaseTypeInt:
|
||||
// We don't have to handle min/max because we don't create the table.
|
||||
case dax.BaseTypeDecimal:
|
||||
rawFld.Config = []byte(fmt.Sprintf(`{"scale":%d}`, fld.Options.Scale))
|
||||
if len(quals) != 1 {
|
||||
return out, errors.Errorf("expected decimal scale")
|
||||
}
|
||||
rawFld.Config = []byte(fmt.Sprintf(`{"scale":%d}`, quals[0]))
|
||||
case dax.BaseTypeID:
|
||||
rawFld.Config = []byte("{\"mutex\":true}")
|
||||
case dax.BaseTypeIDSet:
|
||||
|
|
@ -149,7 +146,7 @@ func ConvertConfig(c Config) (ConfigForIDK, error) {
|
|||
|
||||
// ConfigToFields returns a list of *dax.Field based on the IDField and Fields
|
||||
// in the Config.
|
||||
func ConfigToFields(c Config) []*dax.Field {
|
||||
func ConfigToFields(c Config) ([]*dax.Field, error) {
|
||||
// We don't know if a primary key will be found, so we can't set the
|
||||
// capacity to `len(c.Fields)-1`.
|
||||
out := make([]*dax.Field, 0, len(c.Fields))
|
||||
|
|
@ -158,15 +155,27 @@ func ConfigToFields(c Config) []*dax.Field {
|
|||
if fld.PrimaryKey {
|
||||
continue
|
||||
}
|
||||
typ, quals, err := dax.SplitFieldType(fld.SourceType)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "splitting field type")
|
||||
}
|
||||
dfld := &dax.Field{
|
||||
Name: dax.FieldName(fld.Name),
|
||||
Type: dax.BaseType(fld.Type),
|
||||
Options: dax.FieldOptions{
|
||||
Scale: fld.Options.Scale,
|
||||
},
|
||||
Type: typ,
|
||||
}
|
||||
switch typ {
|
||||
case dax.BaseTypeDecimal:
|
||||
if len(quals) != 1 {
|
||||
return nil, errors.Errorf("expected decimal scale")
|
||||
}
|
||||
scale, ok := quals[0].(int64)
|
||||
if !ok {
|
||||
return nil, errors.Errorf("invalid decimal scale: %v", quals[0])
|
||||
}
|
||||
dfld.Options.Scale = scale
|
||||
}
|
||||
out = append(out, dfld)
|
||||
}
|
||||
|
||||
return out
|
||||
return out, nil
|
||||
}
|
||||
|
|
|
|||
38
dax/table.go
38
dax/table.go
|
|
@ -693,6 +693,42 @@ func BaseTypeFromString(s string) (BaseType, error) {
|
|||
}
|
||||
}
|
||||
|
||||
// SplitFieldType splits a string into a BaseType and, when applicable, a slice
|
||||
// of qualifiers for that type. For example, the string `decimal(2)` would be
|
||||
// split into BaseType `decimal` and []interface{}{int64(2)}.
|
||||
func SplitFieldType(s string) (BaseType, []interface{}, error) {
|
||||
var base string
|
||||
var paren string
|
||||
|
||||
parts := strings.Split(s, "(")
|
||||
base = parts[0]
|
||||
if len(parts) > 1 {
|
||||
parenParts := strings.Split(parts[1], ")")
|
||||
if len(parenParts) != 2 {
|
||||
return "", nil, errors.Errorf("invalid type qualifier: %s", s)
|
||||
}
|
||||
paren = parenParts[0]
|
||||
}
|
||||
|
||||
baseType, err := BaseTypeFromString(base)
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
|
||||
// Handle the string found in parenthesis.
|
||||
args := []interface{}{}
|
||||
switch baseType {
|
||||
case BaseTypeDecimal:
|
||||
scale, err := strconv.ParseInt(paren, 10, 64)
|
||||
if err != nil {
|
||||
return "", nil, errors.Wrapf(err, "parsing int from string: %s", paren)
|
||||
}
|
||||
args = append(args, scale)
|
||||
}
|
||||
|
||||
return baseType, args, nil
|
||||
}
|
||||
|
||||
// Field represents a field and its configuration.
|
||||
type Field struct {
|
||||
Name FieldName `json:"name"`
|
||||
|
|
@ -707,7 +743,7 @@ func (f *Field) String() string {
|
|||
return string(f.Name)
|
||||
}
|
||||
|
||||
// Definition returns the field name along with its parenthetical (when
|
||||
// Definition returns the field type along with its parenthetical (when
|
||||
// applicable).
|
||||
func (f *Field) Definition() string {
|
||||
switch f.Type {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue