forked from Oskang09/goloquent
-
Notifications
You must be signed in to change notification settings - Fork 0
/
filter.go
113 lines (102 loc) · 2.1 KB
/
filter.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
package goloquent
import (
"fmt"
"reflect"
"time"
"cloud.google.com/go/datastore"
)
// Filter :
type Filter struct {
field string
operator operator
value interface{}
isJSON bool
raw string
}
// Field :
func (f Filter) Field() string {
return f.field
}
// IsJSON :
func (f Filter) IsJSON() bool {
return f.isJSON
}
// JSON :
type JSON struct {
}
// JSON :
func (f Filter) JSON() *JSON {
return &JSON{}
}
// Interface :
func (f *Filter) Interface() (interface{}, error) {
v, err := normalizeValue(f.value)
if err != nil {
return nil, err
}
return interfaceToValue(v)
}
// final data type :
// string, bool, uint64, int64, float64, []byte
// time.Time, *datastore.Key, datastore.GeoPoint, []interface{}
func normalizeValue(val interface{}) (interface{}, error) {
if val == nil {
return nil, nil
}
v := reflect.ValueOf(val)
var it interface{}
t := v.Type()
switch vi := v.Interface().(type) {
case *datastore.Key:
if vi == nil {
return nil, nil
}
it = vi
case datastore.GeoPoint:
it = geoLocation{vi.Lat, vi.Lng}
case time.Time:
it = vi
case Date:
it = vi
default:
switch t.Kind() {
case reflect.String:
it = v.String()
case reflect.Bool:
it = v.Bool()
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
it = v.Uint()
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
it = v.Int()
case reflect.Float32, reflect.Float64:
it = v.Float()
case reflect.Slice, reflect.Array:
if t.Elem().Kind() == reflect.Uint8 {
return v.Bytes(), nil
}
arr := make([]interface{}, 0, v.Len())
for i := 0; i < v.Len(); i++ {
vv := v.Index(i)
var vi, err = normalizeValue(vv.Interface())
if err != nil {
return vi, err
}
arr = append(arr, vi)
}
it = arr
case reflect.Ptr:
if v.IsNil() {
return nil, nil
}
var val, err = normalizeValue(v.Elem().Interface())
if err != nil {
return nil, err
}
vi := reflect.ValueOf(val).Interface()
it = &vi
default:
return nil, fmt.Errorf("goloquent: unsupported data type %v", t)
}
}
return it, nil
}