Fix Scan with soft delete, close #3712

This commit is contained in:
Jinzhu 2020-11-04 11:03:22 +08:00
parent c915471169
commit 560d303e71
3 changed files with 126 additions and 110 deletions

View File

@ -13,15 +13,7 @@ import (
func Query(db *gorm.DB) { func Query(db *gorm.DB) {
if db.Error == nil { if db.Error == nil {
if db.Statement.Schema != nil && !db.Statement.Unscoped {
for _, c := range db.Statement.Schema.QueryClauses {
db.Statement.AddClause(c)
}
}
if db.Statement.SQL.String() == "" {
BuildQuerySQL(db) BuildQuerySQL(db)
}
if !db.DryRun && db.Error == nil { if !db.DryRun && db.Error == nil {
rows, err := db.Statement.ConnPool.QueryContext(db.Statement.Context, db.Statement.SQL.String(), db.Statement.Vars...) rows, err := db.Statement.ConnPool.QueryContext(db.Statement.Context, db.Statement.SQL.String(), db.Statement.Vars...)
@ -37,6 +29,13 @@ func Query(db *gorm.DB) {
} }
func BuildQuerySQL(db *gorm.DB) { func BuildQuerySQL(db *gorm.DB) {
if db.Statement.Schema != nil && !db.Statement.Unscoped {
for _, c := range db.Statement.Schema.QueryClauses {
db.Statement.AddClause(c)
}
}
if db.Statement.SQL.String() == "" {
db.Statement.SQL.Grow(100) db.Statement.SQL.Grow(100)
clauseSelect := clause.Select{Distinct: db.Statement.Distinct} clauseSelect := clause.Select{Distinct: db.Statement.Distinct}
@ -162,6 +161,7 @@ func BuildQuerySQL(db *gorm.DB) {
db.Statement.AddClauseIfNotExists(clauseSelect) db.Statement.AddClauseIfNotExists(clauseSelect)
db.Statement.Build("SELECT", "FROM", "WHERE", "GROUP BY", "ORDER BY", "LIMIT", "FOR") db.Statement.Build("SELECT", "FROM", "WHERE", "GROUP BY", "ORDER BY", "LIMIT", "FOR")
}
} }
func Preload(db *gorm.DB) { func Preload(db *gorm.DB) {

View File

@ -6,9 +6,7 @@ import (
func RowQuery(db *gorm.DB) { func RowQuery(db *gorm.DB) {
if db.Error == nil { if db.Error == nil {
if db.Statement.SQL.String() == "" {
BuildQuerySQL(db) BuildQuerySQL(db)
}
if !db.DryRun { if !db.DryRun {
if isRows, ok := db.InstanceGet("rows"); ok && isRows.(bool) { if isRows, ok := db.InstanceGet("rows"); ok && isRows.(bool) {

View File

@ -14,10 +14,16 @@ func TestSoftDelete(t *testing.T) {
DB.Save(&user) DB.Save(&user)
var count int64 var count int64
var age uint
if DB.Model(&User{}).Where("name = ?", user.Name).Count(&count).Error != nil || count != 1 { if DB.Model(&User{}).Where("name = ?", user.Name).Count(&count).Error != nil || count != 1 {
t.Errorf("Count soft deleted record, expects: %v, got: %v", 1, count) t.Errorf("Count soft deleted record, expects: %v, got: %v", 1, count)
} }
if DB.Model(&User{}).Select("age").Where("name = ?", user.Name).Scan(&age).Error != nil || age != user.Age {
t.Errorf("Age soft deleted record, expects: %v, got: %v", 0, age)
}
if err := DB.Delete(&user).Error; err != nil { if err := DB.Delete(&user).Error; err != nil {
t.Fatalf("No error should happen when soft delete user, but got %v", err) t.Fatalf("No error should happen when soft delete user, but got %v", err)
} }
@ -26,18 +32,30 @@ func TestSoftDelete(t *testing.T) {
t.Errorf("Can't find a soft deleted record") t.Errorf("Can't find a soft deleted record")
} }
count = 0
if DB.Model(&User{}).Where("name = ?", user.Name).Count(&count).Error != nil || count != 0 { if DB.Model(&User{}).Where("name = ?", user.Name).Count(&count).Error != nil || count != 0 {
t.Errorf("Count soft deleted record, expects: %v, got: %v", 0, count) t.Errorf("Count soft deleted record, expects: %v, got: %v", 0, count)
} }
age = 0
if DB.Model(&User{}).Select("age").Where("name = ?", user.Name).Scan(&age).Error != nil || age != 0 {
t.Errorf("Age soft deleted record, expects: %v, got: %v", 0, age)
}
if err := DB.Unscoped().First(&User{}, "name = ?", user.Name).Error; err != nil { if err := DB.Unscoped().First(&User{}, "name = ?", user.Name).Error; err != nil {
t.Errorf("Should find soft deleted record with Unscoped, but got err %s", err) t.Errorf("Should find soft deleted record with Unscoped, but got err %s", err)
} }
count = 0
if DB.Unscoped().Model(&User{}).Where("name = ?", user.Name).Count(&count).Error != nil || count != 1 { if DB.Unscoped().Model(&User{}).Where("name = ?", user.Name).Count(&count).Error != nil || count != 1 {
t.Errorf("Count soft deleted record, expects: %v, count: %v", 1, count) t.Errorf("Count soft deleted record, expects: %v, count: %v", 1, count)
} }
age = 0
if DB.Unscoped().Model(&User{}).Select("age").Where("name = ?", user.Name).Scan(&age).Error != nil || age != user.Age {
t.Errorf("Age soft deleted record, expects: %v, got: %v", 0, age)
}
DB.Unscoped().Delete(&user) DB.Unscoped().Delete(&user)
if err := DB.Unscoped().First(&User{}, "name = ?", user.Name).Error; !errors.Is(err, gorm.ErrRecordNotFound) { if err := DB.Unscoped().First(&User{}, "name = ?", user.Name).Error; !errors.Is(err, gorm.ErrRecordNotFound) {
t.Errorf("Can't find permanently deleted record") t.Errorf("Can't find permanently deleted record")