Fix can't update record with customized primary key

This commit is contained in:
Jinzhu 2014-11-11 11:46:21 +08:00
parent a29ac54e48
commit 010e7a90b3
2 changed files with 53 additions and 39 deletions

View File

@ -6,7 +6,7 @@ import (
) )
type CustomizeColumn struct { type CustomizeColumn struct {
Id int64 `gorm:"column:mapped_id; primary_key:yes"` ID int64 `gorm:"column:mapped_id; primary_key:yes"`
Name string `gorm:"column:mapped_name"` Name string `gorm:"column:mapped_name"`
Date time.Time `gorm:"column:mapped_time"` Date time.Time `gorm:"column:mapped_time"`
} }
@ -14,8 +14,8 @@ type CustomizeColumn struct {
// Make sure an ignored field does not interfere with another field's custom // Make sure an ignored field does not interfere with another field's custom
// column name that matches the ignored field. // column name that matches the ignored field.
type CustomColumnAndIgnoredFieldClash struct { type CustomColumnAndIgnoredFieldClash struct {
Body string `sql:"-"` Body string `sql:"-"`
RawBody string `gorm:"column:body"` RawBody string `gorm:"column:body"`
} }
func TestCustomizeColumn(t *testing.T) { func TestCustomizeColumn(t *testing.T) {
@ -34,16 +34,25 @@ func TestCustomizeColumn(t *testing.T) {
} }
expected := "foo" expected := "foo"
cc := CustomizeColumn{Id: 666, Name: expected, Date: time.Now()} cc := CustomizeColumn{ID: 666, Name: expected, Date: time.Now()}
if count := DB.Save(&cc).RowsAffected; count != 1 { if count := DB.Create(&cc).RowsAffected; count != 1 {
t.Error("There should be one record be affected when create record") t.Error("There should be one record be affected when create record")
} }
var ccs []CustomizeColumn var cc1 CustomizeColumn
DB.Find(&ccs) DB.First(&cc1, 666)
if len(ccs) > 0 && ccs[0].Name != expected && ccs[0].Id != 666 { if cc1.Name != expected {
t.Errorf("Failed to query CustomizeColumn")
}
cc.Name = "bar"
DB.Save(&cc)
var cc2 CustomizeColumn
DB.First(&cc2, 666)
if cc2.Name != "bar" {
t.Errorf("Failed to query CustomizeColumn") t.Errorf("Failed to query CustomizeColumn")
} }
} }

View File

@ -12,16 +12,16 @@ import (
) )
type Scope struct { type Scope struct {
Value interface{} Value interface{}
indirectValue *reflect.Value indirectValue *reflect.Value
Search *search Search *search
Sql string Sql string
SqlVars []interface{} SqlVars []interface{}
db *DB db *DB
skipLeft bool skipLeft bool
primaryKey string primaryKeyField *Field
instanceId string instanceId string
fields map[string]*Field fields map[string]*Field
} }
func (scope *Scope) IndirectValue() reflect.Value { func (scope *Scope) IndirectValue() reflect.Value {
@ -90,27 +90,33 @@ func (scope *Scope) HasError() bool {
return scope.db.Error != nil return scope.db.Error != nil
} }
// PrimaryKey get the primary key's column name func (scope *Scope) PrimaryKeyField() *Field {
func (scope *Scope) PrimaryKey() string { if scope.primaryKeyField == nil {
if scope.primaryKey != "" { var indirectValue = scope.IndirectValue()
return scope.primaryKey
}
var indirectValue = scope.IndirectValue() clone := scope
if indirectValue.Kind() == reflect.Slice {
clone = scope.New(reflect.New(indirectValue.Type().Elem()).Elem().Interface())
}
clone := scope for _, field := range clone.Fields() {
if indirectValue.Kind() == reflect.Slice { if field.IsPrimaryKey {
clone = scope.New(reflect.New(indirectValue.Type().Elem()).Elem().Interface()) scope.primaryKeyField = field
} break
}
for _, field := range clone.Fields() {
if field.IsPrimaryKey {
scope.primaryKey = field.DBName
break
} }
} }
return scope.primaryKey return scope.primaryKeyField
}
// PrimaryKey get the primary key's column name
func (scope *Scope) PrimaryKey() string {
if field := scope.PrimaryKeyField(); field != nil {
return field.DBName
} else {
return ""
}
} }
// PrimaryKeyZero check the primary key is blank or not // PrimaryKeyZero check the primary key is blank or not
@ -120,12 +126,11 @@ func (scope *Scope) PrimaryKeyZero() bool {
// PrimaryKeyValue get the primary key's value // PrimaryKeyValue get the primary key's value
func (scope *Scope) PrimaryKeyValue() interface{} { func (scope *Scope) PrimaryKeyValue() interface{} {
if scope.IndirectValue().Kind() == reflect.Struct { if field := scope.PrimaryKeyField(); field != nil {
if field := scope.IndirectValue().FieldByName(SnakeToUpperCamel(scope.PrimaryKey())); field.IsValid() { return field.Field.Interface()
return field.Interface() } else {
} return 0
} }
return 0
} }
// HasColumn to check if has column // HasColumn to check if has column