Fix stylecheck warnings

master
Vladimir Hodakov 2019-10-19 01:41:57 +04:00
parent ca047193ee
commit 3697f12c5c
Signed by: Vladimir Hodakov
GPG Key ID: 673980B6882F82C6
10 changed files with 101 additions and 78 deletions

View File

@ -6,6 +6,7 @@ linters:
- gochecknoglobals - gochecknoglobals
- gocritic - gocritic
- funlen - funlen
- godox
linters-settings: linters-settings:
lll: lll:
line-length: 180 line-length: 180
@ -21,4 +22,6 @@ issues:
- lll - lll
- goconst - goconst
- unparam - unparam
- unused - unused
max-issues-per-linter: 0
max-same-issues: 0

14
eval.go
View File

@ -259,17 +259,17 @@ func pathEndValue(q *query, e *Eval, i *Item) queryStateFn {
switch q.firstType { switch q.firstType {
case jsonBraceLeft: case jsonBraceLeft:
r.Type = JsonObject r.Type = JSONObject
case jsonString: case jsonString:
r.Type = JsonString r.Type = JSONString
case jsonBracketLeft: case jsonBracketLeft:
r.Type = JsonArray r.Type = JSONArray
case jsonNull: case jsonNull:
r.Type = JsonNull r.Type = JSONNull
case jsonBool: case jsonBool:
r.Type = JsonBool r.Type = JSONBool
case jsonNumber: case jsonNumber:
r.Type = JsonNumber r.Type = JSONNumber
default: default:
r.Type = -1 r.Type = -1
} }
@ -297,7 +297,7 @@ func (b *exprBucket) evaluate() (bool, error) {
for _, q := range b.queries { for _, q := range b.queries {
result := q.resultQueue.Pop() result := q.resultQueue.Pop()
if result != nil { if result != nil {
t, err := getJsonTokenType(result.Value) t, err := getJSONTokenType(result.Value)
if err != nil { if err != nil {
return false, err return false, err
} }

View File

@ -15,32 +15,32 @@ type test struct {
} }
var tests = []test{ var tests = []test{
{`key selection`, `{"aKey":32}`, `$.aKey+`, []Result{newResult(`32`, JsonNumber, `aKey`)}}, {`key selection`, `{"aKey":32}`, `$.aKey+`, []Result{newResult(`32`, JSONNumber, `aKey`)}},
{`nested key selection`, `{"aKey":{"bKey":32}}`, `$.aKey+`, []Result{newResult(`{"bKey":32}`, JsonObject, `aKey`)}}, {`nested key selection`, `{"aKey":{"bKey":32}}`, `$.aKey+`, []Result{newResult(`{"bKey":32}`, JSONObject, `aKey`)}},
{`empty array`, `{"aKey":[]}`, `$.aKey+`, []Result{newResult(`[]`, JsonArray, `aKey`)}}, {`empty array`, `{"aKey":[]}`, `$.aKey+`, []Result{newResult(`[]`, JSONArray, `aKey`)}},
{`multiple same-level keys, weird spacing`, `{ "aKey" : true , "bKey": [ 1 , 2 ], "cKey" : true } `, `$.bKey+`, []Result{newResult(`[1,2]`, JsonArray, `bKey`)}}, {`multiple same-level keys, weird spacing`, `{ "aKey" : true , "bKey": [ 1 , 2 ], "cKey" : true } `, `$.bKey+`, []Result{newResult(`[1,2]`, JSONArray, `bKey`)}},
{`array index selection`, `{"aKey":[123,456]}`, `$.aKey[1]+`, []Result{newResult(`456`, JsonNumber, `aKey`, 1)}}, {`array index selection`, `{"aKey":[123,456]}`, `$.aKey[1]+`, []Result{newResult(`456`, JSONNumber, `aKey`, 1)}},
{`array wild index selection`, `{"aKey":[123,456]}`, `$.aKey[*]+`, []Result{newResult(`123`, JsonNumber, `aKey`, 0), newResult(`456`, JsonNumber, `aKey`, 1)}}, {`array wild index selection`, `{"aKey":[123,456]}`, `$.aKey[*]+`, []Result{newResult(`123`, JSONNumber, `aKey`, 0), newResult(`456`, JSONNumber, `aKey`, 1)}},
{`array range index selection`, `{"aKey":[11,22,33,44]}`, `$.aKey[1:3]+`, []Result{newResult(`22`, JsonNumber, `aKey`, 1), newResult(`33`, JsonNumber, `aKey`, 2)}}, {`array range index selection`, `{"aKey":[11,22,33,44]}`, `$.aKey[1:3]+`, []Result{newResult(`22`, JSONNumber, `aKey`, 1), newResult(`33`, JSONNumber, `aKey`, 2)}},
{`array range (no index) selection`, `{"aKey":[11,22,33,44]}`, `$.aKey[1:1]+`, []Result{}}, {`array range (no index) selection`, `{"aKey":[11,22,33,44]}`, `$.aKey[1:1]+`, []Result{}},
{`array range (no upper bound) selection`, `{"aKey":[11,22,33]}`, `$.aKey[1:]+`, []Result{newResult(`22`, JsonNumber, `aKey`, 1), newResult(`33`, JsonNumber, `aKey`, 2)}}, {`array range (no upper bound) selection`, `{"aKey":[11,22,33]}`, `$.aKey[1:]+`, []Result{newResult(`22`, JSONNumber, `aKey`, 1), newResult(`33`, JSONNumber, `aKey`, 2)}},
{`empty array - try selection`, `{"aKey":[]}`, `$.aKey[1]+`, []Result{}}, {`empty array - try selection`, `{"aKey":[]}`, `$.aKey[1]+`, []Result{}},
{`null selection`, `{"aKey":[null]}`, `$.aKey[0]+`, []Result{newResult(`null`, JsonNull, `aKey`, 0)}}, {`null selection`, `{"aKey":[null]}`, `$.aKey[0]+`, []Result{newResult(`null`, JSONNull, `aKey`, 0)}},
{`empty object`, `{"aKey":{}}`, `$.aKey+`, []Result{newResult(`{}`, JsonObject, `aKey`)}}, {`empty object`, `{"aKey":{}}`, `$.aKey+`, []Result{newResult(`{}`, JSONObject, `aKey`)}},
{`object w/ height=2`, `{"aKey":{"bKey":32}}`, `$.aKey.bKey+`, []Result{newResult(`32`, JsonNumber, `aKey`, `bKey`)}}, {`object w/ height=2`, `{"aKey":{"bKey":32}}`, `$.aKey.bKey+`, []Result{newResult(`32`, JSONNumber, `aKey`, `bKey`)}},
{`array of multiple types`, `{"aKey":[1,{"s":true},"asdf"]}`, `$.aKey[1]+`, []Result{newResult(`{"s":true}`, JsonObject, `aKey`, 1)}}, {`array of multiple types`, `{"aKey":[1,{"s":true},"asdf"]}`, `$.aKey[1]+`, []Result{newResult(`{"s":true}`, JSONObject, `aKey`, 1)}},
{`nested array selection`, `{"aKey":{"bKey":[123,456]}}`, `$.aKey.bKey+`, []Result{newResult(`[123,456]`, JsonArray, `aKey`, `bKey`)}}, {`nested array selection`, `{"aKey":{"bKey":[123,456]}}`, `$.aKey.bKey+`, []Result{newResult(`[123,456]`, JSONArray, `aKey`, `bKey`)}},
{`nested array`, `[[[[[]], [true, false, []]]]]`, `$[0][0][1][2]+`, []Result{newResult(`[]`, JsonArray, 0, 0, 1, 2)}}, {`nested array`, `[[[[[]], [true, false, []]]]]`, `$[0][0][1][2]+`, []Result{newResult(`[]`, JSONArray, 0, 0, 1, 2)}},
{`index of array selection`, `{"aKey":{"bKey":[123, 456, 789]}}`, `$.aKey.bKey[1]+`, []Result{newResult(`456`, JsonNumber, `aKey`, `bKey`, 1)}}, {`index of array selection`, `{"aKey":{"bKey":[123, 456, 789]}}`, `$.aKey.bKey[1]+`, []Result{newResult(`456`, JSONNumber, `aKey`, `bKey`, 1)}},
{`index of array selection (more than one)`, `{"aKey":{"bKey":[123,456]}}`, `$.aKey.bKey[1]+`, []Result{newResult(`456`, JsonNumber, `aKey`, `bKey`, 1)}}, {`index of array selection (more than one)`, `{"aKey":{"bKey":[123,456]}}`, `$.aKey.bKey[1]+`, []Result{newResult(`456`, JSONNumber, `aKey`, `bKey`, 1)}},
{`multi-level object/array`, `{"1Key":{"aKey": null, "bKey":{"trash":[1,2]}, "cKey":[123,456] }, "2Key":false}`, `$.1Key.bKey.trash[0]+`, []Result{newResult(`1`, JsonNumber, `1Key`, `bKey`, `trash`, 0)}}, {`multi-level object/array`, `{"1Key":{"aKey": null, "bKey":{"trash":[1,2]}, "cKey":[123,456] }, "2Key":false}`, `$.1Key.bKey.trash[0]+`, []Result{newResult(`1`, JSONNumber, `1Key`, `bKey`, `trash`, 0)}},
{`multi-level array`, `{"aKey":[true,false,null,{"michael":[5,6,7]}, ["s", "3"] ]}`, `$.*[*].michael[1]+`, []Result{newResult(`6`, JsonNumber, `aKey`, 3, `michael`, 1)}}, {`multi-level array`, `{"aKey":[true,false,null,{"michael":[5,6,7]}, ["s", "3"] ]}`, `$.*[*].michael[1]+`, []Result{newResult(`6`, JSONNumber, `aKey`, 3, `michael`, 1)}},
{`multi-level array 2`, `{"aKey":[true,false,null,{"michael":[5,6,7]}, ["s", "3"] ]}`, `$.*[*][1]+`, []Result{newResult(`"3"`, JsonString, `aKey`, 4, 1)}}, {`multi-level array 2`, `{"aKey":[true,false,null,{"michael":[5,6,7]}, ["s", "3"] ]}`, `$.*[*][1]+`, []Result{newResult(`"3"`, JSONString, `aKey`, 4, 1)}},
{`evaluation literal equality`, `{"items":[ {"name":"alpha", "value":11}]}`, `$.items[*]?("bravo" == "bravo").value+`, []Result{newResult(`11`, JsonNumber, `items`, 0, `value`)}}, {`evaluation literal equality`, `{"items":[ {"name":"alpha", "value":11}]}`, `$.items[*]?("bravo" == "bravo").value+`, []Result{newResult(`11`, JSONNumber, `items`, 0, `value`)}},
{`evaluation based on string equal to path value`, `{"items":[ {"name":"alpha", "value":11}, {"name":"bravo", "value":22}, {"name":"charlie", "value":33} ]}`, `$.items[*]?(@.name == "bravo").value+`, []Result{newResult(`22`, JsonNumber, `items`, 1, `value`)}}, {`evaluation based on string equal to path value`, `{"items":[ {"name":"alpha", "value":11}, {"name":"bravo", "value":22}, {"name":"charlie", "value":33} ]}`, `$.items[*]?(@.name == "bravo").value+`, []Result{newResult(`22`, JSONNumber, `items`, 1, `value`)}},
} }
func TestPathQuery(t *testing.T) { func TestPathQuery(t *testing.T) {
@ -52,14 +52,16 @@ func TestPathQuery(t *testing.T) {
eval, err := EvalPathsInBytes([]byte(t.json), paths) eval, err := EvalPathsInBytes([]byte(t.json), paths)
if as.NoError(err, "Testing: %s", t.name) { if as.NoError(err, "Testing: %s", t.name) {
res := toResultArray(eval) res := toResultArray(eval)
if as.NoError(eval.Error) { if as.NoError(eval.Error) {
as.EqualValues(t.expected, res, "Testing of %q", t.name) as.EqualValues(t.expected, res, "Testing of %q", t.name)
} }
} }
eval_reader, err := EvalPathsInReader(strings.NewReader(t.json), paths) evalReader, err := EvalPathsInReader(strings.NewReader(t.json), paths)
if as.NoError(err, "Testing: %s", t.name) { if as.NoError(err, "Testing: %s", t.name) {
res := toResultArray(eval_reader) res := toResultArray(evalReader)
if as.NoError(eval.Error) { if as.NoError(eval.Error) {
as.EqualValues(t.expected, res, "Testing of %q", t.name) as.EqualValues(t.expected, res, "Testing of %q", t.name)
} }

View File

@ -64,11 +64,11 @@ func infixToPostFix(items []Item) (out []Item, err error) {
found := false found := false
for { for {
// pop item ("(" or operator) from stack // pop item ("(" or operator) from stack
op_interface, ok := stack.pop() opInterface, ok := stack.pop()
if !ok { if !ok {
return nil, errors.New(exprErrorMismatchedParens) return nil, errors.New(exprErrorMismatchedParens)
} }
op := op_interface.(Item) op := opInterface.(Item)
if op.typ == exprParenLeft { if op.typ == exprParenLeft {
found = true found = true
break // discard "(" break // discard "("
@ -83,8 +83,8 @@ func infixToPostFix(items []Item) (out []Item, err error) {
// token is an operator // token is an operator
for stack.len() > 0 { for stack.len() > 0 {
// consider top item on stack // consider top item on stack
op_int, _ := stack.peek() opInt, _ := stack.peek()
op := op_int.(Item) op := opInt.(Item)
if o2, isOp := opa[op.typ]; !isOp || o1.prec > o2.prec || if o2, isOp := opa[op.typ]; !isOp || o1.prec > o2.prec ||
o1.prec == o2.prec && o1.rAssoc { o1.prec == o2.prec && o1.rAssoc {
break break
@ -102,8 +102,8 @@ func infixToPostFix(items []Item) (out []Item, err error) {
} }
// drain stack to result // drain stack to result
for stack.len() > 0 { for stack.len() > 0 {
op_int, _ := stack.pop() opInt, _ := stack.pop()
op := op_int.(Item) op := opInt.(Item)
if op.typ == exprParenLeft { if op.typ == exprParenLeft {
return nil, errors.New(exprErrorMismatchedParens) return nil, errors.New(exprErrorMismatchedParens)
} }
@ -308,7 +308,7 @@ func evaluatePostFix(postFixItems []Item, pathValues map[string]Item) (interface
} }
if a == 0.0 { if a == 0.0 {
return false, errors.New("Cannot divide by zero") return false, errors.New("cannot divide by zero")
} }
s.push(b / a) s.push(b / a)
case exprOpStar: case exprOpStar:
@ -340,15 +340,16 @@ func evaluatePostFix(postFixItems []Item, pathValues map[string]Item) (interface
s.push(!a) s.push(!a)
// Other // Other
default: default:
return false, fmt.Errorf("Token not supported in evaluator: %v", exprTokenNames[item.typ]) return false, fmt.Errorf("token not supported in evaluator: %v", exprTokenNames[item.typ])
} }
} }
if s.len() != 1 { if s.len() != 1 {
return false, fmt.Errorf(exprErrorBadExpression) return false, fmt.Errorf(exprErrorBadExpression)
} }
end_int, _ := s.pop()
return end_int, nil endInt, _ := s.pop()
return endInt, nil
} }
func take1Bool(s *stack, op int) (bool, error) { func take1Bool(s *stack, op int) (bool, error) {

View File

@ -38,12 +38,14 @@ var jsonTokenNames = map[int]string{
jsonBool: "BOOL", jsonBool: "BOOL",
} }
var JSON = lexJsonRoot var JSON = lexJSONRoot
func lexJsonRoot(l lexer, state *intStack) stateFn { func lexJSONRoot(l lexer, state *intStack) stateFn {
ignoreSpaceRun(l) ignoreSpaceRun(l)
cur := l.peek() cur := l.peek()
var next stateFn var next stateFn
switch cur { switch cur {
case '{': case '{':
next = stateJSONObjectOpen next = stateJSONObjectOpen

View File

@ -33,7 +33,7 @@ func TestValidJson(t *testing.T) {
} }
} }
var errorJsonTests = []lexTest{ var errorJSONTests = []lexTest{
{"Missing end brace", `{`, []int{jsonBraceLeft, jsonError}}, {"Missing end brace", `{`, []int{jsonBraceLeft, jsonError}},
{"Missing start brace", `}`, []int{jsonError}}, {"Missing start brace", `}`, []int{jsonError}},
{"Missing key start quote", `{key":true}`, []int{jsonBraceLeft, jsonError}}, {"Missing key start quote", `{key":true}`, []int{jsonBraceLeft, jsonError}},
@ -50,7 +50,7 @@ var errorJsonTests = []lexTest{
func TestMalformedJson(t *testing.T) { func TestMalformedJson(t *testing.T) {
as := assert.New(t) as := assert.New(t)
for _, test := range errorJsonTests { for _, test := range errorJSONTests {
lexer := NewSliceLexer([]byte(test.input), JSON) lexer := NewSliceLexer([]byte(test.input), JSON)
types := itemsToTypes(readerToArray(lexer)) types := itemsToTypes(readerToArray(lexer))

View File

@ -34,14 +34,14 @@ func (l *SliceLexer) takeString() error {
inputLen := len(l.input) inputLen := len(l.input)
if int(curPos) >= inputLen { if int(curPos) >= inputLen {
return errors.New("End of file where string expected") return errors.New("end of file where string expected")
} }
cur := int(l.input[curPos]) cur := int(l.input[curPos])
curPos++ curPos++
if cur != '"' { if cur != '"' {
l.pos = curPos l.pos = curPos
return fmt.Errorf("Expected \" as start of string instead of %#U", cur) return fmt.Errorf("expected \" as start of string instead of %#U", cur)
} }
var previous int var previous int
@ -49,7 +49,7 @@ looper:
for { for {
if int(curPos) >= inputLen { if int(curPos) >= inputLen {
l.pos = curPos l.pos = curPos
return errors.New("End of file where string expected") return errors.New("end of file where string expected")
} }
cur := int(l.input[curPos]) cur := int(l.input[curPos])
curPos++ curPos++

17
misc.go
View File

@ -16,13 +16,13 @@ func takeExponent(l lexer) error {
case '+', '-': case '+', '-':
// Check digit immediately follows sign // Check digit immediately follows sign
if d := l.peek(); !(d >= '0' && d <= '9') { if d := l.peek(); !(d >= '0' && d <= '9') {
return fmt.Errorf("Expected digit after numeric sign instead of %#U", d) return fmt.Errorf("expected digit after numeric sign instead of %#U", d)
} }
takeDigits(l) takeDigits(l)
case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
takeDigits(l) takeDigits(l)
default: default:
return fmt.Errorf("Expected digit after 'e' instead of %#U", r) return fmt.Errorf("expected digit after 'e' instead of %#U", r)
} }
return nil return nil
} }
@ -33,13 +33,13 @@ func takeJSONNumeric(l lexer) error {
case '-': case '-':
// Check digit immediately follows sign // Check digit immediately follows sign
if d := l.peek(); !(d >= '0' && d <= '9') { if d := l.peek(); !(d >= '0' && d <= '9') {
return fmt.Errorf("Expected digit after dash instead of %#U", d) return fmt.Errorf("expected digit after dash instead of %#U", d)
} }
takeDigits(l) takeDigits(l)
case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
takeDigits(l) takeDigits(l)
default: default:
return fmt.Errorf("Expected digit or dash instead of %#U", cur) return fmt.Errorf("expected digit or dash instead of %#U", cur)
} }
// fraction or exponent // fraction or exponent
@ -49,7 +49,7 @@ func takeJSONNumeric(l lexer) error {
l.take() l.take()
// Check digit immediately follows period // Check digit immediately follows period
if d := l.peek(); !(d >= '0' && d <= '9') { if d := l.peek(); !(d >= '0' && d <= '9') {
return fmt.Errorf("Expected digit after '.' instead of %#U", d) return fmt.Errorf("expected digit after '.' instead of %#U", d)
} }
takeDigits(l) takeDigits(l)
if err := takeExponent(l); err != nil { if err := takeExponent(l); err != nil {
@ -158,10 +158,11 @@ func abs(x int) int {
} }
//TODO: Kill the need for this //TODO: Kill the need for this
func getJsonTokenType(val []byte) (int, error) { func getJSONTokenType(val []byte) (int, error) {
if len(val) == 0 { if len(val) == 0 {
return -1, errors.New("No Value") return -1, errors.New("no value")
} }
switch val[0] { switch val[0] {
case '{': case '{':
return jsonBraceLeft, nil return jsonBraceLeft, nil
@ -176,6 +177,6 @@ func getJsonTokenType(val []byte) (int, error) {
case '-', '+', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': case '-', '+', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
return jsonNumber, nil return jsonNumber, nil
default: default:
return -1, errors.New("Unrecognized Json Value") return -1, errors.New("unrecognized JSON value")
} }
} }

46
path.go
View File

@ -36,10 +36,13 @@ type operator struct {
// nolint:gocognit // nolint:gocognit
func genIndexKey(tr tokenReader) (*operator, error) { func genIndexKey(tr tokenReader) (*operator, error) {
k := &operator{} k := &operator{}
var t *Item var t *Item
var ok bool var ok bool
if t, ok = tr.next(); !ok { if t, ok = tr.next(); !ok {
return nil, errors.New("Expected number, key, or *, but got none") return nil, errors.New("expected number, key, or *, but got none")
} }
switch t.typ { switch t.typ {
@ -47,22 +50,23 @@ func genIndexKey(tr tokenReader) (*operator, error) {
k.typ = opTypeIndexWild k.typ = opTypeIndexWild
k.indexStart = 0 k.indexStart = 0
if t, ok = tr.next(); !ok { if t, ok = tr.next(); !ok {
return nil, errors.New("Expected ] after *, but got none") return nil, errors.New("expected ] after *, but got none")
} }
if t.typ != pathBracketRight { if t.typ != pathBracketRight {
return nil, fmt.Errorf("Expected ] after * instead of %q", t.val) return nil, fmt.Errorf("expected ] after * instead of %q", t.val)
} }
case pathIndex: case pathIndex:
v, err := strconv.Atoi(string(t.val)) v, err := strconv.Atoi(string(t.val))
if err != nil { if err != nil {
return nil, fmt.Errorf("Could not parse %q into int64", t.val) return nil, fmt.Errorf("could not parse %q into int64", t.val)
} }
k.indexStart = v k.indexStart = v
k.indexEnd = v k.indexEnd = v
k.hasIndexEnd = true k.hasIndexEnd = true
if t, ok = tr.next(); !ok { if t, ok = tr.next(); !ok {
return nil, errors.New("Expected number or *, but got none") return nil, errors.New("expected number or *, but got none")
} }
switch t.typ { switch t.typ {
@ -77,6 +81,7 @@ func genIndexKey(tr tokenReader) (*operator, error) {
if err != nil { if err != nil {
return nil, fmt.Errorf("could not parse %q into int64", t.val) return nil, fmt.Errorf("could not parse %q into int64", t.val)
} }
k.indexEnd = v - 1 k.indexEnd = v - 1
k.hasIndexEnd = true k.hasIndexEnd = true
@ -113,6 +118,7 @@ func genIndexKey(tr tokenReader) (*operator, error) {
func parsePath(pathString string) (*Path, error) { func parsePath(pathString string) (*Path, error) {
lexer := NewSliceLexer([]byte(pathString), PATH) lexer := NewSliceLexer([]byte(pathString), PATH)
p, err := tokensToOperators(lexer) p, err := tokensToOperators(lexer)
if err != nil { if err != nil {
return nil, err return nil, err
@ -124,9 +130,11 @@ func parsePath(pathString string) (*Path, error) {
for _, op := range p.operators { for _, op := range p.operators {
if len(op.whereClauseBytes) > 0 { if len(op.whereClauseBytes) > 0 {
var err error var err error
trimmed := op.whereClauseBytes[1 : len(op.whereClauseBytes)-1] trimmed := op.whereClauseBytes[1 : len(op.whereClauseBytes)-1]
whereLexer := NewSliceLexer(trimmed, EXPRESSION) whereLexer := NewSliceLexer(trimmed, EXPRESSION)
items := readerToArray(whereLexer) items := readerToArray(whereLexer)
if errItem, found := findErrors(items); found { if errItem, found := findErrors(items); found {
return nil, errors.New(string(errItem.val)) return nil, errors.New(string(errItem.val))
} }
@ -136,6 +144,7 @@ func parsePath(pathString string) (*Path, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
op.dependentPaths = make([]*Path, 0) op.dependentPaths = make([]*Path, 0)
// parse all paths in expression // parse all paths in expression
for _, item := range op.whereClause { for _, item := range op.whereClause {
@ -144,11 +153,13 @@ func parsePath(pathString string) (*Path, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
op.dependentPaths = append(op.dependentPaths, p) op.dependentPaths = append(op.dependentPaths, p)
} }
} }
} }
} }
return p, nil return p, nil
} }
@ -158,27 +169,28 @@ func tokensToOperators(tr tokenReader) (*Path, error) {
captureEndValue: false, captureEndValue: false,
operators: make([]*operator, 0), operators: make([]*operator, 0),
} }
for { for {
p, ok := tr.next() p, ok := tr.next()
if !ok { if !ok {
break break
} }
switch p.typ { switch p.typ {
case pathRoot: case pathRoot:
if len(q.operators) != 0 { if len(q.operators) != 0 {
return nil, errors.New("Unexpected root node after start") return nil, errors.New("unexpected root node after start")
} }
continue
continue
case pathCurrent: case pathCurrent:
if len(q.operators) != 0 { if len(q.operators) != 0 {
return nil, errors.New("Unexpected current node after start") return nil, errors.New("unexpected current node after start")
} }
continue
continue
case pathPeriod: case pathPeriod:
continue continue
case pathBracketLeft: case pathBracketLeft:
k, err := genIndexKey(tr) k, err := genIndexKey(tr)
if err != nil { if err != nil {
@ -190,11 +202,13 @@ func tokensToOperators(tr tokenReader) (*Path, error) {
keyName := p.val keyName := p.val
if len(p.val) == 0 { if len(p.val) == 0 {
return nil, fmt.Errorf("Key length is zero at %d", p.pos) return nil, fmt.Errorf("key length is zero at %d", p.pos)
} }
if p.val[0] == '"' && p.val[len(p.val)-1] == '"' { if p.val[0] == '"' && p.val[len(p.val)-1] == '"' {
keyName = p.val[1 : len(p.val)-1] keyName = p.val[1 : len(p.val)-1]
} }
q.operators = append( q.operators = append(
q.operators, q.operators,
&operator{ &operator{
@ -204,28 +218,28 @@ func tokensToOperators(tr tokenReader) (*Path, error) {
}, },
}, },
) )
case pathWildcard: case pathWildcard:
q.operators = append(q.operators, &operator{typ: opTypeNameWild}) q.operators = append(q.operators, &operator{typ: opTypeNameWild})
case pathValue: case pathValue:
q.captureEndValue = true q.captureEndValue = true
case pathWhere: case pathWhere:
case pathExpression: case pathExpression:
if len(q.operators) == 0 { if len(q.operators) == 0 {
return nil, errors.New("Cannot add where clause on last key") return nil, errors.New("cannot add where clause on last key")
} }
last := q.operators[len(q.operators)-1] last := q.operators[len(q.operators)-1]
if last.whereClauseBytes != nil { if last.whereClauseBytes != nil {
return nil, errors.New("Expression on last key already set") return nil, errors.New("expression on last key already set")
} }
last.whereClauseBytes = p.val
last.whereClauseBytes = p.val
case pathError: case pathError:
return q, errors.New(string(p.val)) return q, errors.New(string(p.val))
} }
} }
return q, nil return q, nil
} }

View File

@ -6,12 +6,12 @@ import (
) )
const ( const (
JsonObject = iota JSONObject = iota
JsonArray JSONArray
JsonString JSONString
JsonNumber JSONNumber
JsonNull JSONNull
JsonBool JSONBool
) )
type Result struct { type Result struct {