コード例 #1
0
ファイル: repository.py プロジェクト: helixyte/everest_nosql
 def __rollback(self, state):
     source_entity = state.entity
     ent_cls = type(source_entity)
     status = state.status
     if status != ENTITY_STATUS.CLEAN:
         mongo_coll = self.__get_mongo_collection(ent_cls)
         ent_oid = getattr(source_entity, '_id')
         if status == ENTITY_STATUS.NEW:
             mongo_coll.remove(ent_oid)
             if __debug__:
                 self.__logger.debug("Rollback INSERT entity OID %s."
                                     % ent_oid)
         else:
             if status == ENTITY_STATUS.DELETED:
                 data = transform_incoming(ent_cls, source_entity)
                 mongo_coll.insert(data)
                 if __debug__:
                     self.__logger.debug('Rollback REMOVE entity OID %s: '
                                         '%s.' % (ent_oid, data.items()))
             else:
                 assert status == ENTITY_STATUS.DIRTY
                 EntityState.set_state_data(source_entity,
                                            state.clean_data)
                 data = transform_incoming(ent_cls, source_entity)
                 mongo_coll.update({'_id':ent_oid}, data)
                 if __debug__:
                     self.__logger.debug('Rollback UPDATE entity OID %s: '
                                         '%s.' % (ent_oid, data.items()))
コード例 #2
0
ファイル: uow.py プロジェクト: helixyte/everest
 def unregister(self, entity_class, entity):
     """
     Unregisters the given entity for the given class and discards its
     state information.
     """
     EntityState.release(entity, self)
     self.__entity_set_map[entity_class].remove(entity)
コード例 #3
0
 def unregister(self, entity_class, entity):
     """
     Unregisters the given entity for the given class and discards its
     state information.
     """
     EntityState.release(entity, self)
     self.__entity_set_map[entity_class].remove(entity)
コード例 #4
0
ファイル: cache.py プロジェクト: helixyte/everest
    def update(self, source_data, target_entity):
        """
        Updates the state of the target entity with the given source data.

        :param target_entity: Entity to update.
        :type target_entity: Object implementing
          :class:`everest.interfaces.IEntity`.
        """
        EntityState.set_state_data(target_entity, source_data)
コード例 #5
0
ファイル: uow.py プロジェクト: helixyte/everest
    def register_clean(self, entity_class, entity):
        """
        Registers the given entity for the given class as CLEAN.

        :returns: Cloned entity.
        """
        EntityState.manage(entity, self)
        EntityState.get_state(entity).status = ENTITY_STATUS.CLEAN
        self.__entity_set_map[entity_class].add(entity)
コード例 #6
0
 def reset(self):
     """
     Releases all entities held by this Unit Of Work (i.e., removes state
     information from all registered entities and clears the entity map).
     """
     for ents in self.__entity_set_map.values():
         for ent in ents:
             EntityState.release(ent, self)
     self.__entity_set_map.clear()
コード例 #7
0
ファイル: uow.py プロジェクト: helixyte/everest
 def reset(self):
     """
     Releases all entities held by this Unit Of Work (i.e., removes state
     information from all registered entities and clears the entity map).
     """
     for ents in self.__entity_set_map.values():
         for ent in ents:
             EntityState.release(ent, self)
     self.__entity_set_map.clear()
コード例 #8
0
    def register_clean(self, entity_class, entity):
        """
        Registers the given entity for the given class as CLEAN.

        :returns: Cloned entity.
        """
        EntityState.manage(entity, self)
        EntityState.get_state(entity).status = ENTITY_STATUS.CLEAN
        self.__entity_set_map[entity_class].add(entity)
コード例 #9
0
ファイル: cache.py プロジェクト: papagr/everest
    def update(self, source_data, target_entity):
        """
        Updates the state of the target entity with the given source data.

        :param target_entity: Entity to update.
        :type target_entity: Object implementing
          :class:`everest.interfaces.IEntity`.
        """
        EntityState.set_state_data(target_entity, source_data)
コード例 #10
0
    def register_deleted(self, entity_class, entity):
        """
        Registers the given entity for the given class as DELETED.

        :raises ValueError: If the given entity already holds state that was
          created by another Unit Of Work.
        """
        EntityState.manage(entity, self)
        EntityState.get_state(entity).status = ENTITY_STATUS.DELETED
        self.__entity_set_map[entity_class].add(entity)
コード例 #11
0
ファイル: uow.py プロジェクト: helixyte/everest
    def register_deleted(self, entity_class, entity):
        """
        Registers the given entity for the given class as DELETED.

        :raises ValueError: If the given entity already holds state that was
          created by another Unit Of Work.
        """
        EntityState.manage(entity, self)
        EntityState.get_state(entity).status = ENTITY_STATUS.DELETED
        self.__entity_set_map[entity_class].add(entity)
