Skip to content

Commit 1da1de1

Browse files
committed
- update filter to recognise ids
1 parent b8d71c6 commit 1da1de1

File tree

1 file changed

+117
-46
lines changed

1 file changed

+117
-46
lines changed

filter/filter.go

Lines changed: 117 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,11 @@ import (
1212
)
1313

1414
const (
15-
id = "id"
16-
_id = "_id"
15+
id = "id"
16+
_id = "_id"
17+
desc = "desc"
18+
//ID ...
19+
ID = "ID"
1720
)
1821

1922
//Filter describe fiter query
@@ -27,13 +30,55 @@ type Filter struct {
2730

2831
//BeforeFilter ...
2932
type BeforeFilter struct {
30-
Skip string
31-
Limit string
33+
Skip interface{}
34+
Limit interface{}
3235
Where map[string]interface{}
3336
Sort map[string]string
3437
Search string
3538
}
3639

40+
func (bf *BeforeFilter) getSort() []string {
41+
var sort []string
42+
sort = make([]string, 0)
43+
for key, value := range bf.Sort {
44+
if desc == strings.ToLower(value) {
45+
key = "-" + key
46+
}
47+
sort = append(sort, key)
48+
}
49+
return sort
50+
}
51+
52+
func (bf *BeforeFilter) getLimit() int {
53+
return convertParam(bf.Limit)
54+
}
55+
56+
func (bf *BeforeFilter) getSkip() int {
57+
return convertParam(bf.Skip)
58+
}
59+
60+
//convertParam to convert skip/limit to int
61+
//by default return 0
62+
func convertParam(param interface{}) int {
63+
var result int
64+
switch param.(type) {
65+
default:
66+
return int(0)
67+
case float64:
68+
result = int(param.(float64))
69+
case string:
70+
t, err := strconv.Atoi(param.(string))
71+
if err != nil {
72+
result = int(0)
73+
}
74+
result = t
75+
}
76+
if result < 0 {
77+
return int(0)
78+
}
79+
return result
80+
}
81+
3782
//GetSkip ...
3883
func (f *Filter) GetSkip() int {
3984
return f.skip
@@ -70,36 +115,27 @@ func (f *Filter) AddQuery(q bson.M) {
70115

71116
//GetFilterData ...
72117
func GetFilterData(filter string, t interface{}) Filter {
73-
74118
var f Filter
75119
if filter != "" {
76120
var tmp BeforeFilter
77121
ffjson.Unmarshal([]byte(filter), &tmp)
78-
f.limit, _ = strconv.Atoi(tmp.Limit)
79-
f.skip, _ = strconv.Atoi(tmp.Skip)
80-
f.search = tmp.Search
81-
82-
for key, value := range tmp.Sort {
83-
if "desc" == strings.ToLower(value) {
84-
key = "-" + key
85-
}
86-
f.sort = append(f.sort, key)
87-
}
122+
f.limit = tmp.getLimit()
123+
f.skip = tmp.getSkip()
124+
f.sort = tmp.getSort()
88125
f.query = tmp.parseWhere(t)
89126
}
90127
return f
91128
}
92129

93-
func (f *BeforeFilter) parseWhere(t interface{}) bson.M {
130+
func (bf *BeforeFilter) parseWhere(t interface{}) bson.M {
94131
var q bson.M
95-
for key, values := range f.Where {
132+
for key, values := range bf.Where {
96133
if key == "and" || key == "or" {
97134
key = "$" + key
98135
q = parseAnd(key, values.([]interface{}), q, t)
99136
} else {
100137
q = parse(key, values, q, t)
101138
}
102-
103139
}
104140
return q
105141
}
@@ -109,34 +145,85 @@ func parse(key string, values interface{}, q bson.M, t interface{}) bson.M {
109145
key = _id
110146
}
111147
val := reflect.ValueOf(t)
148+
var fieldType string
149+
if val.FieldByName(convertName(key)).IsValid() == true {
150+
fieldType = val.FieldByName(convertName(key)).Type().String()
151+
if fieldType == "*time.Time" || fieldType == "time.Time" {
152+
if q == nil {
153+
q = bson.M{"$and": []bson.M{}}
154+
} else {
155+
if q["$and"] == nil {
156+
q["$and"] = []bson.M{}
157+
}
158+
}
159+
q = parseFilterDate("$and", key, values, q)
160+
}
161+
if fieldType == "bson.ObjectId" {
162+
q = parseID(key, values, q)
163+
}
164+
}
165+
return q
166+
}
167+
168+
func addKeyToQuery(key string, q bson.M) bson.M {
112169
if q == nil {
113170
q = bson.M{key: []bson.M{}}
114171
} else {
115172
q[key] = []bson.M{}
116173
}
117-
fieldName := convertName(key)
118-
var fieldType string
174+
return q
175+
}
176+
177+
func parseID(key string, values interface{}, q bson.M) bson.M {
178+
q = addKeyToQuery(key, q)
119179
for field, data := range values.(map[string]interface{}) {
120-
if val.FieldByName(fieldName).IsValid() == true {
121-
fieldType = val.FieldByName(fieldName).Type().String()
122-
if fieldType == "bson.ObjectId" {
123-
q = parseIDData(key, field, data, q)
180+
ids := convertStringIDtoObjectID(data)
181+
if len(ids) > 0 {
182+
if field == "in" || field == "nin" || field == "all" {
183+
q[key] = bson.M{"$" + field: ids}
124184
}
125185
}
126186
}
127187
return q
128188
}
129189

130-
func parseIDData(key string, field string, data interface{}, q bson.M) bson.M {
131-
IDS := prepareInIds(data.(string))
132-
if len(IDS) > 0 {
133-
if field == "in" || field == "nin" || field == "all" {
134-
q[key] = bson.M{"$" + field: IDS}
190+
func parseAndIDData(key string, field string, data interface{}, q bson.M) bson.M {
191+
if field == id {
192+
field = _id
193+
}
194+
slice := data.(map[string]interface{})
195+
for k, value := range slice {
196+
IDS := convertStringIDtoObjectID(value)
197+
if len(IDS) > 0 {
198+
if k == "in" || k == "nin" || k == "all" {
199+
q[key] = append(q[key].([]bson.M), bson.M{field: bson.M{"$" + k: IDS}})
200+
}
135201
}
136202
}
137203
return q
138204
}
139205

206+
func convertStringIDtoObjectID(data interface{}) []bson.ObjectId {
207+
var ids []bson.ObjectId
208+
ids = make([]bson.ObjectId, 0)
209+
switch data.(type) {
210+
case []interface{}:
211+
ids = prepareIDSArray(data.([]interface{}))
212+
case string:
213+
ids = prepareInIds(data.(string))
214+
}
215+
return ids
216+
}
217+
218+
func prepareIDSArray(values []interface{}) []bson.ObjectId {
219+
var ids []bson.ObjectId
220+
ids = make([]bson.ObjectId, 0)
221+
for _, id := range values {
222+
ids = append(ids, bson.ObjectIdHex(id.(string)))
223+
}
224+
return ids
225+
}
226+
140227
func parseAnd(key string, values []interface{}, q bson.M, t interface{}) bson.M {
141228
val := reflect.ValueOf(t)
142229
if q == nil {
@@ -164,29 +251,13 @@ func parseAnd(key string, values []interface{}, q bson.M, t interface{}) bson.M
164251

165252
func convertName(name string) string {
166253
if name == id || name == _id {
167-
return "ID"
254+
return ID
168255
}
169256
newName := []rune(name)
170257
newName[0] = unicode.ToUpper(newName[0])
171258
return string(newName)
172259
}
173260

174-
func parseAndIDData(key string, field string, data interface{}, q bson.M) bson.M {
175-
if field == id {
176-
field = _id
177-
}
178-
slice := data.(map[string]interface{})
179-
for k, value := range slice {
180-
IDS := prepareInIds(value.(string))
181-
if len(IDS) > 0 {
182-
if k == "in" || k == "nin" || k == "all" {
183-
q[key] = append(q[key].([]bson.M), bson.M{field: bson.M{"$" + k: IDS}})
184-
}
185-
}
186-
}
187-
return q
188-
}
189-
190261
func parseFilterDate(key string, field string, data interface{}, q bson.M) bson.M {
191262
for k, v := range data.(map[string]interface{}) {
192263
if k == "lte" || k == "lt" || k == "gte" || k == "gt" {

0 commit comments

Comments
 (0)