diff --git a/callbacks/delete.go b/callbacks/delete.go index 288f2d69..f444f020 100644 --- a/callbacks/delete.go +++ b/callbacks/delete.go @@ -51,7 +51,7 @@ func Delete(db *gorm.DB) { } } - if _, ok := db.Statement.Clauses["WHERE"]; !ok { + if _, ok := db.Statement.Clauses["WHERE"]; !db.AllowGlobalUpdate && !ok { db.AddError(gorm.ErrMissingWhereClause) return } diff --git a/callbacks/update.go b/callbacks/update.go index 5656d166..bd8a4150 100644 --- a/callbacks/update.go +++ b/callbacks/update.go @@ -69,7 +69,7 @@ func Update(db *gorm.DB) { db.Statement.Build("UPDATE", "SET", "WHERE") } - if _, ok := db.Statement.Clauses["WHERE"]; !ok { + if _, ok := db.Statement.Clauses["WHERE"]; !db.AllowGlobalUpdate && !ok { db.AddError(gorm.ErrMissingWhereClause) return } diff --git a/gorm.go b/gorm.go index 1ace0099..3c187f42 100644 --- a/gorm.go +++ b/gorm.go @@ -32,6 +32,8 @@ type Config struct { DisableAutomaticPing bool // DisableForeignKeyConstraintWhenMigrating DisableForeignKeyConstraintWhenMigrating bool + // AllowGlobalUpdate allow global update + AllowGlobalUpdate bool // ClauseBuilders clause builder ClauseBuilders map[string]clause.ClauseBuilder @@ -61,6 +63,7 @@ type Session struct { PrepareStmt bool WithConditions bool SkipDefaultTransaction bool + AllowGlobalUpdate bool Context context.Context Logger logger.Interface NowFunc func() time.Time @@ -154,6 +157,10 @@ func (db *DB) Session(config *Session) *DB { tx.Config.SkipDefaultTransaction = true } + if config.AllowGlobalUpdate { + txConfig.AllowGlobalUpdate = true + } + if config.Context != nil { tx.Statement = tx.Statement.clone() tx.Statement.DB = tx diff --git a/soft_delete.go b/soft_delete.go index 875623bc..d33bf866 100644 --- a/soft_delete.go +++ b/soft_delete.go @@ -98,7 +98,7 @@ func (sd SoftDeleteDeleteClause) ModifyStatement(stmt *Statement) { } } - if _, ok := stmt.Clauses["WHERE"]; !ok { + if _, ok := stmt.Clauses["WHERE"]; !stmt.DB.AllowGlobalUpdate && !ok { stmt.DB.AddError(ErrMissingWhereClause) return } diff --git a/tests/delete_test.go b/tests/delete_test.go index f5b3e784..09c1a075 100644 --- a/tests/delete_test.go +++ b/tests/delete_test.go @@ -118,4 +118,8 @@ func TestBlockGlobalDelete(t *testing.T) { if err := DB.Delete(&User{}).Error; err == nil || !errors.Is(err, gorm.ErrMissingWhereClause) { t.Errorf("should returns missing WHERE clause while deleting error") } + + if err := DB.Session(&gorm.Session{AllowGlobalUpdate: true}).Delete(&User{}).Error; err != nil { + t.Errorf("should returns no error while enable global update, but got err %v", err) + } } diff --git a/tests/update_test.go b/tests/update_test.go index 49a13be9..e52dc652 100644 --- a/tests/update_test.go +++ b/tests/update_test.go @@ -222,6 +222,10 @@ func TestBlockGlobalUpdate(t *testing.T) { if err := DB.Model(&User{}).Update("name", "jinzhu").Error; err == nil || !errors.Is(err, gorm.ErrMissingWhereClause) { t.Errorf("should returns missing WHERE clause while updating error, got err %v", err) } + + if err := DB.Session(&gorm.Session{AllowGlobalUpdate: true}).Model(&User{}).Update("name", "jinzhu").Error; err != nil { + t.Errorf("should returns no error while enable global update, but got err %v", err) + } } func TestSelectWithUpdate(t *testing.T) {