forked from mirror/gorm
feat: copy dest fields to model struct
This commit is contained in:
parent
4581e8b590
commit
eaa63d15e7
|
@ -23,11 +23,38 @@ func SetupUpdateReflectValue(db *gorm.DB) {
|
||||||
rel.Field.Set(db.Statement.ReflectValue, dest[rel.Name])
|
rel.Field.Set(db.Statement.ReflectValue, dest[rel.Name])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if modelType, destType := findType(db.Statement.Model), findType(db.Statement.Dest); modelType.Kind() == reflect.Struct && destType.Kind() == reflect.Struct {
|
||||||
|
db.Statement.Dest = transToModel(reflect.Indirect(reflect.ValueOf(db.Statement.Dest)), reflect.New(modelType).Elem())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func findType(target interface{}) reflect.Type {
|
||||||
|
t := reflect.TypeOf(target)
|
||||||
|
if t.Kind() == reflect.Ptr {
|
||||||
|
return t.Elem()
|
||||||
|
}
|
||||||
|
return t
|
||||||
|
}
|
||||||
|
|
||||||
|
func transToModel(from, to reflect.Value) interface{} {
|
||||||
|
if from.String() == to.String() {
|
||||||
|
return from.Interface()
|
||||||
|
}
|
||||||
|
|
||||||
|
fromType := from.Type()
|
||||||
|
for i := 0; i < fromType.NumField(); i++ {
|
||||||
|
fieldName := fromType.Field(i).Name
|
||||||
|
fromField, toField := from.FieldByName(fieldName), to.FieldByName(fieldName)
|
||||||
|
if !toField.IsValid() || !toField.CanSet() || toField.Kind() != fromField.Kind() {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
toField.Set(fromField)
|
||||||
|
}
|
||||||
|
return to.Interface()
|
||||||
|
}
|
||||||
|
|
||||||
func BeforeUpdate(db *gorm.DB) {
|
func BeforeUpdate(db *gorm.DB) {
|
||||||
if db.Error == nil && db.Statement.Schema != nil && !db.Statement.SkipHooks && (db.Statement.Schema.BeforeSave || db.Statement.Schema.BeforeUpdate) {
|
if db.Error == nil && db.Statement.Schema != nil && !db.Statement.SkipHooks && (db.Statement.Schema.BeforeSave || db.Statement.Schema.BeforeUpdate) {
|
||||||
callMethod(db, func(value interface{}, tx *gorm.DB) (called bool) {
|
callMethod(db, func(value interface{}, tx *gorm.DB) (called bool) {
|
||||||
|
@ -227,7 +254,7 @@ func ConvertToAssignments(stmt *gorm.Statement) (set clause.Set) {
|
||||||
set = make([]clause.Assignment, 0, len(stmt.Schema.FieldsByDBName))
|
set = make([]clause.Assignment, 0, len(stmt.Schema.FieldsByDBName))
|
||||||
for _, dbName := range stmt.Schema.DBNames {
|
for _, dbName := range stmt.Schema.DBNames {
|
||||||
field := stmt.Schema.LookUpField(dbName)
|
field := stmt.Schema.LookUpField(dbName)
|
||||||
if !field.PrimaryKey || (!updatingValue.CanAddr() || stmt.Dest != stmt.Model) {
|
if !field.PrimaryKey || !updatingValue.CanAddr() || stmt.Dest != stmt.Model {
|
||||||
if v, ok := selectColumns[field.DBName]; (ok && v) || (!ok && (!restricted || (!stmt.SkipHooks && field.AutoUpdateTime > 0))) {
|
if v, ok := selectColumns[field.DBName]; (ok && v) || (!ok && (!restricted || (!stmt.SkipHooks && field.AutoUpdateTime > 0))) {
|
||||||
value, isZero := field.ValueOf(updatingValue)
|
value, isZero := field.ValueOf(updatingValue)
|
||||||
if !stmt.SkipHooks && field.AutoUpdateTime > 0 {
|
if !stmt.SkipHooks && field.AutoUpdateTime > 0 {
|
||||||
|
|
Loading…
Reference in New Issue