~charles/logquery

0212c9ec21d226ffe8cbaa4e701fd568d6aa8b85 — Charles Daniels 3 years ago 1803c85
fix behavior with empty keys
4 files changed, 36 insertions(+), 7 deletions(-)

M logquery.go
M logquery_test.go
M parser/parser.go
M parser/parser_test.go
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\"")