M logquery.go => logquery.go +12 -6
@@ 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
}
M logquery_test.go => logquery_test.go +3 -1
@@ 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) {
M parser/parser.go => parser/parser.go +7 -0
@@ 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()
M parser/parser_test.go => parser/parser_test.go +14 -0
@@ 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\"")