diff --git a/internal/dbtest/soft_delete_test.go b/internal/dbtest/soft_delete_test.go index c44ee2318..b8714ddfc 100644 --- a/internal/dbtest/soft_delete_test.go +++ b/internal/dbtest/soft_delete_test.go @@ -111,15 +111,48 @@ func testSoftDeleteForce(t *testing.T, db *bun.DB) { err := db.ResetModel(ctx, (*Video)(nil)) require.NoError(t, err) - video1 := &Video{ - ID: 1, + videos := []Video{ + {Name: "video1"}, + {Name: "video2"}, + {Name: "video3"}, } - _, err = db.NewInsert().Model(video1).Exec(ctx) + + _, err = db.NewInsert().Model(&videos).Exec(ctx) require.NoError(t, err) - _, err = db.NewDelete().Model(video1).WherePK().ForceDelete().Exec(ctx) + // Force delete video1. + _, err = db.NewDelete().Model((*Video)(nil)).Where("name = ?", "video1").ForceDelete().Exec(ctx) + require.NoError(t, err) + + // Soft delete video2. + _, err = db.NewDelete().Model((*Video)(nil)).Where("name = ?", "video2").Exec(ctx) + require.NoError(t, err) + + // Check one visible video. + var res []Video + err = db.NewSelect().Model((*Video)(nil)).Column("name").Scan(ctx, &res) + require.NoError(t, err) + require.Equal(t, []Video{{Name: "video3"}}, res) + + // Check one soft deleted video. + err = db.NewSelect().Model((*Video)(nil)).Column("name").WhereDeleted().Scan(ctx, &res) + require.NoError(t, err) + require.Equal(t, []Video{{Name: "video2"}}, res) + + // Force delete only soft deleted videos. + _, err = db.NewDelete().Model((*Video)(nil)).WhereDeleted().ForceDelete().Exec(ctx) + require.NoError(t, err) + + // Check one remaining video. + err = db.NewSelect().Model((*Video)(nil)).Column("name").WhereAllWithDeleted().Scan(ctx, &res) + require.NoError(t, err) + require.Equal(t, []Video{{Name: "video3"}}, res) + + // Force delete all videos. + _, err = db.NewDelete().Model((*Video)(nil)).Where("1 = 1").ForceDelete().Exec(ctx) require.NoError(t, err) + // Check no remaining videos. count, err := db.NewSelect().Model((*Video)(nil)).WhereAllWithDeleted().Count(ctx) require.NoError(t, err) require.Equal(t, 0, count) diff --git a/query_base.go b/query_base.go index 421fc399f..9df70d1f4 100644 --- a/query_base.go +++ b/query_base.go @@ -238,7 +238,7 @@ func (q *baseQuery) isSoftDelete() bool { if q.table != nil { return q.table.SoftDeleteField != nil && !q.flags.Has(allWithDeletedFlag) && - !q.flags.Has(forceDeleteFlag) + (!q.flags.Has(forceDeleteFlag) || q.flags.Has(deletedFlag)) } return false } @@ -773,7 +773,7 @@ func (q *whereBaseQuery) addWhereCols(cols []string) { func (q *whereBaseQuery) mustAppendWhere( fmter schema.Formatter, b []byte, withAlias bool, ) ([]byte, error) { - if len(q.where) == 0 && q.whereFields == nil { + if len(q.where) == 0 && q.whereFields == nil && !q.flags.Has(deletedFlag) { err := errors.New("bun: Update and Delete queries require at least one Where") return nil, err } diff --git a/query_delete.go b/query_delete.go index 288b33859..1572ac328 100644 --- a/query_delete.go +++ b/query_delete.go @@ -163,7 +163,6 @@ func (q *DeleteQuery) AppendQuery(fmter schema.Formatter, b []byte) (_ []byte, e return upd.AppendQuery(fmter, b) } - q = q.WhereDeleted() withAlias := q.db.features.Has(feature.DeleteTableAlias) b, err = q.appendWith(fmter, b)