expose input definition frames, fields

This commit is contained in:
Linh Vo 2017-06-12 23:43:03 -05:00
parent 1c2adda8e9
commit ea53216ff2
3 changed files with 130 additions and 110 deletions

215
index.go
View file

@ -162,40 +162,6 @@ func (i *Index) Open() error {
return nil
}
// openInputDefinition opens and initializes the input definitions inside the index.
func (i *Index) openInputDefinition() error {
inputDefs, err := os.Open(i.path)
if err != nil {
return err
}
defer inputDefs.Close()
fis, err := inputDefs.Readdir(0)
if err != nil {
return err
}
for _, fi := range fis {
if fi.Name() != InputDefinitionRepo {
continue
}
inputPath, err := os.Open(i.InputDefPath())
if err != nil {
return err
}
inputFiles, err := inputPath.Readdir(0)
for _, file := range inputFiles {
input, err := i.newInputDefinition(i.InputDefPath(), file.Name())
if err != nil {
return err
}
input.Open()
i.inputDefinitions[file.Name()] = input
}
}
return nil
}
// openFrames opens and initializes the frames inside the index.
func (i *Index) openFrames() error {
f, err := os.Open(i.path)
@ -412,47 +378,6 @@ func (i *Index) CreateFrame(name string, opt FrameOptions) (*Frame, error) {
return i.createFrame(name, opt)
}
// CreateInputDefinition creates a new input definition.
func (i *Index) CreateInputDefinition(name string, frames []InputFrame, field []Field) (*InputDefinition, error) {
// Ensure input definition doesn't already exist.
if i.inputDefinitions[name] != nil {
return nil, ErrInputDefinitionExists
}
return i.createInputDefinition(name, frames, field)
}
func (i *Index) createInputDefinition(name string, frames []InputFrame, fields []Field) (*InputDefinition, error) {
if name == "" {
return nil, errors.New("input-definition name required")
} else if len(frames) == 0 || len(fields) == 0 {
return nil, errors.New("frames and fields are required")
}
for _, fr := range frames {
_, err := i.CreateFrame(fr.Name, fr.Options)
if err == ErrFrameExists {
continue
} else if err != nil {
return nil, err
}
}
// Initialize input definition.
inputDef, err := i.newInputDefinition(i.InputDefPath(), name)
if err != nil {
return nil, err
}
inputDef.frames = frames
inputDef.fields = fields
if err = inputDef.saveMeta(); err != nil {
return nil, err
}
i.inputDefinitions[name] = inputDef
return inputDef, nil
}
// CreateFrameIfNotExists creates a frame with the given options if it doesn't exist.
func (i *Index) CreateFrameIfNotExists(name string, opt FrameOptions) (*Frame, error) {
i.mu.Lock()
@ -536,15 +461,6 @@ func (i *Index) newFrame(path, name string) (*Frame, error) {
return f, nil
}
func (i *Index) newInputDefinition(path, name string) (*InputDefinition, error) {
f, err := NewInputDefinition(path, i.name, name)
if err != nil {
return nil, err
}
f.broadcaster = i.broadcaster
return f, nil
}
// DeleteFrame removes a frame from the index.
func (i *Index) DeleteFrame(name string) error {
i.mu.Lock()
@ -572,32 +488,6 @@ func (i *Index) DeleteFrame(name string) error {
return nil
}
// DeleteFrame removes a frame from the index.
func (i *Index) DeleteInputDefinition(name string) error {
i.mu.Lock()
defer i.mu.Unlock()
// Ignore if input definition doesn't exist.
f := i.inputDefinition(name)
if f == nil {
return nil
}
//if err := f.Close(); err != nil {
// return err
//}
// Delete input definition file.
if err := os.Remove(filepath.Join(i.InputDefPath(), name)); err != nil {
return err
}
// Remove reference.
delete(i.inputDefinitions, name)
return nil
}
type indexSlice []*Index
func (p indexSlice) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
@ -711,3 +601,108 @@ type importData struct {
RowIDs []uint64
ColumnIDs []uint64
}
// CreateInputDefinition creates a new input definition.
func (i *Index) CreateInputDefinition(name string, frames []InputFrame, field []Field) (*InputDefinition, error) {
// Ensure input definition doesn't already exist.
if i.inputDefinitions[name] != nil {
return nil, ErrInputDefinitionExists
}
return i.createInputDefinition(name, frames, field)
}
func (i *Index) createInputDefinition(name string, frames []InputFrame, fields []Field) (*InputDefinition, error) {
if name == "" {
return nil, errors.New("input-definition name required")
} else if len(frames) == 0 || len(fields) == 0 {
return nil, errors.New("frames and fields are required")
}
for _, fr := range frames {
_, err := i.CreateFrame(fr.Name, fr.Options)
if err == ErrFrameExists {
continue
} else if err != nil {
return nil, err
}
}
// Initialize input definition.
inputDef, err := i.newInputDefinition(i.InputDefPath(), name)
if err != nil {
return nil, err
}
inputDef.frames = frames
inputDef.fields = fields
if err = inputDef.saveMeta(); err != nil {
return nil, err
}
i.inputDefinitions[name] = inputDef
return inputDef, nil
}
func (i *Index) newInputDefinition(path, name string) (*InputDefinition, error) {
f, err := NewInputDefinition(path, i.name, name)
if err != nil {
return nil, err
}
f.broadcaster = i.broadcaster
return f, nil
}
// DeleteFrame removes a frame from the index.
func (i *Index) DeleteInputDefinition(name string) error {
i.mu.Lock()
defer i.mu.Unlock()
// Ignore if input definition doesn't exist.
f := i.inputDefinition(name)
if f == nil {
return nil
}
// Delete input definition file.
if err := os.Remove(filepath.Join(i.InputDefPath(), name)); err != nil {
return err
}
// Remove reference.
delete(i.inputDefinitions, name)
return nil
}
// openInputDefinition opens and initializes the input definitions inside the index.
func (i *Index) openInputDefinition() error {
inputDefs, err := os.Open(i.path)
if err != nil {
return err
}
defer inputDefs.Close()
fis, err := inputDefs.Readdir(0)
if err != nil {
return err
}
for _, fi := range fis {
if fi.Name() != InputDefinitionRepo {
continue
}
inputPath, err := os.Open(i.InputDefPath())
if err != nil {
return err
}
inputFiles, err := inputPath.Readdir(0)
for _, file := range inputFiles {
input, err := i.newInputDefinition(i.InputDefPath(), file.Name())
if err != nil {
return err
}
input.Open()
i.inputDefinitions[file.Name()] = input
}
}
return nil
}

View file

@ -20,6 +20,7 @@ import (
"testing"
"github.com/pilosa/pilosa"
"reflect"
)
// Ensure index can open and retrieve a frame.
@ -239,3 +240,21 @@ func TestIndex_InvalidName(t *testing.T) {
t.Fatalf("unexpected index name %s", index)
}
}
func TestIndex_CreateInputDefinition(t *testing.T) {
index := MustOpenIndex()
defer index.Close()
// Create Input Definition.
frames := pilosa.InputFrame{Name: "f", Options: pilosa.FrameOptions{RowLabel: "row"}}
action := pilosa.Action{Frame: "f", ValueDestination: "map", ValueMap: map[string]uint64{"Green": 1}}
fields := pilosa.Field{Name: "id", PrimaryKey: true, Actions: []pilosa.Action{action}}
inputDef, err := index.CreateInputDefinition("test", []pilosa.InputFrame{frames}, []pilosa.Field{fields})
if err != nil {
t.Fatal(err)
} else if inputDef.Frames()[0] != frames {
t.Fatalf("unexpected input definition frames", inputDef.Frames())
} else if !reflect.DeepEqual(inputDef.Fields()[0], fields) {
t.Fatalf("unexpected input definition actions", inputDef.Fields())
}
}

View file

@ -39,6 +39,12 @@ func (i *InputDefinition) Index() string { return i.index }
// Path returns the path of the input definition was initialized with.
func (i *InputDefinition) Path() string { return i.path }
// Frames returns frames of the input definition was initialized with.
func (i *InputDefinition) Frames() []InputFrame { return i.frames }
// Fields returns frames of the input definition was initialized with.
func (i *InputDefinition) Fields() []Field { return i.fields }
func (i *InputDefinition) Open() error {
if err := func() error {
if err := os.MkdirAll(i.path, 0777); err != nil {