diff --git a/src/grung/types.py b/src/grung/types.py index bcac032..09da45a 100644 --- a/src/grung/types.py +++ b/src/grung/types.py @@ -295,13 +295,28 @@ class BinaryFilePointer(Field): def relpath(self, record): return Path(record._metadata.table) / record[record._metadata.primary_key] / f"{self.name}{self.extension}" + def reference(self, record): + return f"/::{self.relpath(record)}" + + def dereference(self, reference, db): + relpath = reference.replace("/::", "", 1) + try: + return (db.path / relpath).read_bytes() + except FileNotFoundError: + return None + + def serialize(self, value: value_type | str, record: Record | None = None) -> str: + return self.reference(record) + def deserialize(self, value: str, db: TinyDB, recurse: bool = True) -> value_type: if not value: return None - _, relpath = value.split("::") - return self.value_type((db.path / relpath).read_bytes()) + return self.dereference(value, db) def prepare(self, data: value_type): + """ + Return bytes to be written to disk + """ if not data: return if not isinstance(data, self.value_type): @@ -315,7 +330,6 @@ class BinaryFilePointer(Field): path = db.path / relpath path.parent.mkdir(parents=True, exist_ok=True) path.write_bytes(self.prepare(value)) - record[self.name] = f"File::{self.relpath(record)}" @dataclass @@ -335,8 +349,8 @@ class TextFilePointer(BinaryFilePointer): def deserialize(self, value: str, db: TinyDB, recurse: bool = True) -> value_type: if not value: return None - _, relpath = value.split("::") - return (db.path / relpath).read_text() + buf = super().deserialize(value, db) + return buf.decode() if buf else None @dataclass