def __clone(self, entity, cache): clone = object.__new__(entity.__class__) # We add the clone with its ID set to the cache *before* we load it # so that circular references will work. clone.id = entity.id cache.add(clone) state = EntityState.get_state_data(entity) id_attr = None for attr, value in iteritems_(state): if attr.entity_attr == 'id': id_attr = attr continue attr_type = attr.attr_type if attr.kind != RESOURCE_ATTRIBUTE_KINDS.TERMINAL \ and not self.__repository.is_registered_resource(attr_type): # Prevent loading of entities from other repositories. # FIXME: Doing this here is inconsistent, since e.g. the RDB # session does not perform this kind of check. continue elif attr.kind == RESOURCE_ATTRIBUTE_KINDS.MEMBER \ and not value is None: ent_cls = get_entity_class(attr_type) new_value = self.load(ent_cls, value) state[attr] = new_value elif attr.kind == RESOURCE_ATTRIBUTE_KINDS.COLLECTION \ and len(value) > 0: value_type = type(value) new_value = value_type.__new__(value_type) if issubclass(value_type, MutableSequence): add_op = new_value.append elif issubclass(value_type, MutableSet): add_op = new_value.add else: raise ValueError('Do not know how to clone value of type ' '%s for resource attribute %s.' % (type(new_value), attr)) ent_cls = get_entity_class(attr_type) for child in value: child_clone = self.load(ent_cls, child) add_op(child_clone) state[attr] = new_value # We set the ID already above. if not id_attr is None: del state[id_attr] EntityState.set_state_data(clone, state) return clone
def __clone(self, entity, cache): clone = object.__new__(entity.__class__) # We add the clone with its ID set to the cache *before* we load it # so that circular references will work. clone.id = entity.id cache.add(clone) state = EntityState.get_state_data(entity) id_attr = None for attr, value in iteritems_(state): if attr.entity_attr == 'id': id_attr = attr continue attr_type = attr.attr_type if attr.kind != RESOURCE_ATTRIBUTE_KINDS.TERMINAL \ and not self.__repository.is_registered_resource(attr_type): # Prevent loading of entities from other repositories. # FIXME: Doing this here is inconsistent, since e.g. the RDB # session does not perform this kind of check. continue elif attr.kind == RESOURCE_ATTRIBUTE_KINDS.MEMBER \ and not value is None: ent_cls = get_entity_class(attr_type) new_value = self.load(ent_cls, value) state[attr] = new_value elif attr.kind == RESOURCE_ATTRIBUTE_KINDS.COLLECTION \ and len(value) > 0: value_type = type(value) new_value = value_type.__new__(value_type) if issubclass(value_type, MutableSequence): add_op = new_value.append elif issubclass(value_type, MutableSet): add_op = new_value.add else: raise ValueError('Do not know how to clone value of type ' '%s for resource attribute %s.' % (type(new_value), attr)) ent_cls = get_entity_class(attr_type) for child in value: child_clone = self.load(ent_cls, child) add_op(child_clone) state[attr] = new_value # We set the ID already above. if not id_attr is None: del state[id_attr] EntityState.set_state_data(clone, state) return clone
def test_basics(self): ent = MyEntity(id=0) cache = EntityCache(entities=[]) cache.add(ent) self.assert_true(cache.get_by_id(ent.id) is ent) self.assert_true(cache.has_id(ent.id)) self.assert_true(cache.get_by_slug(ent.slug) is ent) self.assert_true(cache.has_slug(ent.slug)) self.assert_equal(len(cache.get_all()), 1) # Adding the same entity twice should not have any effect. cache.add(ent) self.assert_true(cache.get_by_id(ent.id) is ent) self.assert_equal(len(cache.get_all()), 1) # ent1 = MyEntity(id=0) txt = 'FROBNIC' ent1.text = txt cache.update(EntityState.get_state_data(ent1), ent) self.assert_equal(cache.get_by_id(ent.id).text, txt) self.assert_equal(cache.get_all(), [ent]) self.assert_equal(list(cache.retrieve()), [ent]) cache.remove(ent) self.assert_is_none(cache.get_by_id(ent.id)) self.assert_is_none(cache.get_by_slug(ent.slug))
def test_basics(self): ent = MyEntity(id=0) cache = EntityCache(entities=[]) cache.add(ent) assert cache.get_by_id(ent.id) is ent assert cache.has_id(ent.id) assert cache.get_by_slug(ent.slug)[0] is ent assert cache.has_slug(ent.slug) assert len(cache.get_all()) == 1 # Adding the same entity twice should not have any effect. cache.add(ent) assert cache.get_by_id(ent.id) is ent assert len(cache.get_all()) == 1 # ent1 = MyEntity(id=0) txt = 'FROBNIC' ent1.text = txt cache.update(EntityState.get_state_data(ent1), ent) assert cache.get_by_id(ent.id).text == txt assert cache.get_all() == [ent] assert list(cache.retrieve()) == [ent] cache.remove(ent) assert cache.get_by_id(ent.id) is None assert cache.get_by_slug(ent.slug) is None