From cc7fd1d7d60de614649d14fbf5e3fe04ece8f80b Mon Sep 17 00:00:00 2001 From: Simon Martin Date: Tue, 2 Jun 2026 10:02:43 +0000 Subject: [PATCH] model: support "unset" RID values This will allow supporting empty RID attributes in GraphQL, for example to unset a resource identified by its RID, like in [1]. Signed-off-by: Simon Martin [1] https://lists.sr.ht/~sircmpwn/sr.ht-dev/patches/69497#%3CDISLPAS09WFR.1KQUECIN0GPM@ddevault.org%3E --- model/rid.go | 37 +++++++++++++++++++++++-------------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/model/rid.go b/model/rid.go index 8af5a9d67e517b9ac8605f23aaec173c3e38bacc..818c1856a1f266e8f67e6ae96fab334b15fd6193 100644 --- a/model/rid.go +++ b/model/rid.go @@ -16,28 +16,37 @@ var base32Encoding = base32. // An RID is a unique resource ID. type RID struct { - uuid uuid.UUID + uuid uuid.NullUUID } // Creates a new resource ID. func NewRID() RID { - uuid, err := uuid.NewV7() + uu, err := uuid.NewV7() if err != nil { panic(err) } return RID{ - uuid: uuid, + uuid: uuid.NullUUID{ + UUID: uu, + Valid: true, + }, } } // Returns the UUID representation of this RID. func (rid *RID) UUID() uuid.UUID { - return rid.uuid + if !rid.uuid.Valid { + panic(fmt.Errorf("invalid UUID")) + } + return rid.uuid.UUID } // Returns the string representation of this RID. func (rid *RID) String() string { - return base32Encoding.EncodeToString(rid.uuid[:]) + if !rid.uuid.Valid { + return "" + } + return base32Encoding.EncodeToString(rid.uuid.UUID[:]) } func (rid RID) MarshalGQL(w io.Writer) { @@ -45,14 +54,20 @@ func (rid RID) MarshalGQL(w io.Writer) { } func (rid *RID) unmarshalString(s string) error { + if len(s) == 0 { + rid.uuid.Valid = false + return nil + } bytes, err := base32Encoding.DecodeString(s) if err != nil { return err } - rid.uuid, err = uuid.FromBytes(bytes) + rid.uuid.UUID, err = uuid.FromBytes(bytes) if err != nil { + rid.uuid.Valid = false return err } + rid.uuid.Valid = true return nil } @@ -71,17 +86,11 @@ func (rid *RID) Scan(src any) error { case string: return rid.unmarshalString(src) default: - var uuid uuid.UUID - err := uuid.Scan(src) - if err != nil { - return err - } - rid.uuid = uuid - return nil + return rid.uuid.Scan(src) } } // database/sql/driver.Valuer func (rid RID) Value() (driver.Value, error) { - return rid.UUID().Value() + return rid.uuid.Value() }