Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 7e30272020 | |||
| a712ccc38f | |||
| eafe84ef31 | |||
| 338294f957 |
+1
-1
@@ -16,7 +16,7 @@
|
|||||||
- `Query`, `MustQuery`, and `UpdateOne` helpers (+ Context variants).
|
- `Query`, `MustQuery`, and `UpdateOne` helpers (+ Context variants).
|
||||||
- `WithTxValue` for transactional functions that return a value.
|
- `WithTxValue` for transactional functions that return a value.
|
||||||
- `QueryCount`, `BuildQueryCountFn`, and `CountResult` for pagination counts.
|
- `QueryCount`, `BuildQueryCountFn`, and `CountResult` for pagination counts.
|
||||||
- `BinaryKSUID.BinExpr`, `ExprStringKSUIDs`, and flexible `Parse*Any` KSUID parsers.
|
- `StringKSUIDExpr`, `BinaryKSUIDExpr`, `ExprPtrs`, and flexible `Parse*Any` KSUID parsers.
|
||||||
- `MarshalUint64` and `UnmarshalUint64` for JS-safe GraphQL uint64 scalars.
|
- `MarshalUint64` and `UnmarshalUint64` for JS-safe GraphQL uint64 scalars.
|
||||||
- Context-aware variants for all query and mutation helpers.
|
- Context-aware variants for all query and mutation helpers.
|
||||||
- `Delete`, `DeleteAffected`, `WithTx`, `ContainsCol`, and `CurrentDialect()`.
|
- `Delete`, `DeleteAffected`, `WithTx`, `ContainsCol`, and `CurrentDialect()`.
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ For Postgres, use `dbx.DialectPostgres` and blank-import `dbxp` instead of `dbxm
|
|||||||
| Query | `Fetch`, `MustFetch`, `FetchOne`, `MustFetchOne`, `Query`, `MustQuery` (+ `*Context` variants) |
|
| Query | `Fetch`, `MustFetch`, `FetchOne`, `MustFetchOne`, `Query`, `MustQuery` (+ `*Context` variants) |
|
||||||
| Mutations | `Insert`, `InsertReturning`, `Update`, `UpdateAffected`, `UpdateOne`, `UpdateReturning`, `Delete`, `DeleteAffected` (+ `*Context` variants) |
|
| Mutations | `Insert`, `InsertReturning`, `Update`, `UpdateAffected`, `UpdateOne`, `UpdateReturning`, `Delete`, `DeleteAffected` (+ `*Context` variants) |
|
||||||
| Transactions | `WithTx`, `WithTxValue` |
|
| Transactions | `WithTx`, `WithTxValue` |
|
||||||
| Columns | `NormalCols`, `ContainsCol`, `ExprValues`, `ExprStringers`, `ExprStringKSUIDs`, `QueryCount`, `BuildQueryCountFn` |
|
| Columns | `NormalCols`, `ContainsCol`, `ExprValues`, `ExprPtrs`, `ExprStringers`, `StringKSUIDExpr`, `BinaryKSUIDExpr`, `QueryCount`, `BuildQueryCountFn` |
|
||||||
| Partial update | `ApplyPtr`, `ApplyComplexPtr`, `ApplyInterfacePtr`, `ApplyVal` |
|
| Partial update | `ApplyPtr`, `ApplyComplexPtr`, `ApplyInterfacePtr`, `ApplyVal` |
|
||||||
| Pointers | `Ptr`, `Val`, `NowPtr`, `TrimPtr`, `TrimPtrToNil`, `IsZero` |
|
| Pointers | `Ptr`, `Val`, `NowPtr`, `TrimPtr`, `TrimPtrToNil`, `IsZero` |
|
||||||
| Types | `StringKSUID`, `BinaryKSUID`, `JSONB` |
|
| Types | `StringKSUID`, `BinaryKSUID`, `JSONB` |
|
||||||
|
|||||||
@@ -16,7 +16,8 @@
|
|||||||
// # Jet column utilities
|
// # Jet column utilities
|
||||||
//
|
//
|
||||||
// Dialect-neutral type aliases ([Column], [ColumnList]) and helpers for column
|
// Dialect-neutral type aliases ([Column], [ColumnList]) and helpers for column
|
||||||
// lists ([NormalCols], [ContainsCol]) and expression building ([ExprValues]).
|
// lists ([NormalCols], [ContainsCol]) and expression building ([ExprValues],
|
||||||
|
// [ExprPtrs], [StringKSUIDExpr], [BinaryKSUIDExpr]).
|
||||||
// [QueryCount] and [BuildQueryCountFn] support pagination total counts.
|
// [QueryCount] and [BuildQueryCountFn] support pagination total counts.
|
||||||
//
|
//
|
||||||
// Partial-update helpers ([ApplyPtr], [ApplyVal]) track changed fields for
|
// Partial-update helpers ([ApplyPtr], [ApplyVal]) track changed fields for
|
||||||
@@ -26,7 +27,8 @@
|
|||||||
//
|
//
|
||||||
// [StringKSUID] and [BinaryKSUID] wrap segmentio/ksuid with storage-specific
|
// [StringKSUID] and [BinaryKSUID] wrap segmentio/ksuid with storage-specific
|
||||||
// SQL encoding. Both implement [ApplyInterface] via Equal and IsZero for use
|
// SQL encoding. Both implement [ApplyInterface] via Equal and IsZero for use
|
||||||
// with [ApplyInterfacePtr]. Both share identical GraphQL string scalar transit.
|
// with [ApplyInterfacePtr]. Expr returns a Jet expression via [StringKSUIDExpr]
|
||||||
|
// or [BinaryKSUIDExpr]. Both share identical GraphQL string scalar transit.
|
||||||
// Choose StringKSUID for text columns (VARCHAR, TEXT); choose BinaryKSUID for
|
// Choose StringKSUID for text columns (VARCHAR, TEXT); choose BinaryKSUID for
|
||||||
// binary columns (BINARY(20), BYTEA). [ParseStringKSUIDAny] and
|
// binary columns (BINARY(20), BYTEA). [ParseStringKSUIDAny] and
|
||||||
// [ParseBinaryKSUIDAny] accept flexible input for API boundaries.
|
// [ParseBinaryKSUIDAny] accept flexible input for API boundaries.
|
||||||
|
|||||||
+26
-6
@@ -16,6 +16,19 @@ func ExprValues[T any](values []T, f func(T) Expression) []Expression {
|
|||||||
return expressions
|
return expressions
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ExprPtrs converts a list of pointers to Expression values, skipping nil
|
||||||
|
// entries. Function f receives the dereferenced value.
|
||||||
|
func ExprPtrs[T any](values []*T, f func(T) Expression) []Expression {
|
||||||
|
expressions := make([]Expression, 0, len(values))
|
||||||
|
for _, v := range values {
|
||||||
|
if v == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
expressions = append(expressions, f(*v))
|
||||||
|
}
|
||||||
|
return expressions
|
||||||
|
}
|
||||||
|
|
||||||
// ExprStringers converts a list of fmt.Stringers to a list of Expression values.
|
// ExprStringers converts a list of fmt.Stringers to a list of Expression values.
|
||||||
func ExprStringers(values []fmt.Stringer) []Expression {
|
func ExprStringers(values []fmt.Stringer) []Expression {
|
||||||
expressions := make([]Expression, len(values))
|
expressions := make([]Expression, len(values))
|
||||||
@@ -25,11 +38,18 @@ func ExprStringers(values []fmt.Stringer) []Expression {
|
|||||||
return expressions
|
return expressions
|
||||||
}
|
}
|
||||||
|
|
||||||
// ExprStringKSUIDs converts StringKSUID pointers to Jet string expressions.
|
// StringKSUIDExpr returns a Jet expression for a string-encoded KSUID column.
|
||||||
func ExprStringKSUIDs(ids []*StringKSUID) []Expression {
|
func StringKSUIDExpr(id StringKSUID) Expression {
|
||||||
expressions := make([]Expression, len(ids))
|
if id.IsNil() {
|
||||||
for i, id := range ids {
|
return mysql.StringExp(mysql.NULL)
|
||||||
expressions[i] = mysql.String(id.String())
|
|
||||||
}
|
}
|
||||||
return expressions
|
return mysql.String(id.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
// BinaryKSUIDExpr returns a Jet expression for a binary-encoded KSUID column.
|
||||||
|
func BinaryKSUIDExpr(id BinaryKSUID) Expression {
|
||||||
|
if id.IsNil() {
|
||||||
|
return mysql.StringExp(mysql.NULL)
|
||||||
|
}
|
||||||
|
return mysql.String(string(id.Bytes()))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,60 @@
|
|||||||
|
package dbx
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestStringKSUIDExpr(t *testing.T) {
|
||||||
|
id := NewStringKSUID()
|
||||||
|
expr := StringKSUIDExpr(id)
|
||||||
|
require.NotNil(t, expr)
|
||||||
|
assert.Equal(t, expr, id.Expr())
|
||||||
|
|
||||||
|
nilExpr := StringKSUIDExpr(NilStringKSUID)
|
||||||
|
require.NotNil(t, nilExpr)
|
||||||
|
assert.Equal(t, nilExpr, NilStringKSUID.Expr())
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBinaryKSUIDExpr(t *testing.T) {
|
||||||
|
id := NewBinaryKSUID()
|
||||||
|
expr := BinaryKSUIDExpr(id)
|
||||||
|
require.NotNil(t, expr)
|
||||||
|
assert.Equal(t, expr, id.Expr())
|
||||||
|
|
||||||
|
nilExpr := BinaryKSUIDExpr(NilBinaryKSUID)
|
||||||
|
require.NotNil(t, nilExpr)
|
||||||
|
assert.Equal(t, nilExpr, NilBinaryKSUID.Expr())
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestExprPtrs_StringKSUID(t *testing.T) {
|
||||||
|
a := NewStringKSUID()
|
||||||
|
b := NewStringKSUID()
|
||||||
|
exprs := ExprPtrs([]*StringKSUID{&a, nil, &b}, StringKSUIDExpr)
|
||||||
|
require.Len(t, exprs, 2)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestExprPtrs_BinaryKSUID(t *testing.T) {
|
||||||
|
a := NewBinaryKSUID()
|
||||||
|
exprs := ExprPtrs([]*BinaryKSUID{&a, nil}, BinaryKSUIDExpr)
|
||||||
|
require.Len(t, exprs, 1)
|
||||||
|
assert.NotNil(t, exprs[0])
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestExprValues_StringKSUID(t *testing.T) {
|
||||||
|
a := NewStringKSUID()
|
||||||
|
b := NewStringKSUID()
|
||||||
|
exprs := ExprValues([]*StringKSUID{&a, &b}, func(id *StringKSUID) Expression {
|
||||||
|
return id.Expr()
|
||||||
|
})
|
||||||
|
require.Len(t, exprs, 2)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestExprValues_BinaryKSUID(t *testing.T) {
|
||||||
|
a := NewBinaryKSUID()
|
||||||
|
exprs := ExprValues([]BinaryKSUID{a}, BinaryKSUIDExpr)
|
||||||
|
require.Len(t, exprs, 1)
|
||||||
|
assert.NotNil(t, exprs[0])
|
||||||
|
}
|
||||||
+5
-9
@@ -5,7 +5,6 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
"github.com/go-jet/jet/v2/mysql"
|
|
||||||
"github.com/segmentio/ksuid"
|
"github.com/segmentio/ksuid"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -44,19 +43,16 @@ func ParseBinaryKSUID(b []byte) (BinaryKSUID, error) {
|
|||||||
return BinaryKSUID{KSUID: id}, nil
|
return BinaryKSUID{KSUID: id}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// BinExpr returns a Jet string expression for binary-encoded IN clauses.
|
|
||||||
func (b BinaryKSUID) BinExpr() mysql.StringExpression {
|
|
||||||
if b.IsNil() {
|
|
||||||
return mysql.StringExp(mysql.NULL)
|
|
||||||
}
|
|
||||||
return mysql.String(string(b.Bytes()))
|
|
||||||
}
|
|
||||||
|
|
||||||
// AsStringKSUID returns a StringKSUID view of the same identifier.
|
// AsStringKSUID returns a StringKSUID view of the same identifier.
|
||||||
func (b BinaryKSUID) AsStringKSUID() StringKSUID {
|
func (b BinaryKSUID) AsStringKSUID() StringKSUID {
|
||||||
return StringKSUID{KSUID: b.KSUID}
|
return StringKSUID{KSUID: b.KSUID}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Expr returns a Jet expression for this BinaryKSUID. See [BinaryKSUIDExpr].
|
||||||
|
func (b BinaryKSUID) Expr() Expression {
|
||||||
|
return BinaryKSUIDExpr(b)
|
||||||
|
}
|
||||||
|
|
||||||
// Scan implements sql.Scanner for binary-backed KSUID columns.
|
// Scan implements sql.Scanner for binary-backed KSUID columns.
|
||||||
func (b *BinaryKSUID) Scan(src any) error {
|
func (b *BinaryKSUID) Scan(src any) error {
|
||||||
switch v := src.(type) {
|
switch v := src.(type) {
|
||||||
|
|||||||
@@ -52,19 +52,3 @@ func TestParseStringKSUIDAny_InvalidType(t *testing.T) {
|
|||||||
_, err := ParseStringKSUIDAny(123)
|
_, err := ParseStringKSUIDAny(123)
|
||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestBinaryKSUID_BinExpr(t *testing.T) {
|
|
||||||
id := NewBinaryKSUID()
|
|
||||||
expr := id.BinExpr()
|
|
||||||
require.NotNil(t, expr)
|
|
||||||
|
|
||||||
nilExpr := NilBinaryKSUID.BinExpr()
|
|
||||||
require.NotNil(t, nilExpr)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestExprStringKSUIDs(t *testing.T) {
|
|
||||||
a := NewStringKSUID()
|
|
||||||
b := NewStringKSUID()
|
|
||||||
exprs := ExprStringKSUIDs([]*StringKSUID{&a, &b})
|
|
||||||
require.Len(t, exprs, 2)
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -48,6 +48,11 @@ func (s StringKSUID) AsBinaryKSUID() BinaryKSUID {
|
|||||||
return BinaryKSUID{KSUID: s.KSUID}
|
return BinaryKSUID{KSUID: s.KSUID}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Expr returns a Jet expression for this StringKSUID. See [StringKSUIDExpr].
|
||||||
|
func (s StringKSUID) Expr() Expression {
|
||||||
|
return StringKSUIDExpr(s)
|
||||||
|
}
|
||||||
|
|
||||||
// Scan implements sql.Scanner for string-backed KSUID columns.
|
// Scan implements sql.Scanner for string-backed KSUID columns.
|
||||||
func (s *StringKSUID) Scan(src any) error {
|
func (s *StringKSUID) Scan(src any) error {
|
||||||
switch v := src.(type) {
|
switch v := src.(type) {
|
||||||
|
|||||||
Reference in New Issue
Block a user