def _serialize_entity(self, entity: ffd.Entity, add_new: bool = False): relationships = self._get_relationships(entity.__class__) if len(relationships.keys()) > 0: obj = entity.to_dict(force_all=True, skip=list(relationships.keys())) for k, v in relationships.items(): if v['this_side'] == 'one': try: sub_entity = getattr(entity, k) if sub_entity is not None: if add_new: exists = self._cache_get( f'aggregate_references.{sub_entity.__class__}.{sub_entity.id_value()}' ) if exists is None: e = self._registry(v['target']).find( sub_entity.id_value()) if e is not None: self._cache_set( f'aggregate_references.{sub_entity.__class__}.{sub_entity.id_value()}', True) else: self._registry( v['target']).append(sub_entity) obj[k] = sub_entity.id_value() except AttributeError: obj[k] = None elif v['this_side'] == 'many': obj[k] = [] for f in getattr(entity, k): try: if add_new: exists = self._cache_get( f'aggregate_references.{f.__class__}.{f.id_value()}' ) if exists is None: e = self._registry(v['target']).find( f.id_value()) if e is not None: self._cache_set( f'aggregate_references.{f.__class__}.{f.id_value()}', True) else: self._registry(v['target']).append(f) obj[k].append(f.id_value()) except AttributeError: obj[k].append(None) else: obj = entity.to_dict(force_all=True) return self._serializer.serialize(obj)
def _update(self, entity: ffd.Entity): criteria = ffd.Attr(entity.id_name()) == entity.id_value() try: criteria &= ffd.Attr('version') == getattr(entity, '__ff_version') except AttributeError: pass return self._execute(*self._generate_query( entity, f'{self._sql_prefix}/update.sql', { 'data': self._data_fields(entity, add_new=True), 'criteria': criteria } ))
def update(self, entity: ffd.Entity): self._check_prerequisites(entity.__class__) if hasattr(entity, 'updated_on'): entity.updated_on = datetime.now() return self._update(entity)
def _remove(self, entity: ffd.Entity): cursor = self._connection.cursor() sql = f"delete from {self._fqtn(entity.__class__)} where id = ?" cursor.execute(sql, (entity.id_value(), )) self._connection.commit() self._remove_from_cache(entity)
def _generate_parameters(self, entity: ffd.Entity, part: str = None): obj = self._serializer.serialize(entity) params = {'id': entity.id_value(), 'obj': obj} for field_ in self.get_indexes(entity.__class__): params[field_.name] = getattr(entity, field_.name) return params
def _remove_from_cache(self, entity: ffd.Entity): if entity.__class__ in self._cache and entity.id_value( ) in self._cache[entity.__class__]: del self._cache[entity.__class__][entity.id_value()]
def _set(self, entity: ffd.Entity): if entity.__class__ not in self._cache: self._cache[entity.__class__] = {} self._cache[entity.__class__][entity.id_value()] = entity
def _get(self, entity: ffd.Entity): if entity.__class__ in self._cache and entity.id_value( ) in self._cache[entity.__class__]: return self._cache[entity.__class__][entity.id_value()]
def register_entity(self, entity: ffd.Entity): self._entity_hashes[entity.id_value()] = self._get_hash(entity) self._entities.append(entity) if self._parent is not None: self._parent.register_entity(entity)
def _get_hash(self, entity: ffd.Entity): return hashlib.md5(self._serializer.serialize(entity.to_dict(force_all=True)).encode('utf-8')).hexdigest()
def touch(self, entity: ffd.Entity): if entity.id_value() in self._entity_hashes: self._entity_hashes[entity.id_value()] = ''
def _has_changed(self, entity: ffd.Entity): if entity.id_value() not in self._entity_hashes: return False return self._get_hash(entity) != self._entity_hashes[entity.id_value()]