feat: support reset result as nil when record not found

This commit is contained in:
mr-chenguang lcgash 2024-04-11 09:27:40 +00:00
parent 1e13fd7543
commit ad81206cc2
3 changed files with 20 additions and 0 deletions

View File

@ -50,6 +50,8 @@ type Config struct {
CreateBatchSize int
// TranslateError enabling error translation
TranslateError bool
// NotFoundAsError set result is nil when no record found and result is ptr
NotFoundAsNilWhenPtr bool
// ClauseBuilders clause builder
ClauseBuilders map[string]clause.ClauseBuilder

View File

@ -342,5 +342,9 @@ func Scan(rows Rows, db *DB, mode ScanMode) {
if db.RowsAffected == 0 && db.Statement.RaiseErrorOnNotFound && db.Error == nil {
db.AddError(ErrRecordNotFound)
if db.NotFoundAsNilWhenPtr && db.Statement.Dest != nil && reflect.ValueOf(db.Statement.Dest).Kind() == reflect.Ptr {
// reset dest to nil
reflect.ValueOf(db.Statement.Dest).Elem().Set(reflect.Zero(reflect.ValueOf(db.Statement.Dest).Elem().Type()))
}
}
}

View File

@ -206,6 +206,20 @@ func TestFind(t *testing.T) {
}
})
t.Run("NotFoundAsNil", func(t *testing.T) {
var first *User
if err := DB.Where("name = ?", "find-not-found").First(&first).Error; err != nil {
AssertEqual(t, err, gorm.ErrRecordNotFound)
AssertEqual(t, first == nil, false)
}
DB.Config.NotFoundAsNilWhenPtr = true
if err := DB.Where("name = ?", "find-not-found").First(&first).Error; err != nil {
AssertEqual(t, err, gorm.ErrRecordNotFound)
AssertEqual(t, first, nil)
}
})
var models []User
if err := DB.Where("name in (?)", []string{"find"}).Find(&models).Error; err != nil || len(models) != 3 {
t.Errorf("errors happened when query find with in clause: %v, length: %v", err, len(models))