-
Notifications
You must be signed in to change notification settings - Fork 39
/
util.go
133 lines (119 loc) · 3.34 KB
/
util.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
package gosql
import (
"reflect"
"sort"
"time"
)
//inSlice
func inSlice(k string, s []string) bool {
for _, v := range s {
if k == v {
return true
}
}
return false
}
//IsZero assert value is zero value
func IsZero(val reflect.Value) bool {
if !val.IsValid() {
return true
}
kind := val.Kind()
switch kind {
case reflect.String:
return val.Len() == 0
case reflect.Bool:
return val.Bool() == false
case reflect.Float32, reflect.Float64:
return val.Float() == 0
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
return val.Int() == 0
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
return val.Uint() == 0
case reflect.Ptr, reflect.Chan, reflect.Func, reflect.Interface, reflect.Slice, reflect.Map:
return val.IsNil()
case reflect.Array:
for i := 0; i < val.Len(); i++ {
if !IsZero(val.Index(i)) {
return false
}
}
return true
case reflect.Struct:
if t, ok := val.Interface().(time.Time); ok {
return t.IsZero()
} else {
valid := val.FieldByName("Valid")
if valid.IsValid() {
va, ok := valid.Interface().(bool)
return ok && !va
}
return reflect.DeepEqual(val.Interface(), reflect.Zero(val.Type()).Interface())
}
default:
return reflect.DeepEqual(val.Interface(), reflect.Zero(val.Type()).Interface())
}
}
//zeroValueFilter filter zero value and keep the specified zero value
func zeroValueFilter(fields map[string]reflect.Value, zv []string) map[string]interface{} {
m := make(map[string]interface{})
for k, v := range fields {
v = reflect.Indirect(v)
if inSlice(k, zv) || !IsZero(v) {
m[k] = v.Interface()
}
}
return m
}
// structAutoTime auto set created_at updated_at
func structAutoTime(fields map[string]reflect.Value, f []string) {
for k, v := range fields {
v = reflect.Indirect(v)
if v.IsValid() && inSlice(k, f) && IsZero(v) {
switch v.Kind() {
case reflect.String:
v.SetString(time.Now().Format("2006-01-02 15:04:05"))
case reflect.Struct:
// truncate 1 sec, Otherwise the data you create and the data you get will never be compared
v.Set(reflect.ValueOf(time.Now().Truncate(1 * time.Second)))
case reflect.Int, reflect.Int32, reflect.Int64:
v.SetInt(time.Now().Unix())
case reflect.Uint, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
v.SetUint(uint64(time.Now().Unix()))
}
}
}
}
// structToMap
func structToMap(fields map[string]reflect.Value) map[string]interface{} {
m := make(map[string]interface{})
for k, v := range fields {
v = reflect.Indirect(v)
m[k] = v.Interface()
}
return m
}
// fillPrimaryKey is created fill primary key
func fillPrimaryKey(v reflect.Value, value int64) {
v = reflect.Indirect(v)
if v.IsValid() {
switch v.Kind() {
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
v.SetInt(value)
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
v.SetUint(uint64(value))
}
}
}
// sortedParamKeys Sorts the param names given - map iteration order is explicitly random in Go
// but we need params in a defined order to avoid unexpected results.
func sortedParamKeys(params map[string]interface{}) []string {
sortedKeys := make([]string, len(params))
i := 0
for k := range params {
sortedKeys[i] = k
i++
}
sort.Strings(sortedKeys)
return sortedKeys
}