From 0f3bb09ee8c9a281e129f56826ea9362a02eb533 Mon Sep 17 00:00:00 2001 From: Mithrandie Date: Sun, 9 Jul 2017 06:42:28 +0900 Subject: [PATCH 1/2] Fix some bugs. --- lib/csv/reader.go | 6 ++++- lib/csv/reader_test.go | 9 +++++++ lib/query/query.go | 5 ++++ lib/query/query_test.go | 44 +++++++++++++++++++++++++++++++--- lib/query/view.go | 52 ++++++++++++++++++++++++----------------- 5 files changed, 90 insertions(+), 26 deletions(-) diff --git a/lib/csv/reader.go b/lib/csv/reader.go index 8dca9162..9af27a57 100644 --- a/lib/csv/reader.go +++ b/lib/csv/reader.go @@ -109,7 +109,11 @@ func (r *Reader) parseRecord(withoutNull bool) ([]parser.Primary, error) { } if eol { - break + if fieldIndex < 1 && (parser.IsNull(field) || len(field.(parser.String).Value()) < 1) { + continue + } else { + break + } } fieldIndex++ diff --git a/lib/csv/reader_test.go b/lib/csv/reader_test.go index 48f71b78..3c99b5a8 100644 --- a/lib/csv/reader_test.go +++ b/lib/csv/reader_test.go @@ -89,6 +89,15 @@ var readAllTests = []struct { }, LineBreak: "", }, + { + Name: "Trailing empty lines", + Input: "a,b,c\nd,e,f\n\n", + Output: [][]parser.Primary{ + {parser.NewString("a"), parser.NewString("b"), parser.NewString("c")}, + {parser.NewString("d"), parser.NewString("e"), parser.NewString("f")}, + }, + LineBreak: cmd.LF, + }, { Name: "ExtraneousQuote", Input: "a,\"b\",\"ccc\ncc\nd,e,", diff --git a/lib/query/query.go b/lib/query/query.go index e4faef45..ba9d881e 100644 --- a/lib/query/query.go +++ b/lib/query/query.go @@ -722,6 +722,7 @@ func Update(query parser.UpdateQuery) ([]*View, error) { if viewsToUpdate[table.Name()], err = ViewCache.Get(table.Name()); err != nil { return nil, err } + viewsToUpdate[table.Name()].UpdateHeader(table.Name(), nil) updatedIndices[table.Name()] = []int{} } @@ -741,6 +742,9 @@ func Update(query parser.UpdateQuery) ([]*View, error) { if err != nil { return nil, err } + if _, ok := viewsToUpdate[viewref]; !ok { + return nil, errors.New(fmt.Sprintf("table %s is not specified in tables to update", viewref)) + } internalId, err := view.InternalRecordId(viewref, i) if err != nil { @@ -813,6 +817,7 @@ func Delete(query parser.DeleteQuery) ([]*View, error) { if viewsToDelete[table.Name()], err = ViewCache.Get(table.Name()); err != nil { return nil, err } + viewsToDelete[table.Name()].UpdateHeader(table.Name(), nil) deletedIndices[table.Name()] = []int{} } diff --git a/lib/query/query_test.go b/lib/query/query_test.go index 4a3fe229..e9ff2c49 100644 --- a/lib/query/query_test.go +++ b/lib/query/query_test.go @@ -2368,6 +2368,44 @@ var updateTests = []struct { }, { Name: "Update Query File Is Not Loaded Error", + Query: parser.UpdateQuery{ + Update: "update", + Tables: []parser.Expression{ + parser.Table{Object: parser.Identifier{Literal: "notexist"}}, + }, + Set: "set", + SetList: []parser.Expression{ + parser.UpdateSet{ + Field: parser.FieldReference{Column: parser.Identifier{Literal: "column2"}}, + Value: parser.FieldReference{Column: parser.Identifier{Literal: "column4"}}, + }, + }, + FromClause: parser.FromClause{ + Tables: []parser.Expression{ + parser.Table{Object: parser.Join{ + Table: parser.Table{ + Object: parser.Identifier{Literal: "table1"}, + Alias: parser.Identifier{Literal: "t1"}, + }, + JoinTable: parser.Table{ + Object: parser.Identifier{Literal: "table2"}, + Alias: parser.Identifier{Literal: "t2"}, + }, + Condition: parser.JoinCondition{ + On: parser.Comparison{ + LHS: parser.FieldReference{Column: parser.Identifier{Literal: "column1"}}, + RHS: parser.FieldReference{Column: parser.Identifier{Literal: "column3"}}, + Operator: parser.Token{Token: parser.COMPARISON_OP, Literal: "="}, + }, + }, + }}, + }, + }, + }, + Error: "file notexist is not loaded", + }, + { + Name: "Update Query Update Table Is Not Specified Error", Query: parser.UpdateQuery{ Update: "update", Tables: []parser.Expression{ @@ -2402,7 +2440,7 @@ var updateTests = []struct { }, }, }, - Error: "file table1 is not loaded", + Error: "table t1 is not specified in tables to update", }, { Name: "Update Query Update Field Error", @@ -2684,7 +2722,7 @@ var deleteTests = []struct { Query: parser.DeleteQuery{ Delete: "delete", Tables: []parser.Expression{ - parser.Table{Object: parser.Identifier{Literal: "table1"}}, + parser.Table{Object: parser.Identifier{Literal: "notexist"}}, }, FromClause: parser.FromClause{ Tables: []parser.Expression{ @@ -2708,7 +2746,7 @@ var deleteTests = []struct { }, }, }, - Error: "file table1 is not loaded", + Error: "file notexist is not loaded", }, } diff --git a/lib/query/view.go b/lib/query/view.go index dfbd31e0..3e743fa2 100644 --- a/lib/query/view.go +++ b/lib/query/view.go @@ -275,27 +275,33 @@ func loadView(table parser.Table, parentFilter Filter, useInternalId bool) (*Vie if _, ok := ViewCache.Exists(fileInfo.Path); !ok { file := os.Stdin defer file.Close() - err = loadViewFromFile(file, fileInfo, table.Name()) + if err := loadViewFromFile(file, fileInfo, table.Name()); err != nil { + return nil, err + } } else { if _, ok := ViewCache.HasAlias(table.Name()); !ok { ViewCache.SetAlias(table.Name(), fileInfo.Path) } } - if err == nil { - if useInternalId { - view, _ = ViewCache.GetWithInternalId(fileInfo.Path) - } else { - view, _ = ViewCache.Get(fileInfo.Path) - } + if useInternalId { + view, _ = ViewCache.GetWithInternalId(fileInfo.Path) + } else { + view, _ = ViewCache.Get(fileInfo.Path) } case parser.Identifier: tableIdentifier := table.Object.(parser.Identifier).Literal if strings.EqualFold(tableIdentifier, parentFilter.RecursiveTable.Name.Literal) && parentFilter.RecursiveTmpView != nil { view = parentFilter.RecursiveTmpView + if parentFilter.RecursiveTable.Name.Literal != table.Name() { + view.UpdateHeader(table.Name(), nil) + } } else if ct, err := parentFilter.CommonTables.Get(tableIdentifier); err == nil { view = ct + if tableIdentifier != table.Name() { + view.UpdateHeader(table.Name(), nil) + } } else if _, err := parentFilter.CommonTables.Get(table.Name()); err == nil { - err = errors.New(fmt.Sprintf("table name %s is duplicated", table.Name())) + return nil, errors.New(fmt.Sprintf("table name %s is duplicated", table.Name())) } else { flags := cmd.GetFlags() @@ -305,24 +311,29 @@ func loadView(table parser.Table, parentFilter Filter, useInternalId bool) (*Vie return nil, err } + commonTableName := parser.FormatTableName(fileInfo.Path) + if _, ok := ViewCache.Exists(fileInfo.Path); !ok { file, err := os.Open(fileInfo.Path) if err != nil { return nil, err } defer file.Close() - err = loadViewFromFile(file, fileInfo, table.Name()) - } else { - if _, ok := ViewCache.HasAlias(table.Name()); !ok { - ViewCache.SetAlias(table.Name(), fileInfo.Path) + if err := loadViewFromFile(file, fileInfo, commonTableName); err != nil { + return nil, err } } - if err == nil { - if useInternalId { - view, _ = ViewCache.GetWithInternalId(fileInfo.Path) - } else { - view, _ = ViewCache.Get(fileInfo.Path) - } + if _, ok := ViewCache.HasAlias(table.Name()); !ok { + ViewCache.SetAlias(table.Name(), fileInfo.Path) + } + + if useInternalId { + view, _ = ViewCache.GetWithInternalId(fileInfo.Path) + } else { + view, _ = ViewCache.Get(fileInfo.Path) + } + if commonTableName != table.Name() { + view.UpdateHeader(table.Name(), nil) } } case parser.Join: @@ -363,10 +374,7 @@ func loadView(table parser.Table, parentFilter Filter, useInternalId bool) (*Vie } } - if err != nil { - return nil, err - } - return view, nil + return view, err } func loadViewFromFile(file *os.File, fileInfo *FileInfo, reference string) error { From 545e0f40794c7a1230c5da1836580ff811ea0bbb Mon Sep 17 00:00:00 2001 From: Mithrandie Date: Sun, 9 Jul 2017 08:07:08 +0900 Subject: [PATCH 2/2] Update version for Release v0.2.8 --- main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.go b/main.go index ecf27709..0e797b29 100644 --- a/main.go +++ b/main.go @@ -11,7 +11,7 @@ import ( "github.com/urfave/cli" ) -var version = "v0.2.7" +var version = "v0.2.8" func main() { cli.AppHelpTemplate = appHHelpTemplate