Make pointer serialization idempotent

This commit is contained in:
evilchili 2025-10-03 12:03:21 -07:00
parent 600209d485
commit f1a47aaed4

View File

@ -130,14 +130,19 @@ class Pointer(Field):
name: str = "" name: str = ""
value_type: type = Record value_type: type = Record
def serialize(self, value: value_type) -> str: def serialize(self, value: value_type | str) -> str:
return Pointer.reference(value) return Pointer.reference(value)
def deserialize(self, value: str, db: TinyDB, recurse: bool = True) -> value_type: def deserialize(self, value: str, db: TinyDB, recurse: bool = True) -> value_type:
return Pointer.dereference(value, db, recurse) return Pointer.dereference(value, db, recurse)
@classmethod @classmethod
def reference(cls, value: Record): def reference(cls, value: Record | str):
# XXX This could be smarter
if isinstance(value, str):
if '::' not in value:
raise PointerReferenceError("Value {value} does not look like a reference!")
return value
if value: if value:
if not value.doc_id: if not value.doc_id:
raise PointerReferenceError(value) raise PointerReferenceError(value)
@ -196,7 +201,7 @@ class Collection(Field):
for member in record[self.name]: for member in record[self.name]:
target = Pointer.dereference(member, db=db, recurse=False) target = Pointer.dereference(member, db=db, recurse=False)
for backref in target._metadata.backrefs(type(record)): for backref in target._metadata.backrefs(type(record)):
target[backref.name] = Pointer.reference(record) target[backref.name] = record
db.table(target._metadata.table).update( db.save(target)
{backref.name: target[backref.name]}, where("uid") == target.uid
)