models_utils.go
3.13 KB
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
137
138
139
140
141
142
143
144
145
146
147
148
package orm
import (
"fmt"
"reflect"
"strings"
"time"
)
func getFullName(typ reflect.Type) string {
return typ.PkgPath() + "." + typ.Name()
}
func getTableName(val reflect.Value) string {
ind := reflect.Indirect(val)
fun := val.MethodByName("TableName")
if fun.IsValid() {
vals := fun.Call([]reflect.Value{})
if len(vals) > 0 {
val := vals[0]
if val.Kind() == reflect.String {
return val.String()
}
}
}
return snakeString(ind.Type().Name())
}
func getTableEngine(val reflect.Value) string {
fun := val.MethodByName("TableEngine")
if fun.IsValid() {
vals := fun.Call([]reflect.Value{})
if len(vals) > 0 {
val := vals[0]
if val.Kind() == reflect.String {
return val.String()
}
}
}
return ""
}
func getTableIndex(val reflect.Value) [][]string {
fun := val.MethodByName("TableIndex")
if fun.IsValid() {
vals := fun.Call([]reflect.Value{})
if len(vals) > 0 {
val := vals[0]
if val.CanInterface() {
if d, ok := val.Interface().([][]string); ok {
return d
}
}
}
}
return nil
}
func getTableUnique(val reflect.Value) [][]string {
fun := val.MethodByName("TableUnique")
if fun.IsValid() {
vals := fun.Call([]reflect.Value{})
if len(vals) > 0 {
val := vals[0]
if val.CanInterface() {
if d, ok := val.Interface().([][]string); ok {
return d
}
}
}
}
return nil
}
func getColumnName(ft int, addrField reflect.Value, sf reflect.StructField, col string) string {
col = strings.ToLower(col)
column := col
if col == "" {
column = snakeString(sf.Name)
}
switch ft {
case RelForeignKey, RelOneToOne:
if len(col) == 0 {
column = column + "_id"
}
case RelManyToMany, RelReverseMany, RelReverseOne:
column = sf.Name
}
return column
}
func getFieldType(val reflect.Value) (ft int, err error) {
elm := reflect.Indirect(val)
switch elm.Kind() {
case reflect.Int8:
ft = TypeBitField
case reflect.Int16:
ft = TypeSmallIntegerField
case reflect.Int32, reflect.Int:
ft = TypeIntegerField
case reflect.Int64:
ft = TypeBigIntegerField
case reflect.Uint8:
ft = TypePositiveBitField
case reflect.Uint16:
ft = TypePositiveSmallIntegerField
case reflect.Uint32, reflect.Uint:
ft = TypePositiveIntegerField
case reflect.Uint64:
ft = TypePositiveBigIntegerField
case reflect.Float32, reflect.Float64:
ft = TypeFloatField
case reflect.Bool:
ft = TypeBooleanField
case reflect.String:
ft = TypeCharField
case reflect.Invalid:
default:
if elm.CanInterface() {
if _, ok := elm.Interface().(time.Time); ok {
ft = TypeDateTimeField
}
}
}
if ft&IsFieldType == 0 {
err = fmt.Errorf("unsupport field type %s, may be miss setting tag", val)
}
return
}
func parseStructTag(data string, attrs *map[string]bool, tags *map[string]string) {
attr := make(map[string]bool)
tag := make(map[string]string)
for _, v := range strings.Split(data, defaultStructTagDelim) {
v = strings.TrimSpace(v)
if supportTag[v] == 1 {
attr[v] = true
} else if i := strings.Index(v, "("); i > 0 && strings.Index(v, ")") == len(v)-1 {
name := v[:i]
if supportTag[name] == 2 {
v = v[i+1 : len(v)-1]
tag[name] = v
}
}
}
*attrs = attr
*tags = tag
}