コード例 #12
0
ファイル: uow.py プロジェクト: helixyte/everest
    def mark_deleted(self, entity):
        """
        Marks the given entity as DELETED.

        :raises ValueError: If the given entity does not hold state.
        """
        EntityState.get_state(entity).status = ENTITY_STATUS.DELETED
コード例 #13
0
    def mark_dirty(self, entity):
        """
        Marks the given entity for the given class as DIRTY.

        :raises ValueError: If the given entity does not hold state.
        """
        EntityState.get_state(entity).status = ENTITY_STATUS.DIRTY
コード例 #14
0
    def mark_deleted(self, entity):
        """
        Marks the given entity as DELETED.

        :raises ValueError: If the given entity does not hold state.
        """
        EntityState.get_state(entity).status = ENTITY_STATUS.DELETED
コード例 #15
0
ファイル: uow.py プロジェクト: helixyte/everest
    def mark_dirty(self, entity):
        """
        Marks the given entity for the given class as DIRTY.

        :raises ValueError: If the given entity does not hold state.
        """
        EntityState.get_state(entity).status = ENTITY_STATUS.DIRTY
コード例 #16
0
 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
コード例 #17
0
    def mark_new(self, entity):
        """
        Marks the given entity as NEW.

        This is done when an entity is re-associated with a session after
        having been removed before.
        """
        EntityState.get_state(entity).status = ENTITY_STATUS.NEW
コード例 #18
0
    def mark_pending(self, entity):
        """
        Sets the flag indicating if the state of the given entity has been
        persisted to `False`.

        :note: The persistency flag is orthogonal to the status flag.
        """
        EntityState.get_state(entity).is_persisted = False
コード例 #19
0
ファイル: uow.py プロジェクト: helixyte/everest
    def mark_new(self, entity):
        """
        Marks the given entity as NEW.

        This is done when an entity is re-associated with a session after
        having been removed before.
        """
        EntityState.get_state(entity).status = ENTITY_STATUS.NEW
コード例 #20
0
ファイル: uow.py プロジェクト: helixyte/everest
    def mark_pending(self, entity):
        """
        Sets the flag indicating if the state of the given entity has been
        persisted to `False`.

        :note: The persistency flag is orthogonal to the status flag.
        """
        EntityState.get_state(entity).is_persisted = False
コード例 #21
0
ファイル: session.py プロジェクト: helixyte/everest
 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
コード例 #22
0
ファイル: uow.py プロジェクト: helixyte/everest
    def is_marked_pending(self, entity):
        """
        Checks if the flag indicating that the state for the given entity
        has been persisted is `False`.

        :note: Use only after checking if the given entity is registered.
        :raises ValueError: If the entity has no state information.
        """
        return not EntityState.get_state(entity).is_persisted
コード例 #23
0
ファイル: uow.py プロジェクト: helixyte/everest
 def __object_iterator(self, status, ent_cls):
     if ent_cls is None:
         ent_clss = self.__entity_set_map.keys()
     else:
         ent_clss = [ent_cls]
     for ent_cls in ent_clss:
         for ent in self.__entity_set_map[ent_cls]:
             if EntityState.get_state(ent).status == status:
                 yield ent
コード例 #24
0
    def is_marked_pending(self, entity):
        """
        Checks if the flag indicating that the state for the given entity
        has been persisted is `False`.

        :note: Use only after checking if the given entity is registered.
        :raises ValueError: If the entity has no state information.
        """
        return not EntityState.get_state(entity).is_persisted
コード例 #25
0
ファイル: uow.py プロジェクト: helixyte/everest
 def iterator(self):
     """
     Returns an iterator over all entity states held by this Unit Of Work.
     """
     # FIXME: There is no dependency tracking; objects are iterated in
     #        random order.
     for ent_cls in list(self.__entity_set_map.keys()):
         for ent in self.__entity_set_map[ent_cls]:
             yield EntityState.get_state(ent)
コード例 #26
0
 def iterator(self):
     """
     Returns an iterator over all entity states held by this Unit Of Work.
     """
     # FIXME: There is no dependency tracking; objects are iterated in
     #        random order.
     for ent_cls in list(self.__entity_set_map.keys()):
         for ent in self.__entity_set_map[ent_cls]:
             yield EntityState.get_state(ent)
コード例 #27
0
 def __object_iterator(self, status, ent_cls):
     if ent_cls is None:
         ent_clss = self.__entity_set_map.keys()
     else:
         ent_clss = [ent_cls]
     for ent_cls in ent_clss:
         for ent in self.__entity_set_map[ent_cls]:
             if EntityState.get_state(ent).status == status:
                 yield ent
