-
Notifications
You must be signed in to change notification settings - Fork 2
/
parser.go
136 lines (113 loc) · 3.1 KB
/
parser.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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
package mgs
import (
"strconv"
"strings"
"time"
)
const DATE_FORMAT = "2006-01-02T15:04:05.000Z"
// Parse parses a given url query.
func Parse(query string, caster *map[string]CastType) []SearchCriteria {
criteria := []SearchCriteria{}
for _, condition := range strings.Split(query, "&") {
criteria = append(criteria, CriteriaParser(condition, caster))
}
return criteria
}
// CriteriaParser build criteria from a condition expression
func CriteriaParser(condition string, caster *map[string]CastType) SearchCriteria {
pattern := GetOperatorPattern()
match := pattern.FindStringSubmatch(condition)
key := match[pattern.SubexpIndex("Key")]
var value CastType
if caster != nil {
value = (*caster)[key]
}
return SearchCriteria{
Prefix: match[pattern.SubexpIndex("Prefix")] != "",
Key: key,
Operation: SearchOperator(1).GetOperation(match[pattern.SubexpIndex("Operator")]),
Value: match[pattern.SubexpIndex("Value")],
Caster: &value,
}
}
// ParseValue converts a string to a data type
func ParseValue(value string, qh *QueryHandler, cast *CastType) interface{} {
if cast == nil {
return parseValue(value, qh)
}
switch option := *cast; option {
case BOOLEAN:
if b, err := strconv.ParseBool(value); err == nil {
return b
}
case DATE:
if datetime, err := time.Parse(DATE_FORMAT, value); err == nil {
return datetime
}
case NUMBER:
if integer, err := strconv.ParseInt(value, 10, 64); err == nil {
return integer
}
if float, err := strconv.ParseFloat(value, 64); err == nil {
return float
}
case PATTERN:
if match := GetRegexPattern().FindStringSubmatch(value); match != nil {
return Regex{
Pattern: match[GetRegexPattern().SubexpIndex("Pattern")],
Option: match[GetRegexPattern().SubexpIndex("Option")],
}
}
case STRING:
return value
}
return parseValue(value, qh)
}
func parseValue(value string, qh *QueryHandler) interface{} {
if strings.EqualFold(value, "true") || strings.EqualFold(value, "false") {
if b, err := strconv.ParseBool(strings.ToLower(value)); err == nil {
return b
}
}
var err error
var integer int64
if integer, err = strconv.ParseInt(value, 10, 64); err == nil {
return integer
}
var float float64
if float, err = strconv.ParseFloat(value, 64); err == nil {
return float
}
var datetime time.Time
if datetime, err = time.Parse(DATE_FORMAT, value); err == nil {
return datetime
}
list := strings.Split(value, ",")
if len(list) > 1 {
var characters []interface{}
for _, _value := range list {
characters = append(characters, parseValue(_value, qh))
}
if len(characters) > 0 {
return characters
}
}
if match := GetRegexPattern().FindStringSubmatch(value); match != nil {
return Regex{
Pattern: match[GetRegexPattern().SubexpIndex("Pattern")],
Option: match[GetRegexPattern().SubexpIndex("Option")],
}
}
objectId, err := qh.Primitives.ObjectID(value)
if err == nil {
return objectId
}
return value
}
func parseIntValueToInt(value string) (int64, error) {
result, err := strconv.ParseInt(value, 10, 64)
if err != nil {
return 0, ErrValueNoMatch
}
return result, nil
}