a712ccc38f
Adds StringKSUIDExpr and BinaryKSUIDExpr for use with ExprValues, plus Expr() methods on both types. Removes ExprStringKSUIDs and BinExpr. Co-authored-by: Cursor <cursoragent@cursor.com>
101 lines
2.6 KiB
Go
101 lines
2.6 KiB
Go
package dbx
|
|
|
|
import (
|
|
"database/sql/driver"
|
|
"fmt"
|
|
"io"
|
|
|
|
"github.com/segmentio/ksuid"
|
|
)
|
|
|
|
// StringKSUID wraps segmentio/ksuid for text-column storage (VARCHAR, TEXT).
|
|
// SQL Scan/Value use the base62 string encoding. GraphQL transit uses a string
|
|
// scalar (base62 KSUID).
|
|
type StringKSUID struct {
|
|
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.
|
|
func NewStringKSUID() StringKSUID {
|
|
return StringKSUID{KSUID: ksuid.New()}
|
|
}
|
|
|
|
// ParseStringKSUID parses a StringKSUID from its base62 string form.
|
|
func ParseStringKSUID(s string) (StringKSUID, error) {
|
|
id, err := ksuid.Parse(s)
|
|
if err != nil {
|
|
return StringKSUID{}, err
|
|
}
|
|
return StringKSUID{KSUID: id}, nil
|
|
}
|
|
|
|
// AsBinaryKSUID returns a BinaryKSUID view of the same identifier.
|
|
func (s StringKSUID) AsBinaryKSUID() BinaryKSUID {
|
|
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.
|
|
func (s *StringKSUID) Scan(src any) error {
|
|
switch v := src.(type) {
|
|
case nil:
|
|
*s = StringKSUID{}
|
|
return nil
|
|
case string:
|
|
id, err := ksuid.Parse(v)
|
|
if err != nil {
|
|
return fmt.Errorf("StringKSUID.Scan: %w", err)
|
|
}
|
|
*s = StringKSUID{KSUID: id}
|
|
return nil
|
|
case []byte:
|
|
if len(v) == ksuidBinaryLength {
|
|
return fmt.Errorf("StringKSUID.Scan: binary KSUID payload (%d bytes); use BinaryKSUID", len(v))
|
|
}
|
|
id, err := ksuid.Parse(string(v))
|
|
if err != nil {
|
|
return fmt.Errorf("StringKSUID.Scan: %w", err)
|
|
}
|
|
*s = StringKSUID{KSUID: id}
|
|
return nil
|
|
default:
|
|
return fmt.Errorf("StringKSUID.Scan: unable to scan type %T", v)
|
|
}
|
|
}
|
|
|
|
// Value implements driver.Valuer for string-backed KSUID columns.
|
|
func (s StringKSUID) Value() (driver.Value, error) {
|
|
if s.IsNil() {
|
|
return nil, nil
|
|
}
|
|
return s.String(), nil
|
|
}
|
|
|
|
// UnmarshalGQL implements the graphql.Unmarshaler interface.
|
|
func (s *StringKSUID) UnmarshalGQL(value any) error {
|
|
return unmarshalKSUIDFromGQL(value, s.UnmarshalText)
|
|
}
|
|
|
|
// MarshalGQL implements the graphql.Marshaler interface.
|
|
func (s StringKSUID) MarshalGQL(w io.Writer) {
|
|
marshalKSUIDToGQL(w, s.KSUID)
|
|
}
|