mirror of
https://github.com/dolthub/dolt.git
synced 2026-05-07 19:30:22 -05:00
2e462b11a5
Noms SDK users frequently shoot themselves in the foot because they're holding onto an "old" Database object. That is, they have a Database tucked away in some internal state, they call Commit() on it, and don't replace the object in their internal state with the new Database returned from Commit. This PR changes the Database and Dataset Go API to be in line with the proposal in Issue #2589. JS follows in a separate patch.
139 lines
4.3 KiB
Go
139 lines
4.3 KiB
Go
// Copyright 2016 Attic Labs, Inc. All rights reserved.
|
|
// Licensed under the Apache License, version 2.0:
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
package main
|
|
|
|
import (
|
|
"testing"
|
|
"text/scanner"
|
|
|
|
"github.com/attic-labs/noms/go/chunks"
|
|
"github.com/attic-labs/noms/go/datas"
|
|
"github.com/attic-labs/noms/go/types"
|
|
"github.com/attic-labs/testify/assert"
|
|
)
|
|
|
|
type scannerResult struct {
|
|
tok int
|
|
text string
|
|
}
|
|
|
|
type parseResult struct {
|
|
query string
|
|
ex expr
|
|
}
|
|
|
|
func TestQueryScanner(t *testing.T) {
|
|
assert := assert.New(t)
|
|
|
|
s := NewQueryScanner(`9 (99.9) -9 0x7F "99.9" and or http://localhost:8000/cli-tour::yo <= >= < > = _ !=`)
|
|
|
|
scannerResults := []scannerResult{
|
|
{tok: scanner.Int, text: "9"},
|
|
{tok: int('('), text: "("},
|
|
{tok: scanner.Float, text: "99.9"},
|
|
{tok: int(')'), text: ")"},
|
|
{tok: '-', text: "-"},
|
|
{tok: scanner.Int, text: "9"},
|
|
{tok: scanner.Int, text: "0x7F"},
|
|
{tok: scanner.String, text: `"99.9"`},
|
|
{tok: scanner.Ident, text: "and"},
|
|
{tok: scanner.Ident, text: "or"},
|
|
{tok: scanner.Ident, text: "http://localhost:8000/cli-tour::yo"},
|
|
{tok: scanner.Ident, text: "<="},
|
|
{tok: scanner.Ident, text: ">="},
|
|
{tok: scanner.Ident, text: "<"},
|
|
{tok: scanner.Ident, text: ">"},
|
|
{tok: int('='), text: "="},
|
|
{tok: int('_'), text: "_"},
|
|
{tok: scanner.Ident, text: "!="},
|
|
}
|
|
|
|
for _, sr := range scannerResults {
|
|
tok := s.Scan()
|
|
assert.Equal(sr.tok, int(tok), "expected text: %s, found: %s, pos: %s", sr.text, s.TokenText(), s.Pos())
|
|
assert.Equal(sr.text, s.TokenText())
|
|
}
|
|
tok := s.Scan()
|
|
assert.Equal(scanner.EOF, int(tok))
|
|
}
|
|
|
|
func TestPeek(t *testing.T) {
|
|
assert := assert.New(t)
|
|
|
|
s := NewQueryScanner(`_ < "one"`)
|
|
scannerResults := []scannerResult{
|
|
{tok: int('_'), text: "_"},
|
|
{tok: scanner.Ident, text: "<"},
|
|
{tok: scanner.String, text: `"one"`},
|
|
{tok: scanner.EOF, text: ""},
|
|
}
|
|
|
|
for _, sr := range scannerResults {
|
|
assert.Equal(sr.tok, int(s.Peek()))
|
|
assert.Equal(sr.text, s.TokenText())
|
|
assert.Equal(sr.tok, int(s.Scan()))
|
|
assert.Equal(sr.text, s.TokenText())
|
|
}
|
|
}
|
|
|
|
func TestParsing(t *testing.T) {
|
|
assert := assert.New(t)
|
|
|
|
re1 := compExpr{"index1", equals, types.Number(2015)}
|
|
re2 := compExpr{"index1", gte, types.Number(2020)}
|
|
re3 := compExpr{"index1", lte, types.Number(2022)}
|
|
re4 := compExpr{"index1", lt, types.Number(-2030)}
|
|
re5 := compExpr{"index1", ne, types.Number(3.5)}
|
|
re6 := compExpr{"index1", ne, types.Number(-3500.4536632)}
|
|
re7 := compExpr{"index1", ne, types.String("whassup")}
|
|
|
|
queries := []parseResult{
|
|
{`index1 = 2015`, re1},
|
|
{`(index1 = 2015 )`, re1},
|
|
{`(((index1 = 2015 ) ))`, re1},
|
|
{`index1 = 2015 or index1 >= 2020`, logExpr{or, re1, re2, "index1"}},
|
|
{`(index1 = 2015) or index1 >= 2020`, logExpr{or, re1, re2, "index1"}},
|
|
{`index1 = 2015 or (index1 >= 2020)`, logExpr{or, re1, re2, "index1"}},
|
|
{`(index1 = 2015 or index1 >= 2020)`, logExpr{or, re1, re2, "index1"}},
|
|
{`(index1 = 2015 or index1 >= 2020) and index1 <= 2022`, logExpr{and, logExpr{or, re1, re2, "index1"}, re3, "index1"}},
|
|
{`index1 = 2015 or index1 >= 2020 and index1 <= 2022`, logExpr{or, re1, logExpr{and, re2, re3, "index1"}, "index1"}},
|
|
{`index1 = 2015 or index1 >= 2020 and index1 <= 2022 or index1 < -2030`, logExpr{or, re1, logExpr{and, re2, logExpr{or, re3, re4, "index1"}, "index1"}, "index1"}},
|
|
{`(index1 = 2015 or index1 >= 2020) and (index1 <= 2022 or index1 < -2030)`, logExpr{and, logExpr{or, re1, re2, "index1"}, logExpr{or, re3, re4, "index1"}, "index1"}},
|
|
{`index1 != 3.5`, re5},
|
|
{`index1 != -3500.4536632`, re6},
|
|
{`index1 != "whassup"`, re7},
|
|
}
|
|
|
|
db := datas.NewDatabase(chunks.NewMemoryStore())
|
|
_, err := db.CommitValue(db.GetDataset("index1"), types.NewMap(types.String("one"), types.NewSet(types.String("two"))))
|
|
assert.NoError(err)
|
|
|
|
im := &indexManager{db: db, indexes: map[string]types.Map{}}
|
|
for _, pr := range queries {
|
|
expr, err := parseQuery(pr.query, im)
|
|
assert.NoError(err)
|
|
assert.Equal(pr.ex, expr, "bad query: %s", pr.query)
|
|
}
|
|
|
|
badQueries := []string{
|
|
`sdfsd = 2015`,
|
|
`index1 = "unfinished string`,
|
|
`index1 and 2015`,
|
|
`index1 < `,
|
|
`index1 < 2015 and ()`,
|
|
`index1 < 2015 an index1 > 2016`,
|
|
`(index1 < 2015) what`,
|
|
`(index1< 2015`,
|
|
`(badIndexName < 2015)`,
|
|
}
|
|
|
|
im1 := &indexManager{db: db, indexes: map[string]types.Map{}}
|
|
for _, q := range badQueries {
|
|
expr, err := parseQuery(q, im1)
|
|
assert.Error(err)
|
|
assert.Nil(expr)
|
|
}
|
|
}
|