-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsimplequery.go
71 lines (66 loc) · 1.89 KB
/
simplequery.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
package simplequery
import (
"fmt"
"reflect"
"regexp"
"strconv"
"strings"
"github.com/Codehardt/go-simplequery-parser"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
)
func Parse(condition string) (bson.M, error) {
root, err := simplequery.Parse(condition)
if err != nil {
return nil, err
}
e, _, _, err := parse(root)
return e, err
}
var rgx = regexp.MustCompile(`^/(.*)/([gimy]*)$`)
func parse(node simplequery.Node) (bson.M, string, interface{}, error) {
if node == nil {
return nil, "", nil, nil
}
c1, c2 := node.Children()
d1, k1, _, err := parse(c1)
if err != nil {
return nil, "", nil, err
}
d2, _, v2, err := parse(c2)
if err != nil {
return nil, "", nil, err
}
switch node.(type) {
case simplequery.AND:
return bson.M{"$and": []interface{}{d1, d2}}, "", nil, nil
case simplequery.OR:
return bson.M{"$or": []interface{}{d1, d2}}, "", nil, nil
case simplequery.NOT:
return bson.M{"$nor": []interface{}{d1}}, "", nil, nil
case simplequery.EQ, simplequery.NE, simplequery.GT, simplequery.GTE, simplequery.LT, simplequery.LTE:
op := "$" + strings.ToLower(reflect.TypeOf(node).Name()) // $eq, $ne, $gt, ...
return bson.M{k1: bson.M{op: v2}}, "", nil, nil
case simplequery.ID:
return nil, node.Value(), nil, nil
case simplequery.VAL:
var v interface{}
str := node.Value()
if strings.HasPrefix(str, "\"") && strings.HasSuffix(str, "\"") {
// trim " prefix and suffix for strings
v = str[1 : len(str)-1]
} else if matches := rgx.FindStringSubmatch(str); len(matches) == 3 {
// parse regex /<pattern>/<options>
v = bson.E{Key: "$regex", Value: primitive.Regex{Pattern: matches[1], Options: matches[2]}}
} else {
// parse integer
v, err = strconv.Atoi(str)
if err != nil {
return nil, "", nil, err
}
}
return nil, "", v, nil
default:
return nil, "", nil, fmt.Errorf("unknown node type %T", node)
}
}