コード例 #28
0
ファイル: uow.py プロジェクト: helixyte/everest
    def mark_clean(self, entity):
        """
        Marks the given entity as CLEAN.

        This is done when an entity is loaded fresh from the repository or
        after a commit.
        """
        state = EntityState.get_state(entity)
        state.status = ENTITY_STATUS.CLEAN
        state.is_persisted = True
コード例 #29
0
    def mark_clean(self, entity):
        """
        Marks the given entity as CLEAN.

        This is done when an entity is loaded fresh from the repository or
        after a commit.
        """
        state = EntityState.get_state(entity)
        state.status = ENTITY_STATUS.CLEAN
        state.is_persisted = True
コード例 #30
0
 def is_marked_new(self, entity):
     """
     Checks if the given entity is marked with status NEW. Returns `False`
     if the entity has no state information.
     """
     try:
         result = EntityState.get_state(entity).status == ENTITY_STATUS.NEW
     except ValueError:
         result = False
     return result
コード例 #31
0
ファイル: uow.py プロジェクト: helixyte/everest
 def is_marked_new(self, entity):
     """
     Checks if the given entity is marked with status NEW. Returns `False`
     if the entity has no state information.
     """
     try:
         result = EntityState.get_state(entity).status == ENTITY_STATUS.NEW
     except ValueError:
         result = False
     return result
コード例 #32
0
ファイル: uow.py プロジェクト: b8va/everest
 def is_marked_pending(self, entity):
     """
     Checks if the flag indicating that the state for the given entity
     has been persisted is `False`. Returns `False` if the entity has no
     state information.
     """
     try:
         result = not EntityState.get_state(entity).is_persisted
     except ValueError:
         result = False
     return result
コード例 #33
0
 def test_basics(self):
     ent = _MyEntity(id=0)
     self._uow.register_new(_MyEntity, ent)
     self.assert_equal(EntityState.get_state(ent).status, ENTITY_STATUS.NEW)
     self.assert_equal([item.entity for item in self._uow.iterator()],
                       [ent])
     self.assert_equal(list(self._uow.get_new(_MyEntity)), [ent])
     self._uow.mark_clean(ent)
     self.assert_equal(list(self._uow.get_clean(_MyEntity)), [ent])
     self._uow.mark_dirty(ent)
     self.assert_equal(list(self._uow.get_dirty(_MyEntity)), [ent])
     self._uow.mark_deleted(ent)
     self.assert_equal(list(self._uow.get_deleted(_MyEntity)), [ent])
     self._uow.unregister(_MyEntity, ent)
     self.assert_equal(list(self._uow.iterator()), [])
     self._uow.reset()
コード例 #34
0
ファイル: test_uow.py プロジェクト: b8va/everest
 def test_basics(self):
     ent = _MyEntity(id=0)
     self._uow.register_new(_MyEntity, ent)
     self.assert_equal(EntityState.get_state(ent).status,
                       ENTITY_STATUS.NEW)
     self.assert_equal([item.entity for item in self._uow.iterator()],
                       [ent])
     self.assert_equal(list(self._uow.get_new(_MyEntity)), [ent])
     self._uow.mark_clean(ent)
     self.assert_equal(list(self._uow.get_clean(_MyEntity)), [ent])
     self._uow.mark_dirty(ent)
     self.assert_equal(list(self._uow.get_dirty(_MyEntity)), [ent])
     self._uow.mark_deleted(ent)
     self.assert_equal(list(self._uow.get_deleted(_MyEntity)), [ent])
     self._uow.unregister(_MyEntity, ent)
     self.assert_equal(list(self._uow.iterator()), [])
     self._uow.reset()
