Skip to content

Commit 9f94473

Browse files
committed
sqlx: move ConstraintFailed and TypedError to Dialect
1 parent 744e4b2 commit 9f94473

File tree

9 files changed

+44
-37
lines changed

9 files changed

+44
-37
lines changed

internal/rhash/tx.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -428,7 +428,7 @@ func (tx *Tx) set(key string, field string, value any) error {
428428
var keyID int
429429
err = tx.tx.QueryRow(tx.sql.set1, args...).Scan(&keyID)
430430
if err != nil {
431-
return sqlx.TypedError(err)
431+
return tx.dialect.TypedError(err)
432432
}
433433
_, err = tx.tx.Exec(tx.sql.set2, keyID, field, valueb)
434434
return err

internal/rlist/tx.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -321,7 +321,7 @@ func (tx *Tx) insert(key string, pivot, elem any, query string) (int, error) {
321321
args = []any{keyID, pivotb, keyID, keyID, elemb, keyID}
322322
_, err = tx.tx.Exec(query, args...)
323323
if err != nil {
324-
if sqlx.ConstraintFailed(err, "not null", "rlist", "pos") {
324+
if tx.dialect.ConstraintFailed(err, "not null", "rlist", "pos") {
325325
return -1, core.ErrNotFound
326326
}
327327
return 0, err
@@ -356,7 +356,7 @@ func (tx *Tx) push(key string, elem any, query string) (int, error) {
356356
var keyID, n int
357357
err = tx.tx.QueryRow(tx.sql.push, args...).Scan(&keyID, &n)
358358
if err != nil {
359-
return 0, sqlx.TypedError(err)
359+
return 0, tx.dialect.TypedError(err)
360360
}
361361

362362
// Insert the element.

internal/rset/tx.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ func (tx *Tx) Add(key string, elems ...any) (int, error) {
6666
var keyID int
6767
err = tx.tx.QueryRow(tx.sql.add1, key, time.Now().UnixMilli()).Scan(&keyID)
6868
if err != nil {
69-
return 0, sqlx.TypedError(err)
69+
return 0, tx.dialect.TypedError(err)
7070
}
7171

7272
// Add the elements.
@@ -448,7 +448,7 @@ func (tx *Tx) createKey(key string, now int64) (int, error) {
448448
var keyID int
449449
err := tx.tx.QueryRow(tx.sql.add1, key, now).Scan(&keyID)
450450
if err != nil {
451-
return 0, sqlx.TypedError(err)
451+
return 0, tx.dialect.TypedError(err)
452452
}
453453
return keyID, nil
454454
}

internal/rstring/tx.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ func (tx *Tx) set(key string, value any, at time.Time) error {
205205
args := []any{key, etime, time.Now().UnixMilli()}
206206
_, err = tx.tx.Exec(tx.sql.set1, args...)
207207
if err != nil {
208-
return sqlx.TypedError(err)
208+
return tx.dialect.TypedError(err)
209209
}
210210

211211
args = []any{key, valueb}
@@ -224,7 +224,7 @@ func (tx *Tx) update(key string, value any) error {
224224

225225
_, err = tx.tx.Exec(tx.sql.update1, key, time.Now().UnixMilli())
226226
if err != nil {
227-
return sqlx.TypedError(err)
227+
return tx.dialect.TypedError(err)
228228
}
229229
_, err = tx.tx.Exec(tx.sql.update2, key, valueb)
230230
return err

internal/rzset/inter.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ func (c InterCmd) store(tx *Tx) (int, error) {
137137
var destID int
138138
err = tx.tx.QueryRow(tx.sql.add1, c.dest, now).Scan(&destID)
139139
if err != nil {
140-
return 0, sqlx.TypedError(err)
140+
return 0, tx.dialect.TypedError(err)
141141
}
142142

143143
// Intersect the source sets and store the result.

internal/rzset/tx.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,7 @@ func (tx *Tx) Incr(key string, elem any, delta float64) (float64, error) {
202202
var keyID int
203203
err = tx.tx.QueryRow(tx.sql.add1, args...).Scan(&keyID)
204204
if err != nil {
205-
return 0, sqlx.TypedError(err)
205+
return 0, tx.dialect.TypedError(err)
206206
}
207207

208208
var score float64
@@ -331,7 +331,7 @@ func (tx *Tx) add(key string, elem any, score float64) error {
331331
var keyID int
332332
err = tx.tx.QueryRow(tx.sql.add1, args...).Scan(&keyID)
333333
if err != nil {
334-
return sqlx.TypedError(err)
334+
return tx.dialect.TypedError(err)
335335
}
336336
_, err = tx.tx.Exec(tx.sql.add2, keyID, elemb, score)
337337
return err

internal/rzset/union.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ func (c UnionCmd) store(tx *Tx) (int, error) {
136136
var destID int
137137
err = tx.tx.QueryRow(tx.sql.add1, c.dest, now).Scan(&destID)
138138
if err != nil {
139-
return 0, sqlx.TypedError(err)
139+
return 0, tx.dialect.TypedError(err)
140140
}
141141

142142
// Union the source sets and store the result.

internal/sqlx/dialect.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import (
44
"errors"
55
"strconv"
66
"strings"
7+
8+
"github.com/nalgeon/redka/internal/core"
79
)
810

911
// SQL dialect.
@@ -17,6 +19,24 @@ const (
1719

1820
var ErrDialect = errors.New("unknown SQL dialect")
1921

22+
// ConstraintFailed checks if the error is due to
23+
// a constraint violation on a column.
24+
// Error examples:
25+
// - sqlite3.Error (NOT NULL constraint failed: rkey.type)
26+
// - *pq.Error (pq: null value in column "type" of relation "rkey" violates not-null constraint)
27+
func (d Dialect) ConstraintFailed(err error, constraint, table string, column string) bool {
28+
var message string
29+
switch d {
30+
case DialectPostgres:
31+
message = `"` + column + `" of relation "` + table +
32+
`" violates ` + strings.ReplaceAll(constraint, " ", "-") + ` constraint`
33+
case DialectSqlite:
34+
message = constraint + " constraint failed: " + table + "." + column
35+
}
36+
errStr := strings.ToLower(err.Error())
37+
return strings.Contains(errStr, message)
38+
}
39+
2040
// Enumerate replaces ? placeholders with $1, $2, ... $n.
2141
func (d Dialect) Enumerate(query string) string {
2242
if d == DialectSqlite {
@@ -70,3 +90,16 @@ func (d Dialect) LimitAll() string {
7090
}
7191
return "limit all"
7292
}
93+
94+
// Returns ErrKeyType if the error is due to a not-null
95+
// constraint violation on rkey.type.
96+
// Otherwise, returns the original error.
97+
func (d Dialect) TypedError(err error) error {
98+
if err == nil {
99+
return nil
100+
}
101+
if d.ConstraintFailed(err, "not null", "rkey", "type") {
102+
return core.ErrKeyType
103+
}
104+
return err
105+
}

internal/sqlx/sql.go

Lines changed: 0 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@ package sqlx
55
import (
66
"database/sql"
77
"strings"
8-
9-
"github.com/nalgeon/redka/internal/core"
108
)
119

1210
// Sorting direction.
@@ -81,27 +79,3 @@ func Select[T any](db Tx, query string, args []any,
8179

8280
return vals, err
8381
}
84-
85-
// Returns typed errors for some specific cases.
86-
func TypedError(err error) error {
87-
if err == nil {
88-
return nil
89-
}
90-
if ConstraintFailed(err, "not null", "rkey", "type") {
91-
return core.ErrKeyType
92-
}
93-
return err
94-
}
95-
96-
// ConstraintFailed checks if the error is due to
97-
// a constraint violation on a column.
98-
// Error examples:
99-
// - sqlite3.Error (NOT NULL constraint failed: rkey.type)
100-
// - *pq.Error (pq: null value in column "type" of relation "rkey" violates not-null constraint)
101-
func ConstraintFailed(err error, constraint, table string, column string) bool {
102-
sqliteMsg := constraint + " constraint failed: " + table + "." + column
103-
postgresMsg := `"` + column + `" of relation "` + table +
104-
`" violates ` + strings.ReplaceAll(constraint, " ", "-") + ` constraint`
105-
errStr := strings.ToLower(err.Error())
106-
return strings.Contains(errStr, sqliteMsg) || strings.Contains(errStr, postgresMsg)
107-
}

0 commit comments

Comments
 (0)