diff options
| author | Stefan Majewsky <majewsky@gmx.net> | 2026-09-17 15:50:45 +0200 |
|---|---|---|
| committer | Stefan Majewsky <majewsky@gmx.net> | 2026-09-17 15:50:45 +0200 |
| commit | fe37a82d0495a8b59b80677dd42d0d94ffafdfb4 (patch) | |
| tree | 58339c88054e9662720e76c2e6c8dd0a34f45ab9 | |
| parent | 635c0f118a490112ca2ee797c92f1dd14e6eeed7 (diff) | |
| download | go-gg-fe37a82d0495a8b59b80677dd42d0d94ffafdfb4.tar.gz | |
gsql: add NoneIfNoRows
| -rw-r--r-- | CHANGELOG.md | 7 | ||||
| -rw-r--r-- | go.mod | 2 | ||||
| -rw-r--r-- | gsql/gsql.go | 18 | ||||
| -rw-r--r-- | gsql/gsql_test.go | 29 |
4 files changed, 55 insertions, 1 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index f259e37..a37cb78 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,13 @@ SPDX-FileCopyrightText: 2026 Stefan Majewsky <majewsky@gmx.net> SPDX-License-Identifier: Apache-2.0 --> +# v1.16.0 (TBD) + +Changes: + +- gsql: Add NoneIfNoRows. + This replaces "OrNone" variants of methods in Oblast, e.g. SelectOne() and then also SelectOneOrNone(). + # v1.15.0 (2026-09-08) Changes: @@ -1,4 +1,4 @@ module go.xyrillian.de/gg -// TODO for 1.27: use sql.ConvertAssign for gg/option; deprecate gg/options and offer methods on Option instead; make jsonmatch.Pointer into an alias of jsontext.Pointer +// TODO for 1.27: use sql.ConvertAssign for gg/option; deprecate gg/options and offer methods on Option instead; make jsonmatch.Pointer into an alias of jsontext.Pointer; replace json.{Unm,M}arshaler with json/v2.{Unm,M}arshaler{From,To} go 1.26 diff --git a/gsql/gsql.go b/gsql/gsql.go index 7df830c..e7e2aa3 100644 --- a/gsql/gsql.go +++ b/gsql/gsql.go @@ -14,6 +14,9 @@ package gsql import ( "context" "database/sql" + "errors" + + . "go.xyrillian.de/gg/option" ) // ConnectionHandle extends [Handle] with methods that make sense for handles referring to entire connections or connection pools, but not e.g. to transactions. @@ -76,3 +79,18 @@ type Rows interface { Next() bool Scan(slots ...any) error } + +// NoneIfNoRows wraps any call returning a record from a DB that may return [sql.ErrNoRows], +// and converts that error into a [None] in the value position instead. +// +// [None]: https://pkg.go.dev/go.xyrillian.de/gg/option#None +func NoneIfNoRows[T any](value T, err error) (Option[T], error) { + switch { + case err == nil: + return Some(value), nil + case errors.Is(err, sql.ErrNoRows): + return None[T](), nil + default: + return None[T](), err + } +} diff --git a/gsql/gsql_test.go b/gsql/gsql_test.go new file mode 100644 index 0000000..acf0bbf --- /dev/null +++ b/gsql/gsql_test.go @@ -0,0 +1,29 @@ +// SPDX-FileCopyrightText: 2026 Stefan Majewsky <majewsky@gmx.net> +// SPDX-License-Identifier: Apache-2.0 + +package gsql_test + +import ( + "database/sql" + "errors" + "testing" + + "go.xyrillian.de/gg/assert" + "go.xyrillian.de/gg/gsql" + . "go.xyrillian.de/gg/option" +) + +func TestNoneIfNoRows(t *testing.T) { + x, err := gsql.NoneIfNoRows(42, nil) + if assert.ErrEqual(t, err, nil) { + assert.Equal(t, x, Some(42)) + } + + x, err = gsql.NoneIfNoRows(0, sql.ErrNoRows) + if assert.ErrEqual(t, err, nil) { + assert.Equal(t, x, None[int]()) + } + + _, err = gsql.NoneIfNoRows(0, errors.New("kaboom")) + assert.ErrEqual(t, err, "kaboom") +} |