コード例 #35
0
ファイル: test_state.py プロジェクト: papagr/everest
 def test_state_data(self):
     data = dict(text='FOO',
                 number=-1,
                 parent=MyEntityParent(),
                 children=[MyEntityChild()])
     entity = MyEntity(**data)
     # We don't want to test the required unit of work here.
     uow = MagicMock()
     self.assert_raises(ValueError, EntityState.get_state, entity)
     entity.__everest__ = EntityState(entity, uow)
     state_data = EntityState.get_state(entity).data
     for attr, value in state_data.items():
         if attr.resource_attr == 'number':
             number_attr = attr
         elif attr.resource_attr == 'parent':
             parent_attr = attr
         elif attr.resource_attr == 'parent_text':
             parent_text_attr = attr
         if attr.resource_attr in data:
             self.assert_equal(value, data[attr.resource_attr])
     new_number = -2
     state_data[number_attr] = new_number
     EntityState.get_state(entity).data = state_data
     self.assert_equal(entity.number, new_number)
     new_entity = MyEntity()
     self.assert_not_equal(new_entity.number, new_number)
     new_entity.__everest__ = EntityState(new_entity, uow)
     EntityState.transfer_state_data(entity, new_entity)
     self.assert_equal(new_entity.number, new_number)
     # Make setting invalid attribute fail.
     invalid_number_attr = terminal_attribute(str, 'grmbl')
     del state_data[number_attr]
     state_data[invalid_number_attr] = -2
     with self.assert_raises(ValueError) as cm:
         EntityState.get_state(entity).data = state_data
     self.assert_true(cm.exception.args[0].startswith('Can not set'))
     # Make set nested attribute fail.
     entity.parent = None
     del state_data[invalid_number_attr]
     del state_data[parent_attr]
     state_data[parent_text_attr] = 'FOO PARENT'
     state = EntityState.get_state(entity)
     self.assert_raises(AttributeError, setattr, state, 'data', state_data)
コード例 #36
0
 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
コード例 #37
0
ファイル: test_memory_cache.py プロジェクト: b8va/everest
 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))
コード例 #38
0
ファイル: test_state.py プロジェクト: b8va/everest
 def test_state_data(self):
     data = dict(text='FOO',
                 number=-1,
                 parent=MyEntityParent(),
                 children=[MyEntityChild()])
     entity = MyEntity(**data)
     # We don't want to test the required unit of work here.
     uow = MagicMock()
     self.assert_raises(ValueError, EntityState.get_state, entity)
     entity.__everest__ = EntityState(entity, uow)
     state_data = EntityState.get_state(entity).data
     for attr, value in state_data.items():
         if attr.resource_attr == 'number':
             number_attr = attr
         elif attr.resource_attr == 'parent':
             parent_attr = attr
         elif attr.resource_attr == 'parent_text':
             parent_text_attr = attr
         if attr.resource_attr in data:
             self.assert_equal(value, data[attr.resource_attr])
     new_number = -2
     state_data[number_attr] = new_number
     EntityState.get_state(entity).data = state_data
     self.assert_equal(entity.number, new_number)
     new_entity = MyEntity()
     self.assert_not_equal(new_entity.number, new_number)
     new_entity.__everest__ = EntityState(new_entity, uow)
     EntityState.transfer_state_data(entity, new_entity)
     self.assert_equal(new_entity.number, new_number)
     # Make setting invalid attribute fail.
     invalid_number_attr = terminal_attribute(str, 'grmbl')
     del state_data[number_attr]
     state_data[invalid_number_attr] = -2
     with self.assert_raises(ValueError) as cm:
         EntityState.get_state(entity).data = state_data
     self.assert_true(cm.exception.args[0].startswith('Can not set'))
     # Make set nested attribute fail.
     entity.parent = None
     del state_data[invalid_number_attr]
     del state_data[parent_attr]
     state_data[parent_text_attr] = 'FOO PARENT'
     state = EntityState.get_state(entity)
     self.assert_raises(AttributeError, setattr, state, 'data', state_data)
コード例 #39
0
ファイル: session.py プロジェクト: papagr/everest
 def __update(self, source_data, target_entity, path): # pylint: disable=W0613
     EntityState.set_state_data(target_entity, source_data)
コード例 #40
0
 def __update(self, source_data, target_entity):  # pylint: disable=W0613
     EntityState.set_state_data(target_entity, source_data)
     if self.__unit_of_work.is_marked_persisted(target_entity):
         self.__unit_of_work.mark_pending(target_entity)
コード例 #41
0
 def test_get_state_unregistered_fails(self):
     ent = _MyEntity()
     with self.assert_raises(ValueError) as cm:
         EntityState.get_state(ent)
     msg = 'Trying to obtain state for un-managed entity'
     self.assert_true(cm.exception.args[0].startswith(msg))
コード例 #42
0
ファイル: test_uow.py プロジェクト: b8va/everest
 def test_get_state_unregistered_fails(self):
     ent = _MyEntity()
     with self.assert_raises(ValueError) as cm:
         EntityState.get_state(ent)
     msg = 'Trying to obtain state for un-managed entity'
     self.assert_true(cm.exception.args[0].startswith(msg))
コード例 #43
0
ファイル: session.py プロジェクト: helixyte/everest
 def __update(self, source_data, target_entity): # pylint: disable=W0613
     EntityState.set_state_data(target_entity, source_data)
     if self.__unit_of_work.is_marked_persisted(target_entity):
         self.__unit_of_work.mark_pending(target_entity)