From 7d30b72d432aa9578fee8dcfac0e8760dec2bef2 Mon Sep 17 00:00:00 2001 From: Linh Vo Date: Tue, 21 Feb 2017 10:09:49 -0600 Subject: [PATCH 1/5] add restriction database --- client.go | 10 ++++++++++ cmd/pilosactl/main.go | 2 ++ db.go | 5 ++++- fragment.go | 6 +++--- frame.go | 9 +++++++-- pilosa.go | 16 ++++++++++++++++ pilosactl/import.go | 10 ++++++++++ 7 files changed, 52 insertions(+), 6 deletions(-) diff --git a/client.go b/client.go index 5c24920ff..bc6338053 100644 --- a/client.go +++ b/client.go @@ -149,6 +149,11 @@ func (c *Client) ExecuteQuery(ctx context.Context, db, query string, allowRedire return nil, ErrQueryRequired } + er := ValidateName(db) + if er != nil { + return nil, ErrName + } + // Encode query request. buf, err := proto.Marshal(&internal.QueryRequest{ DB: db, @@ -205,6 +210,11 @@ func (c *Client) ExecutePQL(ctx context.Context, db, query string) (interface{}, }.Encode(), } + er := ValidateName(db) + if er != nil { + return nil, ErrName + } + req, err := http.NewRequest("POST", u.String(), bytes.NewReader([]byte(query))) if err != nil { return nil, err diff --git a/cmd/pilosactl/main.go b/cmd/pilosactl/main.go index 331459c31..7c25d62cb 100644 --- a/cmd/pilosactl/main.go +++ b/cmd/pilosactl/main.go @@ -290,6 +290,7 @@ func (cmd *ExportCommand) Run(ctx context.Context) error { logger := log.New(cmd.Stderr, "", log.LstdFlags) // Validate arguments. + fmt.Print("1213224") if cmd.Database == "" { return pilosa.ErrDatabaseRequired } else if cmd.Frame == "" { @@ -959,6 +960,7 @@ func (cmd *BenchCommand) Run(ctx context.Context) error { // runSetBit executes a benchmark of random SetBit() operations. func (cmd *BenchCommand) runSetBit(ctx context.Context, client *pilosa.Client) error { + fmt.Print("Nodb") if cmd.N == 0 { return errors.New("operation count required") } else if cmd.Database == "" { diff --git a/db.go b/db.go index 2a4f1d6e0..9d4c6532a 100644 --- a/db.go +++ b/db.go @@ -274,7 +274,10 @@ func (db *DB) createFrameIfNotExists(name string) (*Frame, error) { } func (db *DB) newFrame(path, name string) *Frame { - f := NewFrame(path, db.name, name) + f, err := NewFrame(path, db.name, name) + if err != nil { + return nil + } f.LogOutput = db.LogOutput f.stats = db.stats.WithTags(fmt.Sprintf("frame:%s", name)) return f diff --git a/fragment.go b/fragment.go index 1181f1739..9bc542f93 100644 --- a/fragment.go +++ b/fragment.go @@ -213,11 +213,11 @@ func (f *Fragment) openCache() error { // Determine cache type from frame name. if strings.HasSuffix(f.frame, FrameSuffixRank) { c := NewRankCache() - c.ThresholdLength = 50000 - c.ThresholdIndex = 45000 + c.ThresholdLength = 500000 + c.ThresholdIndex = 450000 f.cache = c } else { - f.cache = NewLRUCache(50000) + f.cache = NewLRUCache(500000) } // Read cache data from disk. diff --git a/frame.go b/frame.go index 9cdb4c707..1971900e4 100644 --- a/frame.go +++ b/frame.go @@ -38,7 +38,12 @@ type Frame struct { } // NewFrame returns a new instance of frame. -func NewFrame(path, db, name string) *Frame { +func NewFrame(path, db, name string) (*Frame, error) { + err := ValidateName(db) + if err != nil { + return nil, err + } + return &Frame{ path: path, db: db, @@ -50,7 +55,7 @@ func NewFrame(path, db, name string) *Frame { stats: NopStatsClient, LogOutput: ioutil.Discard, - } + }, nil } // Name returns the name the frame was initialized with. diff --git a/pilosa.go b/pilosa.go index dff78ebb1..1a8bba840 100644 --- a/pilosa.go +++ b/pilosa.go @@ -4,6 +4,7 @@ import ( "errors" "github.com/pilosa/pilosa/internal" + "regexp" ) var ( @@ -16,6 +17,9 @@ var ( // ErrFrameRequired is returned when no frame is specified. ErrFrameRequired = errors.New("frame required") + // ErrFrameRequired is returned when no frame is specified. + ErrName = errors.New("name restricted to [a-z0-9_-.]") + // ErrFragmentNotFound is returned when a fragment does not exist. ErrFragmentNotFound = errors.New("fragment not found") @@ -75,3 +79,15 @@ func decodeProfile(pb *internal.Profile) *Profile { // TimeFormat is the go-style time format used to parse string dates. const TimeFormat = "2006-01-02T15:04" + + +// Restrict name using regex +func ValidateName(name string) error { + expr := regexp.MustCompile(`^([a-z0-9._-]{2,64}$)`) + validName := expr.FindStringSubmatchIndex(name) + + if len(validName) == 0 { + return ErrName + } + return nil +} \ No newline at end of file diff --git a/pilosactl/import.go b/pilosactl/import.go index 9d4ad63f4..40a735c61 100644 --- a/pilosactl/import.go +++ b/pilosactl/import.go @@ -15,6 +15,7 @@ import ( "time" "github.com/pilosa/pilosa" + "regexp" ) // ImportCommand represents a command for bulk importing data. @@ -104,7 +105,16 @@ func (cmd *ImportCommand) Run(ctx context.Context) error { } else if len(cmd.Paths) == 0 { return errors.New("path required") } + // Restrict frame name and database name with regex + dbError := pilosa.ValidateName(cmd.Database) + if dbError != nil { + return dbError + } + frameError := pilosa.ValidateName(cmd.Frame) + if frameError != nil { + return frameError + } // Create a client to the server. client, err := pilosa.NewClient(cmd.Host) if err != nil { From 69cfdb0df9fd8f2394e46058e7fcda84cc3e85ea Mon Sep 17 00:00:00 2001 From: Linh Vo Date: Thu, 2 Mar 2017 16:06:34 -0600 Subject: [PATCH 2/5] clean up --- cmd/pilosactl/main.go | 2 -- db_test.go | 2 +- fragment.go | 6 +++--- frame.go | 2 +- frame_test.go | 2 +- pilosa.go | 3 +-- 6 files changed, 7 insertions(+), 10 deletions(-) diff --git a/cmd/pilosactl/main.go b/cmd/pilosactl/main.go index 5491dbfca..bb22d14ac 100644 --- a/cmd/pilosactl/main.go +++ b/cmd/pilosactl/main.go @@ -303,7 +303,6 @@ func (cmd *ExportCommand) Run(ctx context.Context) error { logger := log.New(cmd.Stderr, "", log.LstdFlags) // Validate arguments. - fmt.Print("1213224") if cmd.Database == "" { return pilosa.ErrDatabaseRequired } else if cmd.Frame == "" { @@ -973,7 +972,6 @@ func (cmd *BenchCommand) Run(ctx context.Context) error { // runSetBit executes a benchmark of random SetBit() operations. func (cmd *BenchCommand) runSetBit(ctx context.Context, client *pilosa.Client) error { - fmt.Print("Nodb") if cmd.N == 0 { return errors.New("operation count required") } else if cmd.Database == "" { diff --git a/db_test.go b/db_test.go index f0bdc60e2..96120dc1e 100644 --- a/db_test.go +++ b/db_test.go @@ -149,4 +149,4 @@ func TestDB_InvalidName(t *testing.T) { if db != nil { t.Fatalf("unexpected db name %s", db) } -} \ No newline at end of file +} diff --git a/fragment.go b/fragment.go index 9bc542f93..1181f1739 100644 --- a/fragment.go +++ b/fragment.go @@ -213,11 +213,11 @@ func (f *Fragment) openCache() error { // Determine cache type from frame name. if strings.HasSuffix(f.frame, FrameSuffixRank) { c := NewRankCache() - c.ThresholdLength = 500000 - c.ThresholdIndex = 450000 + c.ThresholdLength = 50000 + c.ThresholdIndex = 45000 f.cache = c } else { - f.cache = NewLRUCache(500000) + f.cache = NewLRUCache(50000) } // Read cache data from disk. diff --git a/frame.go b/frame.go index 8ec419057..fa47517c5 100644 --- a/frame.go +++ b/frame.go @@ -46,7 +46,7 @@ type Frame struct { } // NewFrame returns a new instance of frame. -func NewFrame(path, db, name string) (*Frame, error){ +func NewFrame(path, db, name string) (*Frame, error) { err := ValidateName(name) if err != nil { return nil, err diff --git a/frame_test.go b/frame_test.go index 34f03ee15..042bd751e 100644 --- a/frame_test.go +++ b/frame_test.go @@ -96,7 +96,7 @@ func (f *Frame) Reopen() error { path, db, name := f.Path(), f.DB(), f.Name() f.Frame, err = pilosa.NewFrame(path, db, name) - if err != nil{ + if err != nil { return err } diff --git a/pilosa.go b/pilosa.go index f6efb0987..14e5ef203 100644 --- a/pilosa.go +++ b/pilosa.go @@ -80,7 +80,6 @@ func decodeProfile(pb *internal.Profile) *Profile { // TimeFormat is the go-style time format used to parse string dates. const TimeFormat = "2006-01-02T15:04" - // Restrict name using regex func ValidateName(name string) error { expr := regexp.MustCompile(`^([a-z0-9._-]{1,64}$)`) @@ -89,4 +88,4 @@ func ValidateName(name string) error { return ErrName } return nil -} \ No newline at end of file +} From c6a502efed6f089306f821b4452c6d8ea31efd79 Mon Sep 17 00:00:00 2001 From: Linh Vo Date: Mon, 6 Mar 2017 11:03:17 -0600 Subject: [PATCH 3/5] fix review --- client.go | 10 ---------- db.go | 6 +++--- frame.go | 6 +++--- pilosa.go | 15 ++++----------- 4 files changed, 10 insertions(+), 27 deletions(-) diff --git a/client.go b/client.go index bfe4dc57e..e7d0eaf85 100644 --- a/client.go +++ b/client.go @@ -194,11 +194,6 @@ func (c *Client) ExecuteQuery(ctx context.Context, db, query string, allowRedire return nil, ErrQueryRequired } - er := ValidateName(db) - if er != nil { - return nil, ErrName - } - // Encode query request. buf, err := proto.Marshal(&internal.QueryRequest{ DB: db, @@ -255,11 +250,6 @@ func (c *Client) ExecutePQL(ctx context.Context, db, query string) (interface{}, }.Encode(), } - er := ValidateName(db) - if er != nil { - return nil, ErrName - } - req, err := http.NewRequest("POST", u.String(), bytes.NewReader([]byte(query))) if err != nil { return nil, err diff --git a/db.go b/db.go index 9348c97b6..6ad81e16b 100644 --- a/db.go +++ b/db.go @@ -49,9 +49,9 @@ type DB struct { // NewDB returns a new instance of DB. func NewDB(path, name string) (*DB, error) { - err := ValidateName(name) - if err != nil { - return nil, err + validName := Exp.FindStringSubmatchIndex(name) + if len(validName) == 0 { + return nil, ErrName } return &DB{ diff --git a/frame.go b/frame.go index fa47517c5..368cde821 100644 --- a/frame.go +++ b/frame.go @@ -47,9 +47,9 @@ type Frame struct { // NewFrame returns a new instance of frame. func NewFrame(path, db, name string) (*Frame, error) { - err := ValidateName(name) - if err != nil { - return nil, err + validName := Exp.FindStringSubmatchIndex(name) + if len(validName) == 0 { + return nil, ErrName } return &Frame{ diff --git a/pilosa.go b/pilosa.go index 14e5ef203..b3cee7450 100644 --- a/pilosa.go +++ b/pilosa.go @@ -20,13 +20,16 @@ var ( ErrFrameNotFound = errors.New("frame not found") // ErrFrameRequired is returned when no frame is specified. - ErrName = errors.New("name restricted to [a-z0-9_-.]") + ErrName = errors.New("name restricted to [a-z0-9_-]") // ErrFragmentNotFound is returned when a fragment does not exist. ErrFragmentNotFound = errors.New("fragment not found") ErrQueryRequired = errors.New("query required") ) +// Regular expression to valuate db and frame's name +var Exp = regexp.MustCompile(`^([a-z0-9._-]{1,64}$)`) + // Profile represents vertical column in a database. // A profile can have a set of attributes attached to it. type Profile struct { @@ -79,13 +82,3 @@ func decodeProfile(pb *internal.Profile) *Profile { // TimeFormat is the go-style time format used to parse string dates. const TimeFormat = "2006-01-02T15:04" - -// Restrict name using regex -func ValidateName(name string) error { - expr := regexp.MustCompile(`^([a-z0-9._-]{1,64}$)`) - validName := expr.FindStringSubmatchIndex(name) - if len(validName) == 0 { - return ErrName - } - return nil -} From 28580fd3540f3f793c71124ec26c09d479c0940e Mon Sep 17 00:00:00 2001 From: Linh Vo Date: Mon, 6 Mar 2017 11:10:23 -0600 Subject: [PATCH 4/5] remove validate name from client --- pilosactl/import.go | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/pilosactl/import.go b/pilosactl/import.go index 80e9a2973..313c5da99 100644 --- a/pilosactl/import.go +++ b/pilosactl/import.go @@ -104,16 +104,6 @@ func (cmd *ImportCommand) Run(ctx context.Context) error { } else if len(cmd.Paths) == 0 { return errors.New("path required") } - // Restrict frame name and database name with regex - dbError := pilosa.ValidateName(cmd.Database) - if dbError != nil { - return dbError - } - - frameError := pilosa.ValidateName(cmd.Frame) - if frameError != nil { - return frameError - } // Create a client to the server. client, err := pilosa.NewClient(cmd.Host) if err != nil { From 4e31d02979d9ece4099adcfaf37f0d510473e7b0 Mon Sep 17 00:00:00 2001 From: Linh Vo Date: Mon, 6 Mar 2017 12:31:51 -0600 Subject: [PATCH 5/5] wrap regexp in function --- db.go | 6 +++--- frame.go | 6 +++--- pilosa.go | 13 ++++++++++++- 3 files changed, 18 insertions(+), 7 deletions(-) diff --git a/db.go b/db.go index 6ad81e16b..9348c97b6 100644 --- a/db.go +++ b/db.go @@ -49,9 +49,9 @@ type DB struct { // NewDB returns a new instance of DB. func NewDB(path, name string) (*DB, error) { - validName := Exp.FindStringSubmatchIndex(name) - if len(validName) == 0 { - return nil, ErrName + err := ValidateName(name) + if err != nil { + return nil, err } return &DB{ diff --git a/frame.go b/frame.go index 368cde821..fa47517c5 100644 --- a/frame.go +++ b/frame.go @@ -47,9 +47,9 @@ type Frame struct { // NewFrame returns a new instance of frame. func NewFrame(path, db, name string) (*Frame, error) { - validName := Exp.FindStringSubmatchIndex(name) - if len(validName) == 0 { - return nil, ErrName + err := ValidateName(name) + if err != nil { + return nil, err } return &Frame{ diff --git a/pilosa.go b/pilosa.go index b3cee7450..b3620a900 100644 --- a/pilosa.go +++ b/pilosa.go @@ -28,7 +28,8 @@ var ( ) // Regular expression to valuate db and frame's name -var Exp = regexp.MustCompile(`^([a-z0-9._-]{1,64}$)`) +// Todo: remove . when frame doesn't require . for topN +var nameRegexp = regexp.MustCompile(`^([a-z0-9._-]{1,64}$)`) // Profile represents vertical column in a database. // A profile can have a set of attributes attached to it. @@ -82,3 +83,13 @@ func decodeProfile(pb *internal.Profile) *Profile { // TimeFormat is the go-style time format used to parse string dates. const TimeFormat = "2006-01-02T15:04" + + +// Restrict name using regex +func ValidateName(name string) error { + validName := nameRegexp.Match([]byte(name)) + if validName == false{ + return ErrName + } + return nil +} \ No newline at end of file