mirror of https://github.com/go-gorm/gorm.git
Cache model struct for less GC
This commit is contained in:
parent
9a1c0d956d
commit
88917aa2ef
75
model.go
75
model.go
|
@ -8,6 +8,12 @@ import (
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var modelFieldMap map[string][]reflect.StructField
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
modelFieldMap = map[string][]reflect.StructField{}
|
||||||
|
}
|
||||||
|
|
||||||
type Model struct {
|
type Model struct {
|
||||||
data interface{}
|
data interface{}
|
||||||
do *Do
|
do *Do
|
||||||
|
@ -39,45 +45,58 @@ func (m *Model) primaryKeyDb() string {
|
||||||
return toSnake(m.primaryKey())
|
return toSnake(m.primaryKey())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getStructs(typ reflect.Type) (fs []reflect.StructField) {
|
||||||
|
name := typ.Name()
|
||||||
|
if fs = modelFieldMap[name]; fs != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := 0; i < typ.NumField(); i++ {
|
||||||
|
p := typ.Field(i)
|
||||||
|
if !p.Anonymous && ast.IsExported(p.Name) {
|
||||||
|
fs = append(fs, p)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
modelFieldMap[name] = fs
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
func (m *Model) fields(operation string) (fields []*Field) {
|
func (m *Model) fields(operation string) (fields []*Field) {
|
||||||
indirect_value := m.reflectData()
|
indirect_value := m.reflectData()
|
||||||
if !indirect_value.IsValid() {
|
if !indirect_value.IsValid() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
typ := indirect_value.Type()
|
for _, filed_struct := range getStructs(indirect_value.Type()) {
|
||||||
for i := 0; i < typ.NumField(); i++ {
|
var field Field
|
||||||
p := typ.Field(i)
|
field.Name = filed_struct.Name
|
||||||
if !p.Anonymous && ast.IsExported(p.Name) {
|
field.dbName = toSnake(filed_struct.Name)
|
||||||
var field Field
|
field.isPrimaryKey = m.primaryKeyDb() == field.dbName
|
||||||
field.Name = p.Name
|
value := indirect_value.FieldByName(filed_struct.Name)
|
||||||
field.dbName = toSnake(p.Name)
|
field.model = m
|
||||||
field.isPrimaryKey = m.primaryKeyDb() == field.dbName
|
|
||||||
value := indirect_value.FieldByName(p.Name)
|
|
||||||
field.model = m
|
|
||||||
|
|
||||||
if time_value, is_time := value.Interface().(time.Time); is_time {
|
if time_value, is_time := value.Interface().(time.Time); is_time {
|
||||||
field.autoCreateTime = "created_at" == field.dbName
|
field.autoCreateTime = "created_at" == field.dbName
|
||||||
field.autoUpdateTime = "updated_at" == field.dbName
|
field.autoUpdateTime = "updated_at" == field.dbName
|
||||||
|
|
||||||
switch operation {
|
switch operation {
|
||||||
case "create":
|
case "create":
|
||||||
if (field.autoCreateTime || field.autoUpdateTime) && time_value.IsZero() {
|
if (field.autoCreateTime || field.autoUpdateTime) && time_value.IsZero() {
|
||||||
value.Set(reflect.ValueOf(time.Now()))
|
value.Set(reflect.ValueOf(time.Now()))
|
||||||
}
|
}
|
||||||
case "update":
|
case "update":
|
||||||
if field.autoUpdateTime {
|
if field.autoUpdateTime {
|
||||||
value.Set(reflect.ValueOf(time.Now()))
|
value.Set(reflect.ValueOf(time.Now()))
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
field.structField = p
|
|
||||||
field.reflectValue = value
|
|
||||||
field.Value = value.Interface()
|
|
||||||
field.parseAssociation()
|
|
||||||
fields = append(fields, &field)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
field.structField = filed_struct
|
||||||
|
field.reflectValue = value
|
||||||
|
field.Value = value.Interface()
|
||||||
|
field.parseAssociation()
|
||||||
|
fields = append(fields, &field)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue