From 73a0401678c280b5eda9e4be00ad71c1966053f3 Mon Sep 17 00:00:00 2001 From: Jinzhu Date: Tue, 17 Feb 2015 23:18:12 +0800 Subject: [PATCH] Cache generated model structs --- main.go | 15 +++++++++------ main_private.go | 2 +- model_struct.go | 27 +++++++++++++++++++++++++++ 3 files changed, 37 insertions(+), 7 deletions(-) diff --git a/main.go b/main.go index 7e709726..3140fea3 100644 --- a/main.go +++ b/main.go @@ -23,6 +23,7 @@ type DB struct { Value interface{} Error error RowsAffected int64 + ModelStructs map[reflect.Type]*ModelStruct callback *callback db sqlCommon parent *DB @@ -61,12 +62,13 @@ func Open(dialect string, args ...interface{}) (DB, error) { } db = DB{ - dialect: NewDialect(dialect), - logger: defaultLogger, - callback: DefaultCallback, - source: source, - values: map[string]interface{}{}, - db: dbSql, + dialect: NewDialect(dialect), + logger: defaultLogger, + callback: DefaultCallback, + source: source, + values: map[string]interface{}{}, + db: dbSql, + ModelStructs: map[reflect.Type]*ModelStruct{}, } db.parent = &db } @@ -114,6 +116,7 @@ func (s *DB) LogMode(enable bool) *DB { } func (s *DB) SingularTable(enable bool) { + s.parent.ModelStructs = map[reflect.Type]*ModelStruct{} s.parent.singularTable = enable } diff --git a/main_private.go b/main_private.go index 7e5c0ef7..914f7007 100644 --- a/main_private.go +++ b/main_private.go @@ -3,7 +3,7 @@ package gorm import "time" func (s *DB) clone() *DB { - db := DB{db: s.db, parent: s.parent, logMode: s.logMode, Value: s.Value, Error: s.Error, values: map[string]interface{}{}} + db := DB{db: s.db, parent: s.parent, logMode: s.logMode, values: map[string]interface{}{}, Value: s.Value, Error: s.Error} for key, value := range s.values { db.values[key] = value diff --git a/model_struct.go b/model_struct.go index 77f3ec39..7d196e6e 100644 --- a/model_struct.go +++ b/model_struct.go @@ -33,6 +33,24 @@ type StructField struct { Relationship *Relationship } +func (structField *StructField) clone() *StructField { + return &StructField{ + DBName: structField.DBName, + Name: structField.Name, + Names: structField.Names, + IsPrimaryKey: structField.IsPrimaryKey, + IsScanner: structField.IsScanner, + IsTime: structField.IsTime, + IsNormal: structField.IsNormal, + IsIgnored: structField.IsIgnored, + DefaultValue: structField.DefaultValue, + SqlTag: structField.SqlTag, + Tag: structField.Tag, + Struct: structField.Struct, + Relationship: structField.Relationship, + } +} + type Relationship struct { Kind string ForeignType string @@ -105,6 +123,14 @@ func (scope *Scope) GetModelStruct() *ModelStruct { } scopeType := reflectValue.Type() + if scope.db != nil { + if value, ok := scope.db.parent.ModelStructs[scopeType]; ok { + return value + } else { + scope.db.parent.ModelStructs[scopeType] = &modelStruct + } + } + if scopeType.Kind() == reflect.Ptr { scopeType = scopeType.Elem() } @@ -223,6 +249,7 @@ func (scope *Scope) GetModelStruct() *ModelStruct { case reflect.Struct: if _, ok := gormSettings["EMBEDDED"]; ok || fieldStruct.Anonymous { for _, field := range scope.New(reflect.New(indirectType).Interface()).GetStructFields() { + field = field.clone() field.Names = append([]string{fieldStruct.Name}, field.Names...) modelStruct.StructFields = append(modelStruct.StructFields, field) }