Add Pointer field
This commit is contained in:
parent
5828e45e35
commit
450d8d490a
|
@ -95,32 +95,51 @@ class Record(Dict[(str, Field)]):
|
|||
return f"{self.__class__.__name__}[{self.doc_id}]: {self.items()}"
|
||||
|
||||
|
||||
@dataclass
|
||||
class Pointer(Field):
|
||||
"""
|
||||
Store a string reference to a record.
|
||||
"""
|
||||
|
||||
name: str = ""
|
||||
value_type: type = Record
|
||||
|
||||
def serialize(self, value: value_type, db: TinyDB) -> str:
|
||||
if value:
|
||||
if not value.doc_id:
|
||||
raise PointerReferenceError(value)
|
||||
return f"{value._metadata.table}::{value.uid}"
|
||||
return ""
|
||||
|
||||
def deserialize(self, value: str, db: TinyDB, recurse=True) -> value_type:
|
||||
pt, puid = value.split("::")
|
||||
if puid:
|
||||
return db.table(pt).search(where("uid") == puid, recurse=recurse)[0]
|
||||
return value
|
||||
|
||||
|
||||
@dataclass
|
||||
class Collection(Field):
|
||||
"""
|
||||
A collection of fields that store pointers instead of dicts.
|
||||
A collection of pointers.
|
||||
"""
|
||||
|
||||
value_type: type = Record
|
||||
default: List[value_type] = field(default_factory=lambda: [])
|
||||
|
||||
def serialize(self, value: value_type, db: TinyDB) -> List[str]:
|
||||
vals = self.default
|
||||
if value:
|
||||
for rec in value:
|
||||
if not rec.doc_id:
|
||||
raise PointerReferenceError(rec)
|
||||
vals.append(f"{rec._metadata.table}::{rec.uid}")
|
||||
return vals
|
||||
def _pointer(self, rec):
|
||||
return Pointer(value_type=type(rec))
|
||||
|
||||
def deserialize(self, rec: List[value_type], db: TinyDB, recurse=True) -> value_type:
|
||||
def serialize(self, values: List[Record], db: TinyDB) -> List[str]:
|
||||
if values:
|
||||
return [self._pointer(val).serialize(val, db=db) for val in values]
|
||||
|
||||
def deserialize(self, values: List[str], db: TinyDB, recurse=True) -> List[value_type]:
|
||||
"""
|
||||
Recursively deserialize the objects in this collection
|
||||
"""
|
||||
vals = []
|
||||
if not recurse:
|
||||
return rec
|
||||
for member in rec:
|
||||
pt, puid = member.split("::")
|
||||
vals.append(db.table(pt).search(where("uid") == puid)[0])
|
||||
return vals
|
||||
return values
|
||||
if values:
|
||||
return [self._pointer(val).deserialize(val, db=db, recurse=recurse) for val in values]
|
||||
return []
|
||||
|
|
Loading…
Reference in New Issue
Block a user