mirror of
https://github.com/featurebasedb/featurebase.git
synced 2026-10-07 11:27:50 +00:00
add validation for input definition fields
This commit is contained in:
parent
3cecd74e2e
commit
6d12478e6b
2 changed files with 98 additions and 0 deletions
|
|
@ -19,10 +19,14 @@ import (
|
|||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/gogo/protobuf/proto"
|
||||
"github.com/pilosa/pilosa/internal"
|
||||
)
|
||||
|
||||
var ValidValueDestination = []string{"map", "valueToRow", "stringToBool"}
|
||||
|
||||
// InputDefinition represents a container for the data input definition.
|
||||
type InputDefinition struct {
|
||||
name string
|
||||
|
|
@ -89,9 +93,22 @@ func (i *InputDefinition) LoadDefinition(pb *internal.InputDefinition) error {
|
|||
i.frames = append(i.frames, inputFrame)
|
||||
}
|
||||
|
||||
numPrimaryKey := 0
|
||||
countRowID := make(map[uint64]bool)
|
||||
for _, field := range pb.Fields {
|
||||
var actions []Action
|
||||
for _, action := range field.Actions {
|
||||
if err := i.ValidateAction(action); err != nil {
|
||||
return err
|
||||
}
|
||||
if action.RowID != 0 {
|
||||
_, ok := countRowID[action.RowID]
|
||||
if !ok {
|
||||
countRowID[action.RowID] = true
|
||||
} else {
|
||||
return fmt.Errorf("duplicate rowID with other field: %s", action.RowID)
|
||||
}
|
||||
}
|
||||
actions = append(actions, Action{
|
||||
Frame: action.Frame,
|
||||
ValueDestination: action.ValueDestination,
|
||||
|
|
@ -100,6 +117,14 @@ func (i *InputDefinition) LoadDefinition(pb *internal.InputDefinition) error {
|
|||
})
|
||||
}
|
||||
|
||||
if field.PrimaryKey {
|
||||
numPrimaryKey += 1
|
||||
}
|
||||
|
||||
if numPrimaryKey > 1 {
|
||||
return errors.New("duplicate primaryKey with other field")
|
||||
}
|
||||
|
||||
inputField := Field{
|
||||
Name: field.Name,
|
||||
PrimaryKey: field.PrimaryKey,
|
||||
|
|
@ -246,3 +271,28 @@ func (i *InputDefinition) AddFrame(frame InputFrame) error {
|
|||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i *InputDefinition) ValidateAction(action *internal.Action) error {
|
||||
validValues := make(map[string]bool)
|
||||
for _, val := range ValidValueDestination {
|
||||
validValues[val] = true
|
||||
}
|
||||
if _, ok := validValues[action.ValueDestination]; !ok {
|
||||
return fmt.Errorf("invalid ValueDestination: %s", action.ValueDestination)
|
||||
}
|
||||
|
||||
switch action.ValueDestination {
|
||||
case "map":
|
||||
if len(action.ValueMap) == 0 {
|
||||
return errors.New("valueMap required for map")
|
||||
}
|
||||
case "stringToBool":
|
||||
if action.RowID == 0 {
|
||||
return errors.New("rowID required for stringToBool")
|
||||
}
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ import (
|
|||
|
||||
"github.com/pilosa/pilosa"
|
||||
"github.com/pilosa/pilosa/internal"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func TestInputDefinition_Open(t *testing.T) {
|
||||
|
|
@ -93,3 +94,50 @@ func TestInputDefinition_Encoding(t *testing.T) {
|
|||
t.Fatalf("unexpected ValueDestination: %v", internalDef.Fields[1].Actions[0])
|
||||
}
|
||||
}
|
||||
|
||||
func TestInputDefinition_LoadDefinition(t *testing.T) {
|
||||
index := MustOpenIndex()
|
||||
defer index.Close()
|
||||
|
||||
// Create Input Definition.
|
||||
input := pilosa.InputDefinition{}
|
||||
frames := internal.Frame{Name: "f", Meta: &internal.FrameMeta{RowLabel: "row"}}
|
||||
action := internal.Action{Frame: "f", ValueDestination: "ValueToRow", ValueMap: map[string]uint64{"Green": 1}}
|
||||
field := internal.InputDefinitionField{Name: "id", PrimaryKey: true, Actions: []*internal.Action{&action}}
|
||||
def := &internal.InputDefinition{Name: "test", Frames: []*internal.Frame{&frames}, Fields: []*internal.InputDefinitionField{&field}}
|
||||
err := input.LoadDefinition(def)
|
||||
if !strings.Contains(err.Error(), "invalid ValueDestination") {
|
||||
t.Fatalf("Expected invalid ValueDestination error, actual error: %s", err)
|
||||
}
|
||||
|
||||
action = internal.Action{Frame: "f", ValueDestination: "stringToBool", ValueMap: map[string]uint64{"Green": 1}}
|
||||
def = &internal.InputDefinition{Name: "test", Frames: []*internal.Frame{&frames}, Fields: []*internal.InputDefinitionField{&field}}
|
||||
err = input.LoadDefinition(def)
|
||||
if !strings.Contains(err.Error(), "rowID required for stringToBool") {
|
||||
t.Fatalf("Expected rowID required for stringToBool error, actual error: %s", err)
|
||||
}
|
||||
|
||||
action = internal.Action{Frame: "f", ValueDestination: "map", RowID: 100}
|
||||
def = &internal.InputDefinition{Name: "test", Frames: []*internal.Frame{&frames}, Fields: []*internal.InputDefinitionField{&field}}
|
||||
err = input.LoadDefinition(def)
|
||||
if !strings.Contains(err.Error(), "valueMap required for map") {
|
||||
t.Fatalf("Expected valueMap required for map error, actual error: %s", err)
|
||||
}
|
||||
|
||||
action = internal.Action{Frame: "f", ValueDestination: "stringToBool", RowID: 100}
|
||||
action1 := internal.Action{Frame: "f", ValueDestination: "stringToBool", RowID: 101}
|
||||
field1 := internal.InputDefinitionField{Name: "newID", PrimaryKey: true, Actions: []*internal.Action{&action1}}
|
||||
def = &internal.InputDefinition{Name: "test", Frames: []*internal.Frame{&frames}, Fields: []*internal.InputDefinitionField{&field, &field1}}
|
||||
err = input.LoadDefinition(def)
|
||||
if !strings.Contains(err.Error(), "duplicate primaryKey with other field") {
|
||||
t.Fatalf("Expected duplicate primaryKey error, actual error: %s", err)
|
||||
}
|
||||
|
||||
action1 = internal.Action{Frame: "f", ValueDestination: "stringToBool", RowID: 100}
|
||||
field1 = internal.InputDefinitionField{Name: "id", PrimaryKey: true, Actions: []*internal.Action{&action1}}
|
||||
def = &internal.InputDefinition{Name: "test", Frames: []*internal.Frame{&frames}, Fields: []*internal.InputDefinitionField{&field, &field1}}
|
||||
err = input.LoadDefinition(def)
|
||||
if !strings.Contains(err.Error(), "duplicate rowID with other field") {
|
||||
t.Fatalf("Expected duplicate rowID with other field error, actual error: %s", err)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue