Skip to content

Commit 94bc818

Browse files
authored
Implement SingleOrNil (#21)
1 parent 8bf23e8 commit 94bc818

File tree

2 files changed

+30
-0
lines changed

2 files changed

+30
-0
lines changed

querysql/querysql.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ package querysql
66
import (
77
"context"
88
"database/sql"
9+
"errors"
910
"fmt"
1011
"io"
1112
"strings"
@@ -312,6 +313,14 @@ func MustSingle[T any](ctx context.Context, querier CtxQuerier, qry string, args
312313
return must(Single[T](ctx, querier, qry, args...))
313314
}
314315

316+
func SingleOrNil[T any](ctx context.Context, querier CtxQuerier, qry string, args ...any) (*T, error) {
317+
v, err := Single[T](ctx, querier, qry, args...)
318+
if err != nil && errors.Is(err, sql.ErrNoRows) {
319+
return nil, nil
320+
}
321+
return &v, err
322+
}
323+
315324
func Slice[T any](ctx context.Context, querier CtxQuerier, qry string, args ...any) ([]T, error) {
316325
return NextResult(New(ctx, querier, qry, args...).EnsureDoneAfterNext(), SliceOf[T])
317326
}

querysql/querysql_test.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -730,3 +730,24 @@ func Test_TypeThatImplementsScan(t *testing.T) {
730730
_, err := Single[MyType](ctx, sqldb, qry, "world")
731731
assert.NoError(t, err)
732732
}
733+
734+
func Test_SingleOrNil(t *testing.T) {
735+
// No easy way to do this as a table driven test because
736+
// we are calling funcs (Single and SingleOrNil) with different signatures
737+
ctx := context.Background()
738+
739+
// query returns no result set; gives error when queried with Single
740+
_, err := Single[int](ctx, sqldb, `select 1 where 0 = 1;`, "world")
741+
require.Error(t, err)
742+
require.True(t, errors.Is(err, sql.ErrNoRows))
743+
744+
// query returns no result set; gives no error when queried with SingleOrNil
745+
vptr, err := SingleOrNil[int](ctx, sqldb, `select 1 where 0 = 1;`, "world")
746+
require.NoError(t, err)
747+
require.Nil(t, vptr)
748+
749+
// query returns an error; gives error when queried with SingleOrNil
750+
vptr, err = SingleOrNil[int](ctx, sqldb, `throw 55002, 'Here is an error', 1;`, "world")
751+
require.Error(t, err)
752+
require.False(t, errors.Is(err, sql.ErrNoRows))
753+
}

0 commit comments

Comments
 (0)