/
model.go
155 lines (122 loc) · 2.71 KB
/
model.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
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
package daoongorm
import (
"fmt"
"reflect"
"strings"
"github.com/iancoleman/strcase"
)
// 模型
type Model interface {
TableName() string
DBName() string
DBClient() DBClientInterface
GetDaoBase() *DaoBase
SetDaoBase(myDaoBase *DaoBase)
}
// 模型定义
type ModelDef struct {
ModelType reflect.Type
FullName string
PKFields map[string]*Field
Fields map[string]*Field
mapColumnNameFieldName map[string]string
}
func NewModelDef(m interface{}) *ModelDef {
fullName, v := GetModelFullNameAndValue(m)
t := v.Type()
mo := &ModelDef{
ModelType: t,
FullName: fullName,
mapColumnNameFieldName: make(map[string]string),
}
hasPrimaryKey := false
mf := make(map[string]*Field)
pkFields := make(map[string]*Field)
for i := 0; i < t.NumField(); i++ {
tf := t.Field(i)
f := newField(&tf)
if f.Tag.Ignore {
continue
}
if f.IsPrimaryKey() {
hasPrimaryKey = true
pkFields[tf.Name] = f
}
mf[tf.Name] = f
mo.mapColumnNameFieldName[f.ColumnName] = tf.Name
}
if !hasPrimaryKey {
panic("没有设定主键")
}
mo.Fields = mf
mo.PKFields = pkFields
return mo
}
type Field struct {
Name string
StructField *reflect.StructField
Tag *FieldTag
Kind reflect.Kind
ColumnName string
}
func newField(sf *reflect.StructField) *Field {
ft := NewFieldTag(sf.Tag.Get("gorm"))
columnName := ft.ColumnName
if columnName == "" {
columnName = strcase.ToSnake(sf.Name)
}
f := &Field{
Name: sf.Name,
StructField: sf,
Tag: ft,
Kind: sf.Type.Kind(),
ColumnName: columnName,
//Nullable: nullable,
}
return f
}
func (f *Field) IsPrimaryKey() bool {
return f.Tag.IsPK
}
type FieldTag struct {
ColumnName string
Val string
IsPK bool
Ignore bool
ColumnDefault string
HaveColumnDefault bool // 是否有设置默认值
}
func NewFieldTag(tag string) *FieldTag {
ft := &FieldTag{Val: tag}
if tag == "" || tag == "-" {
ft.Ignore = true
}
s := strings.Split(tag, ";")
for _, v := range s {
if strings.EqualFold(v, "primaryKey") {
ft.IsPK = true
}
if strings.HasPrefix(v, "column:") {
cns := strings.Split(v, ":")
if len(cns) == 2 {
ft.ColumnName = strings.Trim(cns[1], " ")
}
}
if strings.HasPrefix(v, "column_default:") {
ft.HaveColumnDefault = true
cns := strings.Split(v, ":")
if len(cns) == 2 {
ft.ColumnDefault = cns[1]
}
}
}
return ft
}
func GetModelFullNameAndValue(m interface{}) (string, reflect.Value) {
if m == nil {
panic("m不能是nil")
}
v := reflect.ValueOf(m).Elem()
t := v.Type()
return fmt.Sprintf("%s.%s", t.PkgPath(), t.Name()), v
}