feat(ksuid): add Equal and IsZero for ApplyInterfacePtr
StringKSUID and BinaryKSUID now implement ApplyInterface with nil-nil equality semantics, enabling ApplyInterfacePtr in patch logic. Adds nil sentinel vars and tests. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -12,6 +12,7 @@
|
|||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
|
- `StringKSUID.Equal` / `IsZero`, `BinaryKSUID.Equal` / `IsZero`, and nil sentinel vars for [ApplyInterfacePtr].
|
||||||
- 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()`.
|
||||||
- Package documentation (`doc.go`), expanded README, and subpackage docs for `dbxm` / `dbxp`.
|
- Package documentation (`doc.go`), expanded README, and subpackage docs for `dbxm` / `dbxp`.
|
||||||
|
|||||||
@@ -23,9 +23,10 @@
|
|||||||
// # Identifier types
|
// # Identifier types
|
||||||
//
|
//
|
||||||
// [StringKSUID] and [BinaryKSUID] wrap segmentio/ksuid with storage-specific
|
// [StringKSUID] and [BinaryKSUID] wrap segmentio/ksuid with storage-specific
|
||||||
// SQL encoding. Both share identical GraphQL string scalar transit. Choose StringKSUID
|
// SQL encoding. Both implement [ApplyInterface] via Equal and IsZero for use
|
||||||
// for text columns (VARCHAR, TEXT); choose BinaryKSUID for binary columns
|
// with [ApplyInterfacePtr]. Both share identical GraphQL string scalar transit.
|
||||||
// (BINARY(20), BYTEA).
|
// Choose StringKSUID for text columns (VARCHAR, TEXT); choose BinaryKSUID for
|
||||||
|
// binary columns (BINARY(20), BYTEA).
|
||||||
//
|
//
|
||||||
// [JSONB] provides map-based JSON column scanning for Postgres JSONB and MySQL JSON.
|
// [JSONB] provides map-based JSON column scanning for Postgres JSONB and MySQL JSON.
|
||||||
//
|
//
|
||||||
|
|||||||
@@ -15,6 +15,20 @@ type BinaryKSUID struct {
|
|||||||
ksuid.KSUID
|
ksuid.KSUID
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NilBinaryKSUID is the zero/nil BinaryKSUID value.
|
||||||
|
var NilBinaryKSUID = BinaryKSUID{KSUID: ksuid.Nil}
|
||||||
|
|
||||||
|
// Equal reports whether two BinaryKSUID values represent the same identifier,
|
||||||
|
// treating two nil values as equal. Implements [ApplyInterface].
|
||||||
|
func (b BinaryKSUID) Equal(rh BinaryKSUID) bool {
|
||||||
|
return equalKSUID(b.KSUID, rh.KSUID)
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsZero reports whether b is nil. Implements [ApplyInterface].
|
||||||
|
func (b BinaryKSUID) IsZero() bool {
|
||||||
|
return b.IsNil()
|
||||||
|
}
|
||||||
|
|
||||||
// NewBinaryKSUID generates a new BinaryKSUID.
|
// NewBinaryKSUID generates a new BinaryKSUID.
|
||||||
func NewBinaryKSUID() BinaryKSUID {
|
func NewBinaryKSUID() BinaryKSUID {
|
||||||
return BinaryKSUID{KSUID: ksuid.New()}
|
return BinaryKSUID{KSUID: ksuid.New()}
|
||||||
|
|||||||
@@ -28,3 +28,10 @@ const (
|
|||||||
ksuidBinaryLength = 20
|
ksuidBinaryLength = 20
|
||||||
ksuidStringLength = 27
|
ksuidStringLength = 27
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func equalKSUID(lh, rh ksuid.KSUID) bool {
|
||||||
|
if lh.IsNil() && rh.IsNil() {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return lh.String() == rh.String()
|
||||||
|
}
|
||||||
|
|||||||
@@ -15,6 +15,20 @@ type StringKSUID struct {
|
|||||||
ksuid.KSUID
|
ksuid.KSUID
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NilStringKSUID is the zero/nil StringKSUID value.
|
||||||
|
var NilStringKSUID = StringKSUID{KSUID: ksuid.Nil}
|
||||||
|
|
||||||
|
// Equal reports whether two StringKSUID values represent the same identifier,
|
||||||
|
// treating two nil values as equal. Implements [ApplyInterface].
|
||||||
|
func (s StringKSUID) Equal(rh StringKSUID) bool {
|
||||||
|
return equalKSUID(s.KSUID, rh.KSUID)
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsZero reports whether s is nil. Implements [ApplyInterface].
|
||||||
|
func (s StringKSUID) IsZero() bool {
|
||||||
|
return s.IsNil()
|
||||||
|
}
|
||||||
|
|
||||||
// NewStringKSUID generates a new StringKSUID.
|
// NewStringKSUID generates a new StringKSUID.
|
||||||
func NewStringKSUID() StringKSUID {
|
func NewStringKSUID() StringKSUID {
|
||||||
return StringKSUID{KSUID: ksuid.New()}
|
return StringKSUID{KSUID: ksuid.New()}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/go-jet/jet/v2/mysql"
|
||||||
"github.com/segmentio/ksuid"
|
"github.com/segmentio/ksuid"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
@@ -118,6 +119,34 @@ func TestBinaryKSUID_Conversion(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func TestStringKSUID_EqualIsZero(t *testing.T) {
|
||||||
|
id := NewStringKSUID()
|
||||||
|
assert.True(t, NilStringKSUID.Equal(NilStringKSUID))
|
||||||
|
assert.True(t, id.Equal(id))
|
||||||
|
assert.False(t, id.Equal(NilStringKSUID))
|
||||||
|
assert.True(t, NilStringKSUID.IsZero())
|
||||||
|
assert.False(t, id.IsZero())
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBinaryKSUID_EqualIsZero(t *testing.T) {
|
||||||
|
id := NewBinaryKSUID()
|
||||||
|
assert.True(t, NilBinaryKSUID.Equal(NilBinaryKSUID))
|
||||||
|
assert.True(t, id.Equal(id))
|
||||||
|
assert.False(t, id.Equal(NilBinaryKSUID))
|
||||||
|
assert.True(t, NilBinaryKSUID.IsZero())
|
||||||
|
assert.False(t, id.IsZero())
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestStringKSUID_ApplyInterfacePtr(t *testing.T) {
|
||||||
|
targetCol := mysql.StringColumn("id")
|
||||||
|
modified := make(ColumnList, 0)
|
||||||
|
current := Ptr(NewStringKSUID())
|
||||||
|
updated := ApplyInterfacePtr(current, Ptr(NewStringKSUID()), &modified, targetCol)
|
||||||
|
require.NotNil(t, updated)
|
||||||
|
assert.Len(t, modified, 1)
|
||||||
|
assert.False(t, current.Equal(*updated))
|
||||||
|
}
|
||||||
|
|
||||||
func TestParseStringKSUID(t *testing.T) {
|
func TestParseStringKSUID(t *testing.T) {
|
||||||
id := ksuid.New()
|
id := ksuid.New()
|
||||||
parsed, err := ParseStringKSUID(id.String())
|
parsed, err := ParseStringKSUID(id.String())
|
||||||
|
|||||||
Reference in New Issue
Block a user