From fb48d751afcb025b33bde5aced0e981412f4bd0a Mon Sep 17 00:00:00 2001 From: bigpigeon Date: Sun, 24 Sep 2017 17:23:18 +0800 Subject: [PATCH 1/2] 1. add update with primary key member test --- main_test.go | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/main_test.go b/main_test.go index 34f96a86..6e178dd1 100644 --- a/main_test.go +++ b/main_test.go @@ -861,6 +861,36 @@ func TestBlockGlobalUpdate(t *testing.T) { } } +func TestUpdatePrimaryKey(t *testing.T) { + type Product struct { + gorm.Model + Name string + Price int + } + type LightItem struct { + gorm.Model + Name string + MyProductID uint `gorm:"index"` + MyProduct Product + } + tables := []interface{}{&LightItem{}, &Product{}} + for _, t := range tables { + DB.DropTableIfExists(t) + DB.CreateTable(t) + } + p := Product{Name: "mi6", Price: 2499} + if err := DB.Save(&p).Error; err != nil { + t.Errorf("Failure to Save with product(%v)", err) + } + l := LightItem{Name: "line", MyProductID: p.ID} + if err := DB.Save(&l).Error; err != nil { + t.Errorf("Failure to Save with light item(%v)", err) + } + if err := DB.Updates(&l).Error; err != nil { + t.Errorf("Failure to update that have primary key object:reason(%v)", err) + } +} + func BenchmarkGorm(b *testing.B) { b.N = 2000 for x := 0; x < b.N; x++ { From 0a21873c6ea2f4b262b5babe27f1994be63fa8bb Mon Sep 17 00:00:00 2001 From: bigpigeon Date: Sun, 24 Sep 2017 17:44:07 +0800 Subject: [PATCH 2/2] 1. fix updates with primary key bug --- errors.go | 2 ++ main.go | 17 +++++++++++++---- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/errors.go b/errors.go index 6845188e..42e2e1a1 100644 --- a/errors.go +++ b/errors.go @@ -16,6 +16,8 @@ var ( ErrCantStartTransaction = errors.New("can't start transaction") // ErrUnaddressable unaddressable value ErrUnaddressable = errors.New("using unaddressable value") + // ErrUpdateWithInvalidPrimaryKey ,when update with a invalid primary key + ErrUpdateWithInvalidPrimaryKey = errors.New("invalid primary key") ) // Errors contains all happened errors diff --git a/main.go b/main.go index 16fa0b79..480cb4f0 100644 --- a/main.go +++ b/main.go @@ -377,10 +377,19 @@ func (s *DB) Update(attrs ...interface{}) *DB { // Updates update attributes with callbacks, refer: https://jinzhu.github.io/gorm/crud.html#update func (s *DB) Updates(values interface{}, ignoreProtectedAttrs ...bool) *DB { - return s.clone().NewScope(s.Value). - Set("gorm:ignore_protected_attrs", len(ignoreProtectedAttrs) > 0). - InstanceSet("gorm:update_interface", values). - callCallbacks(s.parent.callbacks.updates).db + scope := s.clone().NewScope(values) + // if not primary key ,use old updates rule + if scope.PrimaryKeyZero() { + return s.clone().NewScope(s.Value). + Set("gorm:ignore_protected_attrs", len(ignoreProtectedAttrs) > 0). + InstanceSet("gorm:update_interface", values). + callCallbacks(s.parent.callbacks.updates).db + } + newDB := scope.callCallbacks(s.parent.callbacks.updates).db + if newDB.Error == nil && newDB.RowsAffected == 0 { + newDB.AddError(ErrUpdateWithInvalidPrimaryKey) + } + return newDB } // UpdateColumn update attributes without callbacks, refer: https://jinzhu.github.io/gorm/crud.html#update