feat: SelectDataset 新增 Exists/ExistsContext

生成 SELECT 1 FROM ... LIMIT 1 判断是否存在符合条件的行,不用调用方自己拼
COUNT(*) 或者查完整行再判断长度。
This commit is contained in:
2026-08-20 17:09:48 +08:00
parent 6ed2803158
commit 9c6bb5a835
2 changed files with 63 additions and 0 deletions
+11
View File
@@ -701,6 +701,17 @@ func (sd *SelectDataset) ScanValContext(ctx context.Context, i interface{}) (boo
} }
// Generates the SELECT COUNT(*) sql for this dataset and uses Exec#ScanVal to scan the result into an int64. // Generates the SELECT COUNT(*) sql for this dataset and uses Exec#ScanVal to scan the result into an int64.
// Generates SELECT 1 FROM ... LIMIT 1 and returns true if any row exists.
func (sd *SelectDataset) Exists() (bool, error) {
return sd.ExistsContext(context.Background())
}
// Generates SELECT 1 FROM ... LIMIT 1 and returns true if any row exists.
func (sd *SelectDataset) ExistsContext(ctx context.Context) (bool, error) {
var v int64
return sd.Select(L("1")).Limit(1).ScanValContext(ctx, &v)
}
func (sd *SelectDataset) Count() (int64, error) { func (sd *SelectDataset) Count() (int64, error) {
return sd.CountContext(context.Background()) return sd.CountContext(context.Background())
} }
+52
View File
@@ -1618,6 +1618,58 @@ func (sds *selectDatasetSuite) TestSetError() {
sds.Equal(err1, err) sds.Equal(err1, err)
} }
func (sds *selectDatasetSuite) TestExists() {
mDB, sqlMock, err := sqlmock.New()
sds.NoError(err)
sqlMock.ExpectQuery(`SELECT 1 FROM "items" LIMIT 1`).
WithArgs().
WillReturnRows(sqlmock.NewRows([]string{"1"}).FromCSVString("1"))
db := dbv2.New("mock", mDB)
exists, err := db.From("items").Exists()
sds.NoError(err)
sds.True(exists)
}
func (sds *selectDatasetSuite) TestExists_NotFound() {
mDB, sqlMock, err := sqlmock.New()
sds.NoError(err)
sqlMock.ExpectQuery(`SELECT 1 FROM "items" LIMIT 1`).
WithArgs().
WillReturnRows(sqlmock.NewRows([]string{"1"}))
db := dbv2.New("mock", mDB)
exists, err := db.From("items").Exists()
sds.NoError(err)
sds.False(exists)
}
func (sds *selectDatasetSuite) TestExists_WithWhere() {
mDB, sqlMock, err := sqlmock.New()
sds.NoError(err)
sqlMock.ExpectQuery(`SELECT 1 FROM "items" WHERE \("name" = 'Bob'\) LIMIT 1`).
WithArgs().
WillReturnRows(sqlmock.NewRows([]string{"1"}).FromCSVString("1"))
db := dbv2.New("mock", mDB)
exists, err := db.From("items").Where(dbv2.C("name").Eq("Bob")).Exists()
sds.NoError(err)
sds.True(exists)
}
func (sds *selectDatasetSuite) TestExists_WithPreparedStatement() {
mDB, sqlMock, err := sqlmock.New()
sds.NoError(err)
sqlMock.ExpectQuery(`SELECT 1 FROM "items" WHERE \("name" = \?\) LIMIT \?`).
WithArgs("Bob", 1).
WillReturnRows(sqlmock.NewRows([]string{"1"}).FromCSVString("1"))
db := dbv2.New("mock", mDB)
exists, err := db.From("items").Prepared(true).Where(dbv2.C("name").Eq("Bob")).Exists()
sds.NoError(err)
sds.True(exists)
}
func TestSelectDataset(t *testing.T) { func TestSelectDataset(t *testing.T) {
suite.Run(t, new(selectDatasetSuite)) suite.Run(t, new(selectDatasetSuite))
} }