Skip to content
Snippets Groups Projects
Commit 86e68a0b authored by Danis Kirasirov's avatar Danis Kirasirov
Browse files

fix expressions "not in" and "object.field"

parent b9a8d9da
No related branches found
No related tags found
No related merge requests found
......@@ -43,6 +43,7 @@ func convertToMongo(ctx context.Context, tree *parser.Tree, env map[string]inter
env[EnvContextKey] = ctx
config := GetDefaultConfig(env)
config.Visitors = append(config.Visitors, notinPatcher{})
for _, op := range ops {
op(config)
......@@ -212,6 +213,8 @@ func (c *compiler) UnaryNode(node *ast.UnaryNode) interface{} {
case "!", "not":
return bson.M{"$not": op}
case "":
return op
default:
panic(fmt.Sprintf("unknown operator (%v)", node.Operator))
}
......@@ -329,7 +332,7 @@ func (c *compiler) ChainNode(node *ast.ChainNode) string {
func (c *compiler) MemberNode(node *ast.MemberNode) string {
v := c.compile(node.Node)
if val, ok := v.(string); ok {
return fmt.Sprintf("%s.%s", val, node.Property)
return fmt.Sprintf("%s.%s", val, c.compile(node.Property))
}
panic(fmt.Sprintf("unsupported property for %v", ast.Dump(node.Node)))
}
......@@ -639,3 +642,23 @@ func (c *compiler) PairNode(node *ast.PairNode) interface{} {
//c.compile(node.Key)
//c.compile(node.Value)
}
type notinPatcher struct{}
func (t notinPatcher) Visit(node *ast.Node) {
nodeNot, ok := (*node).(*ast.UnaryNode)
if !ok || nodeNot.Operator != "not" {
return
}
inNode, ok := nodeNot.Node.(*ast.BinaryNode)
if !ok || inNode.Operator != "in" {
return
}
nodeNot.Operator = ""
ast.Patch(node, nodeNot)
inNode.Operator = "not in"
ast.Patch(&nodeNot.Node, inNode)
}
\ No newline at end of file
......@@ -30,6 +30,9 @@ func TestConvertToMongo(t *testing.T) {
{"equal", "s == 3", nil, bson.M{"s": 3}, false},
{"in array", "s in [1,2,3]", nil, bson.M{"s": bson.M{"$in": []interface{}{1, 2, 3}}}, false},
{"not in array", "s not in [1,2,3]", nil, bson.M{"s": bson.M{"$nin": []interface{}{1, 2, 3}}}, false},
{"field#1", "s.test > 3", nil, bson.M{"s.test": bson.M{"$gt": 3}}, false},
{"field#2", "s['test'] > 3", nil, bson.M{"s.test": bson.M{"$gt": 3}}, false},
{"field#3", "s[test] > 3", nil, bson.M{"s.test": bson.M{"$gt": 3}}, false},
{"contains", "s contains 'some'", nil, bson.M{"s": bson.M{"$regex": "some"}}, false},
{"contains with . + () $ {} ^", "value contains 'something with . + () $ {} ^'", nil, bson.M{"value": bson.M{"$regex": "something with \\. \\+ \\(\\) \\$ \\{\\} \\^"}}, false},
{"startsWith", "s startsWith 'some'", nil, bson.M{"s": bson.M{"$regex": "^some.*"}}, false},
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment