Fix backreferences to the same table
This commit is contained in:
parent
de72d38b8f
commit
40b6650970
|
@ -21,4 +21,5 @@ class Group(Record):
|
||||||
Field("name", unique=True),
|
Field("name", unique=True),
|
||||||
Collection("members", User),
|
Collection("members", User),
|
||||||
Collection("groups", Group),
|
Collection("groups", Group),
|
||||||
|
BackReference("parent", Group),
|
||||||
]
|
]
|
||||||
|
|
|
@ -127,15 +127,19 @@ class Pointer(Field):
|
||||||
value_type: type = Record
|
value_type: type = Record
|
||||||
|
|
||||||
def serialize(self, value: value_type) -> str:
|
def serialize(self, value: value_type) -> str:
|
||||||
|
return Pointer.reference(value)
|
||||||
|
|
||||||
|
def deserialize(self, value: str, db: TinyDB, recurse: bool = True) -> value_type:
|
||||||
|
return Pointer.dereference(value, db, recurse)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def reference(cls, value: Record):
|
||||||
if value:
|
if value:
|
||||||
if not value.doc_id:
|
if not value.doc_id:
|
||||||
raise PointerReferenceError(value)
|
raise PointerReferenceError(value)
|
||||||
return f"{value._metadata.table}::{value.uid}"
|
return f"{value._metadata.table}::{value.uid}"
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def deserialize(self, value: str, db: TinyDB, recurse: bool = True) -> value_type:
|
|
||||||
return Pointer.dereference(value, db, recurse)
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def dereference(cls, value: str, db: TinyDB, recurse: bool = True):
|
def dereference(cls, value: str, db: TinyDB, recurse: bool = True):
|
||||||
if not value:
|
if not value:
|
||||||
|
@ -186,7 +190,7 @@ class Collection(Field):
|
||||||
return
|
return
|
||||||
|
|
||||||
for member in record[self.name]:
|
for member in record[self.name]:
|
||||||
reference = Pointer.dereference(member, db=db)
|
target = Pointer.dereference(member, db=db)
|
||||||
for backref in reference._metadata.backrefs(type(record)):
|
for backref in target._metadata.backrefs(type(record)):
|
||||||
reference[backref.name] = record
|
target[backref.name] = Pointer.reference(record)
|
||||||
db.table(reference._metadata.table).upsert(reference)
|
db.table(target._metadata.table).update({backref.name: record}, where("uid") == target.uid)
|
||||||
|
|
|
@ -68,9 +68,13 @@ def test_subgroups(db):
|
||||||
snw = db.save(examples.Group(name="Strange New Worlds", members=[pike]))
|
snw = db.save(examples.Group(name="Strange New Worlds", members=[pike]))
|
||||||
|
|
||||||
starfleet = db.save(examples.Group(name="Starfleet", groups=[tos, snw]))
|
starfleet = db.save(examples.Group(name="Starfleet", groups=[tos, snw]))
|
||||||
|
tos = db.table("Group").get(doc_id=tos.doc_id)
|
||||||
|
snw = db.table("Group").get(doc_id=snw.doc_id)
|
||||||
assert tos in starfleet.groups
|
assert tos in starfleet.groups
|
||||||
assert snw in starfleet.groups
|
assert snw in starfleet.groups
|
||||||
|
|
||||||
|
assert tos.parent.uid == starfleet.uid
|
||||||
|
|
||||||
unique_users = set([user for group in starfleet.groups for user in group.members])
|
unique_users = set([user for group in starfleet.groups for user in group.members])
|
||||||
|
|
||||||
kirk = db.table("User").get(doc_id=kirk.doc_id)
|
kirk = db.table("User").get(doc_id=kirk.doc_id)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user