fix: soft delete for join, close #5132

commit a83023bdfc0dc6eaccc6704b64ff6436c2fe7725
Author: Jinzhu <wosmvp@gmail.com>
Date:   Fri Mar 18 01:05:25 2022 +0800

    Refactor #5132

commit 8559f51102c01be6c19913c0bc3a5771721ff1f5
Author: chenrui <chenrui@jingdaka.com>
Date:   Mon Mar 7 20:33:12 2022 +0800

    fix: should add deleted_at exprs for every joins

commit 2b7a1bdcf3eff9d23253173d21e73c1f056f9be4
Author: chenrui <chenrui@jingdaka.com>
Date:   Mon Mar 7 14:46:48 2022 +0800

    test: move debug flag

commit ce13a2a7bc50d2c23678806acf65dbd589827c77
Author: chenrui <chenrui@jingdaka.com>
Date:   Mon Mar 7 14:39:56 2022 +0800

    fix: soft delete for join.on
This commit is contained in:
chenrui 2022-03-18 01:07:49 +08:00 committed by Jinzhu
parent 9b9ae325bb
commit c2e36ebe62
3 changed files with 62 additions and 12 deletions

View File

@ -145,12 +145,23 @@ func BuildQuerySQL(db *gorm.DB) {
} }
} }
{
onStmt := gorm.Statement{Table: tableAliasName, DB: db, Clauses: map[string]clause.Clause{}}
for _, c := range relation.FieldSchema.QueryClauses {
onStmt.AddClause(c)
}
if join.On != nil { if join.On != nil {
onStmt := gorm.Statement{Table: tableAliasName, DB: db} onStmt.AddClause(join.On)
join.On.Build(&onStmt) }
onSQL := onStmt.SQL.String()
if cs, ok := onStmt.Clauses["WHERE"]; ok {
if where, ok := cs.Expression.(clause.Where); ok {
where.Build(&onStmt)
if onSQL := onStmt.SQL.String(); onSQL != "" {
vars := onStmt.Vars vars := onStmt.Vars
for idx, v := range onStmt.Vars { for idx, v := range vars {
bindvar := strings.Builder{} bindvar := strings.Builder{}
onStmt.Vars = vars[0 : idx+1] onStmt.Vars = vars[0 : idx+1]
db.Dialector.BindVarTo(&bindvar, &onStmt, v) db.Dialector.BindVarTo(&bindvar, &onStmt, v)
@ -159,6 +170,9 @@ func BuildQuerySQL(db *gorm.DB) {
exprs = append(exprs, clause.Expr{SQL: onSQL, Vars: vars}) exprs = append(exprs, clause.Expr{SQL: onSQL, Vars: vars})
} }
}
}
}
joins = append(joins, clause.Join{ joins = append(joins, clause.Join{
Type: clause.LeftJoin, Type: clause.LeftJoin,
@ -172,8 +186,8 @@ func BuildQuerySQL(db *gorm.DB) {
} }
} }
db.Statement.Joins = nil
db.Statement.AddClause(clause.From{Joins: joins}) db.Statement.AddClause(clause.From{Joins: joins})
db.Statement.Joins = nil
} else { } else {
db.Statement.AddClauseIfNotExists(clause.From{}) db.Statement.AddClauseIfNotExists(clause.From{})
} }

View File

@ -19,6 +19,7 @@ type Config struct {
Team int Team int
Languages int Languages int
Friends int Friends int
NamedPet bool
} }
func GetUser(name string, config Config) *User { func GetUser(name string, config Config) *User {
@ -65,6 +66,10 @@ func GetUser(name string, config Config) *User {
user.Friends = append(user.Friends, GetUser(name+"_friend_"+strconv.Itoa(i+1), Config{})) user.Friends = append(user.Friends, GetUser(name+"_friend_"+strconv.Itoa(i+1), Config{}))
} }
if config.NamedPet {
user.NamedPet = &Pet{Name: name + "_namepet"}
}
return &user return &user
} }

View File

@ -200,3 +200,34 @@ func TestJoinCount(t *testing.T) {
t.Fatalf("result's id, %d, doesn't match user's id, %d", result.ID, user.ID) t.Fatalf("result's id, %d, doesn't match user's id, %d", result.ID, user.ID)
} }
} }
func TestJoinWithSoftDeleted(t *testing.T) {
DB = DB.Debug()
user := GetUser("TestJoinWithSoftDeletedUser", Config{Account: true, NamedPet: true})
DB.Create(&user)
var user1 User
DB.Model(&User{}).Joins("NamedPet").Joins("Account").First(&user1, user.ID)
if user1.NamedPet == nil || user1.Account.ID == 0 {
t.Fatalf("joins NamedPet and Account should not empty:%v", user1)
}
// Account should empty
DB.Delete(&user1.Account)
var user2 User
DB.Model(&User{}).Joins("NamedPet").Joins("Account").First(&user2, user.ID)
if user2.NamedPet == nil || user2.Account.ID != 0 {
t.Fatalf("joins Account should not empty:%v", user2)
}
// NamedPet should empty
DB.Delete(&user1.NamedPet)
var user3 User
DB.Model(&User{}).Joins("NamedPet").Joins("Account").First(&user3, user.ID)
if user3.NamedPet != nil || user2.Account.ID != 0 {
t.Fatalf("joins NamedPet and Account should not empty:%v", user2)
}
}