Skip to content

Commit 109f239

Browse files
authored
add DB level propagation for the Unscoped flag (go-gorm#7007)
* adds PropagateUnscoped to db Config * adds PropagateUnscoped test * adds PropagateUnscoped to Session and sets it accordingly
1 parent 79bf7f9 commit 109f239

File tree

2 files changed

+53
-0
lines changed

2 files changed

+53
-0
lines changed

gorm.go

+10
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ type Config struct {
5050
CreateBatchSize int
5151
// TranslateError enabling error translation
5252
TranslateError bool
53+
// PropagateUnscoped propagate Unscoped to every other nested statement
54+
PropagateUnscoped bool
5355

5456
// ClauseBuilders clause builder
5557
ClauseBuilders map[string]clause.ClauseBuilder
@@ -110,6 +112,7 @@ type Session struct {
110112
DisableNestedTransaction bool
111113
AllowGlobalUpdate bool
112114
FullSaveAssociations bool
115+
PropagateUnscoped bool
113116
QueryFields bool
114117
Context context.Context
115118
Logger logger.Interface
@@ -241,6 +244,10 @@ func (db *DB) Session(config *Session) *DB {
241244
txConfig.FullSaveAssociations = true
242245
}
243246

247+
if config.PropagateUnscoped {
248+
txConfig.PropagateUnscoped = true
249+
}
250+
244251
if config.Context != nil || config.PrepareStmt || config.SkipHooks {
245252
tx.Statement = tx.Statement.clone()
246253
tx.Statement.DB = tx
@@ -409,6 +416,9 @@ func (db *DB) getInstance() *DB {
409416
Vars: make([]interface{}, 0, 8),
410417
SkipHooks: db.Statement.SkipHooks,
411418
}
419+
if db.Config.PropagateUnscoped {
420+
tx.Statement.Unscoped = db.Statement.Unscoped
421+
}
412422
} else {
413423
// with clone statement
414424
tx.Statement = db.Statement.clone()

tests/hooks_test.go

+43
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ package tests_test
22

33
import (
44
"errors"
5+
"log"
6+
"os"
57
"reflect"
68
"strings"
79
"testing"
@@ -566,3 +568,44 @@ func TestUpdateCallbacks(t *testing.T) {
566568
t.Fatalf("before update should not be called")
567569
}
568570
}
571+
572+
type Product6 struct {
573+
gorm.Model
574+
Name string
575+
Item *ProductItem2
576+
}
577+
578+
type ProductItem2 struct {
579+
gorm.Model
580+
Product6ID uint
581+
}
582+
583+
func (p *Product6) BeforeDelete(tx *gorm.DB) error {
584+
if err := tx.Delete(&p.Item).Error; err != nil {
585+
return err
586+
}
587+
return nil
588+
}
589+
590+
func TestPropagateUnscoped(t *testing.T) {
591+
_DB, err := OpenTestConnection(&gorm.Config{
592+
PropagateUnscoped: true,
593+
})
594+
if err != nil {
595+
log.Printf("failed to connect database, got error %v", err)
596+
os.Exit(1)
597+
}
598+
599+
_DB.Migrator().DropTable(&Product6{}, &ProductItem2{})
600+
_DB.AutoMigrate(&Product6{}, &ProductItem2{})
601+
602+
p := Product6{
603+
Name: "unique_code",
604+
Item: &ProductItem2{},
605+
}
606+
_DB.Model(&Product6{}).Create(&p)
607+
608+
if err := _DB.Unscoped().Delete(&p).Error; err != nil {
609+
t.Fatalf("unscoped did not propagate")
610+
}
611+
}

0 commit comments

Comments
 (0)