From 0212c9ec21d226ffe8cbaa4e701fd568d6aa8b85 Mon Sep 17 00:00:00 2001 From: Charles Daniels Date: Mon, 13 Sep 2021 22:45:18 -0400 Subject: [PATCH] fix behavior with empty keys --- logquery.go | 18 ++++++++++++------ logquery_test.go | 4 +++- parser/parser.go | 7 +++++++ parser/parser_test.go | 14 ++++++++++++++ 4 files changed, 36 insertions(+), 7 deletions(-) diff --git a/logquery.go b/logquery.go index cb9d824..9627587 100644 --- a/logquery.go +++ b/logquery.go @@ -265,7 +265,13 @@ func RunQuery(stream io.Reader, output io.Writer, query string, format OutputFor // decide if we need to add any additional database // columns or modify our prepared statements. for key := range rec { - if _, ok := keys[key]; !ok { + + // In case the key may have an upper case letter in it, + // we need to later be able to access it by its + // all-lower version. + rec[strings.ToLower(key)] = rec[key] + + if _, ok := keys[strings.ToLower(key)]; !ok { // We haven't seen this column before. if madeTable { @@ -275,9 +281,9 @@ func RunQuery(stream io.Reader, output io.Writer, query string, format OutputFor } } - keys[key] = true - keyList = append(keyList, key) - quotedKeyList = append(quotedKeyList, "'"+key+"'") + keys[strings.ToLower(key)] = true + keyList = append(keyList, strings.ToLower(key)) + quotedKeyList = append(quotedKeyList, "'"+strings.ToLower(key)+"'") argList = append(argList, "?") args = append(args, nil) @@ -293,7 +299,7 @@ func RunQuery(stream io.Reader, output io.Writer, query string, format OutputFor keyTypes = append(keyTypes, dtype) if !madeTable { - err := db.Exec(fmt.Sprintf("CREATE TABLE log('%s' %s);", key, dtype)) + err := db.Exec(fmt.Sprintf("CREATE TABLE log('%s' %s);", strings.ToLower(key), dtype)) if err != nil { return err } @@ -302,7 +308,7 @@ func RunQuery(stream io.Reader, output io.Writer, query string, format OutputFor } else { - err := db.Exec(fmt.Sprintf("ALTER TABLE log ADD COLUMN '%s' %s", key, dtype)) + err := db.Exec(fmt.Sprintf("ALTER TABLE log ADD COLUMN '%s' %s", strings.ToLower(key), dtype)) if err != nil { return err } diff --git a/logquery_test.go b/logquery_test.go index 8846aeb..e326513 100644 --- a/logquery_test.go +++ b/logquery_test.go @@ -78,6 +78,9 @@ event=error code=456 msg="something went wrong" timestamp="1970-01-01 18:56" fla } func Test_CSV(t *testing.T) { + // TODO: this test is flaky because the keys can be in potentially any + // order. + input := "c1=5 c2=true c3=3.4\nc1=3 c2=false c3=5.1" inputReader := strings.NewReader(input) buf := bytes.NewBufferString("") @@ -86,7 +89,6 @@ func Test_CSV(t *testing.T) { assert.Nil(t, err) assert.Equal(t, "c1,c2,c3\n5,true,3.4\n3,false,5.1\n", buf.String()) - } func Test_ChangingTypes(t *testing.T) { diff --git a/parser/parser.go b/parser/parser.go index de53ddb..f53de81 100644 --- a/parser/parser.go +++ b/parser/parser.go @@ -246,6 +246,13 @@ func (p *Parser) NextRecord() (map[string]interface{}, error) { return nil, err } + // If the following character is whitespace or EOF, + // then the value is assumed to be an empty string. + if p.isWhitespace() || p.iseof { + record[key] = "" + continue + } + err = p.consumeWhitespace() if IsSyntaxError(err) { _ = p.readUntilNewLine() diff --git a/parser/parser_test.go b/parser/parser_test.go index d06c638..952e8c3 100644 --- a/parser/parser_test.go +++ b/parser/parser_test.go @@ -37,6 +37,20 @@ func Test_Simple2(t *testing.T) { assert.Equal(t, expect, rec) } +func Test_EmptyKey(t *testing.T) { + p, err := NewParserFromString("foo= bar=baz\n") + + assert.Nil(t, err) + rec, err := p.NextRecord() + assert.Nil(t, err) + + expect := map[string]interface{}{ + "foo": "", + "bar": "baz", + } + assert.Equal(t, expect, rec) +} + func Test_MultiLineString(t *testing.T) { // A string with an un-escaped newline in it should be a syntax error. p, err := NewParserFromString("key=\"line1\nline2\"") -- 2.45.2