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 8559f51102
Author: chenrui <chenrui@jingdaka.com>
Date:   Mon Mar 7 20:33:12 2022 +0800

    fix: should add deleted_at exprs for every joins

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

    test: move debug flag

commit ce13a2a7bc
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,19 +145,33 @@ func BuildQuerySQL(db *gorm.DB) {
}
}
if join.On != nil {
onStmt := gorm.Statement{Table: tableAliasName, DB: db}
join.On.Build(&onStmt)
onSQL := onStmt.SQL.String()
vars := onStmt.Vars
for idx, v := range onStmt.Vars {
bindvar := strings.Builder{}
onStmt.Vars = vars[0 : idx+1]
db.Dialector.BindVarTo(&bindvar, &onStmt, v)
onSQL = strings.Replace(onSQL, bindvar.String(), "?", 1)
{
onStmt := gorm.Statement{Table: tableAliasName, DB: db, Clauses: map[string]clause.Clause{}}
for _, c := range relation.FieldSchema.QueryClauses {
onStmt.AddClause(c)
}
exprs = append(exprs, clause.Expr{SQL: onSQL, Vars: vars})
if join.On != nil {
onStmt.AddClause(join.On)
}
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
for idx, v := range vars {
bindvar := strings.Builder{}
onStmt.Vars = vars[0 : idx+1]
db.Dialector.BindVarTo(&bindvar, &onStmt, v)
onSQL = strings.Replace(onSQL, bindvar.String(), "?", 1)
}
exprs = append(exprs, clause.Expr{SQL: onSQL, Vars: vars})
}
}
}
}
joins = append(joins, clause.Join{
@ -172,8 +186,8 @@ func BuildQuerySQL(db *gorm.DB) {
}
}
db.Statement.Joins = nil
db.Statement.AddClause(clause.From{Joins: joins})
db.Statement.Joins = nil
} else {
db.Statement.AddClauseIfNotExists(clause.From{})
}

View File

@ -19,6 +19,7 @@ type Config struct {
Team int
Languages int
Friends int
NamedPet bool
}
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{}))
}
if config.NamedPet {
user.NamedPet = &Pet{Name: name + "_namepet"}
}
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)
}
}
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)
}
}