X-Git-Url: https://plomlompom.com/repos/%7B%7Bprefix%7D%7D/move_up?a=blobdiff_plain;f=plomtask%2Fdb.py;h=b3f1db00986b1142f5f31be34060864840ab5bdc;hb=21df71ef1fde304b158da5989692c01f463515b5;hp=cce2630cd58bfb8bf7283c2eb0d2f45006d8ba26;hpb=c021152e6566c8374170de916c69d6b5c816cd54;p=plomtask diff --git a/plomtask/db.py b/plomtask/db.py index cce2630..b3f1db0 100644 --- a/plomtask/db.py +++ b/plomtask/db.py @@ -274,24 +274,58 @@ class BaseModel(Generic[BaseModelId]): @property def as_dict(self) -> dict[str, object]: - """Return self as (json.dumps-coompatible) dict.""" - d: dict[str, object] = {'id': self.id_} + """Return self as (json.dumps-compatible) dict.""" + library: dict[str, dict[str | int, object]] = {} + d: dict[str, object] = {'id': self.id_, '_library': library} + for to_save in self.to_save: + attr = getattr(self, to_save) + if hasattr(attr, 'as_dict_into_reference'): + d[to_save] = attr.as_dict_into_reference(library) + else: + d[to_save] = attr if len(self.to_save_versioned) > 0: d['_versioned'] = {} - for k in self.to_save: - attr = getattr(self, k) - if hasattr(attr, 'as_dict'): - d[k] = attr.as_dict - d[k] = attr for k in self.to_save_versioned: attr = getattr(self, k) assert isinstance(d['_versioned'], dict) d['_versioned'][k] = attr.history for r in self.to_save_relations: attr_name = r[2] - d[attr_name] = [x.as_dict for x in getattr(self, attr_name)] + l: list[int | str] = [] + for rel in getattr(self, attr_name): + l += [rel.as_dict_into_reference(library)] + d[attr_name] = l return d + def as_dict_into_reference(self, + library: dict[str, dict[str | int, object]] + ) -> int | str: + """Return self.id_ while writing .as_dict into library.""" + def into_library(library: dict[str, dict[str | int, object]], + cls_name: str, + id_: str | int, + d: dict[str, object] + ) -> None: + if cls_name not in library: + library[cls_name] = {} + if id_ in library[cls_name]: + if library[cls_name][id_] != d: + msg = 'Unexpected inequality of entries for ' +\ + f'_library at: {cls_name}/{id_}' + raise HandledException(msg) + else: + library[cls_name][id_] = d + as_dict = self.as_dict + assert isinstance(as_dict['_library'], dict) + for cls_name, dict_of_objs in as_dict['_library'].items(): + for id_, obj in dict_of_objs.items(): + into_library(library, cls_name, id_, obj) + del as_dict['_library'] + assert self.id_ is not None + into_library(library, self.__class__.__name__, self.id_, as_dict) + assert isinstance(as_dict['id'], (int, str)) + return as_dict['id'] + # cache management # (we primarily use the cache to ensure we work on the same object in # memory no matter where and how we retrieve it, e.g. we don't want