From 568320ec6deaccc6e628e55bfecbc6ace8062da6 Mon Sep 17 00:00:00 2001 From: Linh Vo Date: Mon, 19 Jun 2017 11:37:01 -0500 Subject: [PATCH] fix reviews and add more test --- frame.go | 2 +- index.go | 63 ++++++++++++++++++++++----------------------- index_test.go | 22 ++++++++++++++++ input_definition.go | 28 +++++++++++++++++--- 4 files changed, 79 insertions(+), 36 deletions(-) diff --git a/frame.go b/frame.go index dbc26541e..f694c9e97 100644 --- a/frame.go +++ b/frame.go @@ -653,7 +653,7 @@ type FrameOptions struct { TimeQuantum TimeQuantum `json:"timeQuantum,omitempty"` } -// Encode converts o into its internal representation. +// Encode converts i into its internal representation. func (o *FrameOptions) Encode() *internal.FrameMeta { return &internal.FrameMeta{ RowLabel: o.RowLabel, diff --git a/index.go b/index.go index 581da85a4..c0877f0d7 100644 --- a/index.go +++ b/index.go @@ -31,8 +31,8 @@ import ( // Default index settings. const ( - DefaultColumnLabel = "columnID" - InputDefinitionRepo = ".input-definitions" + DefaultColumnLabel = "columnID" + InputDefinitionDir = ".input-definitions" ) // Index represents a container for frames. @@ -176,7 +176,7 @@ func (i *Index) openFrames() error { } for _, fi := range fis { - if !fi.IsDir() || fi.Name() == InputDefinitionRepo { + if !fi.IsDir() || fi.Name() == InputDefinitionDir { continue } @@ -336,9 +336,9 @@ func (i *Index) SetTimeQuantum(q TimeQuantum) error { // FramePath returns the path to a frame in the index. func (i *Index) FramePath(name string) string { return filepath.Join(i.path, name) } -// InputDefPath returns the path to a inputdefinition in the index. -func (i *Index) InputDefPath() string { - return filepath.Join(i.path, InputDefinitionRepo) +// InputDefinitionPath returns the path to a inputdefinition in the index. +func (i *Index) InputDefinitionPath() string { + return filepath.Join(i.path, InputDefinitionDir) } // Frame returns a frame in the index by name. @@ -584,7 +584,7 @@ type IndexOptions struct { TimeQuantum TimeQuantum `json:"timeQuantum,omitempty"` } -// Encode converts o into its internal representation. +// Encode converts i into its internal representation. func (o *IndexOptions) Encode() *internal.IndexMeta { return &internal.IndexMeta{ ColumnLabel: o.ColumnLabel, @@ -645,7 +645,7 @@ func (i *Index) createInputDefinition(pb *internal.InputDefinition) (*InputDefin } // Initialize input definition. - inputDef, err := i.newInputDefinition(i.InputDefPath(), pb.Name) + inputDef, err := i.newInputDefinition(pb.Name) if err != nil { return nil, err } @@ -658,13 +658,13 @@ func (i *Index) createInputDefinition(pb *internal.InputDefinition) (*InputDefin return inputDef, nil } -func (i *Index) newInputDefinition(path, name string) (*InputDefinition, error) { - f, err := NewInputDefinition(path, i.name, name) +func (i *Index) newInputDefinition(name string) (*InputDefinition, error) { + inputDef, err := NewInputDefinition(i.InputDefinitionPath(), i.name, name) if err != nil { return nil, err } - f.broadcaster = i.broadcaster - return f, nil + inputDef.broadcaster = i.broadcaster + return inputDef, nil } // DeleteInputDefinition removes a input definition from the index. @@ -679,7 +679,7 @@ func (i *Index) DeleteInputDefinition(name string) error { } // Delete input definition file. - if err := os.Remove(filepath.Join(i.InputDefPath(), name)); err != nil { + if err := os.Remove(filepath.Join(i.InputDefinitionPath(), name)); err != nil { return err } @@ -690,32 +690,31 @@ func (i *Index) DeleteInputDefinition(name string) error { // openInputDefinition opens and initializes the input definitions inside the index. func (i *Index) openInputDefinition() error { - inputDefs, err := os.Open(i.path) - if err != nil { + inputDef, err := os.Open(i.InputDefinitionPath()) + if os.IsNotExist(err) { + return nil + } else if err != nil { return err } - defer inputDefs.Close() + defer inputDef.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()) + inputFiles, err := inputDef.Readdir(0) + for _, file := range inputFiles { + input, err := i.newInputDefinition(file.Name()) 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 + + // Create frame if it doesn't exist + for _, fr := range input.frames { + _, err := i.CreateFrame(fr.Name, fr.Options) + if err == ErrFrameExists { + continue + } else if err != nil { + return nil } - input.Open() - i.inputDefinitions[file.Name()] = input } } diff --git a/index_test.go b/index_test.go index 5d5e03ab3..f948310ca 100644 --- a/index_test.go +++ b/index_test.go @@ -314,3 +314,25 @@ func TestIndex_DeleteInputDefinition(t *testing.T) { t.Fatal("input definition isn't deleted") } } + +func TestIndex_CreateFrameWhenOpenInputDefinition(t *testing.T) { + index := MustOpenIndex() + defer index.Close() + + // Create Input Definition. + frames := internal.Frame{Name: "f", Meta: &internal.FrameMeta{RowLabel: "row"}} + action := internal.Action{Frame: "f", ValueDestination: "map", ValueMap: map[string]uint64{"Green": 1}} + fields := internal.InputDefinitionField{Name: "id", PrimaryKey: true, Actions: []*internal.Action{&action}} + def := internal.InputDefinition{Name: "test", Frames: []*internal.Frame{&frames}, Fields: []*internal.InputDefinitionField{&fields}} + input, err := index.CreateInputDefinition(&def) + if err != nil { + t.Fatal(err) + } + + input.AddFrame(pilosa.InputFrame{Name: "f1"}) + index.Reopen() + if index.Frame("f1") == nil { + t.Fatal("Frame does not created when open index") + } + +} diff --git a/input_definition.go b/input_definition.go index 20c2a6f0b..e6bb5e972 100644 --- a/input_definition.go +++ b/input_definition.go @@ -1,3 +1,17 @@ +// Copyright 2017 Pilosa Corp. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + package pilosa import ( @@ -213,14 +227,22 @@ type InputDefinitionInfo struct { } // Encode converts InputDefinitionInfo into its internal representation. -func (o *InputDefinitionInfo) Encode() *internal.InputDefinition { +func (i *InputDefinitionInfo) Encode() *internal.InputDefinition { var def internal.InputDefinition - for _, f := range o.Frames { + for _, f := range i.Frames { def.Frames = append(def.Frames, &internal.Frame{Name: f.Name, Meta: f.Options.Encode()}) } - for _, f := range o.Fields { + for _, f := range i.Fields { def.Fields = append(def.Fields, f.Encode()) } return &def } + +func (i *InputDefinition) AddFrame(frame InputFrame) error { + i.frames = append(i.frames, frame) + if err := i.saveMeta(); err != nil { + return err + } + return nil +}