Ejemplo n.º 1
0
	def remove_all (cls):
		""" Remove all objects of this type from the database.

		.. note::
			- Relationships from and to these objects are removed as well.
			- Instanciated objects remain in memory, flagged as uncommitted.

		.. seealso::
			:meth:`~PersistentObject.remove`
		"""
		collection_name = cls.__name__

		n_objects = methods.find(collection_name, None, count = True)
		objects = methods.find(collection_name, None)

		n = 0
		for object in objects:
			try:
				object.remove()
				n += 1
			except:
				continue

		if (n < n_objects):
			logger.warning("%s out of %s objects in collection '%s' were not removed." % (n_objects - n, n_objects, collection_name))
			return

		methods.drop_collection(cls.__name__)
Ejemplo n.º 2
0
    def remove_all(cls):
        """ Remove all objects of this type from the database.

		.. note::
			- Relationships from and to these objects are removed as well.
			- Instanciated objects remain in memory, flagged as uncommitted.

		.. seealso::
			:meth:`~PersistentObject.remove`
		"""
        collection_name = cls.__name__

        n_objects = methods.find(collection_name, None, count=True)
        objects = methods.find(collection_name, None)

        n = 0
        for object in objects:
            try:
                object.remove()
                n += 1
            except:
                continue

        if (n < n_objects):
            logger.warning(
                "%s out of %s objects in collection '%s' were not removed." %
                (n_objects - n, n_objects, collection_name))
            return

        methods.drop_collection(cls.__name__)
Ejemplo n.º 3
0
	def _out_vertices (self, neighbor_collection, neighbor_filter = None, relationship_filter = None, count = False):
		""" List (or count) all outgoing relationships between this object and others.

		.. note::
			- This method should not be called directly.
			- If relationship_filter is not None, a query is performed in the
			  database; hence, the source object must be committed. If not a
			  :class:`MetagenomeDB.errors.UncommittedObjectError` exception is thrown.
		"""
		targets = self._properties["_relationship_with"]

		if (len(targets) == 0):
			if (count):
				return 0
			else:
				return []

		# consider neighbors regardless of their relationship
		if (relationship_filter == None):
			candidates = targets

		# consider neighbors matching relationship_filter
		else:
			if (not self._committed):
				raise errors.UncommittedObjectError("Cannot list relationships from %s to other objects: the source is not committed." % self)

			candidates = []
			for target_id in targets:
				query = {
					"_id": self._properties["_id"],
					"_relationships.%s" % target_id: {"$elemMatch": utils.tree.flatten(relationship_filter)}
				}

				if (methods.find(self.__class__.__name__, query, count = True) == 0):
					continue

				candidates.append(target_id)

		if (len(candidates) == 0):
			if (count):
				return 0
			else:
				return []

		# select candidates matching neighbor_filter
		query = {"_id": {"$in": [bson.objectid.ObjectId(id) for id in candidates]}}

		if (neighbor_filter != None):
			neighbor_filter = utils.tree.expand(neighbor_filter)
			for key in neighbor_filter:
				query[key] = neighbor_filter[key]

		return methods.find(neighbor_collection, query, count = count)
Ejemplo n.º 4
0
    def run(self, group = None, errors = None):
        """
        Called by Synctrex to run the synchronisation. This function takes in
        charge the preparation of the Sync, etc.
        """
        if not self.synctrex.can_sync_run(self, group):
            return

        if not errors:
            errors = []

        errors += self.check()
        if errors:
            return errors

        self.select_group(group or self.group)

        main = self.dest if self.dest.is_remote() else self.source
        method = methods.find(main, [self.method] if self.method else None)

        event = events.Event(sync = self, method = method,
                             main = main) #, errors = errors)
        self.trigger('pre_sync', event, True)
        exit_code = method.run(self)
        if exit_code:
            self.trigger('fail', event, True)
            # fixme: errors?
        else:
            self.trigger('success', event, True)
        self.trigger('post_sync', event, True)
Ejemplo n.º 5
0
	def _in_vertices (self, neighbor_collection, neighbor_filter = None, relationship_filter = None, count = False):
		""" List (or count) all incoming relationships between objects and this object.

		.. note::
			This method should not be called directly.
		"""
		# if the present object has never been committed,
		# no object can possibly be linked to it.
		if (not "_id" in self._properties):
			logger.debug("Attempt to list in-neighbors of %s while this object has never been committed." % self)
			if (count):
				return 0
			else:
				return []

		object_id = str(self._properties["_id"])

		query = {"_relationship_with": object_id}

		if (relationship_filter != None):
			query["_relationships.%s" % object_id] = {"$elemMatch": utils.tree.flatten(relationship_filter)}

		if (neighbor_filter != None):
			neighbor_filter = utils.tree.expand(neighbor_filter)
			for key in neighbor_filter:
				query[key] = neighbor_filter[key]

		return methods.find(neighbor_collection, query, count = count)
Ejemplo n.º 6
0
	def find_one (cls, filter):
		""" Find the first (or only) object of this type that match a query.

		Parameters:
			- **filter**: filter for the object to select; see :doc:`queries`.

		Return:
			An object, or None if no object found.

		.. seealso::
			:meth:`~PersistentObject.find`
		"""
		return methods.find(cls.__name__, query = filter, find_one = True)
Ejemplo n.º 7
0
    def find_one(cls, filter):
        """ Find the first (or only) object of this type that match a query.

		Parameters:
			- **filter**: filter for the object to select; see :doc:`queries`.

		Return:
			An object, or None if no object found.

		.. seealso::
			:meth:`~PersistentObject.find`
		"""
        return methods.find(cls.__name__, query=filter, find_one=True)
Ejemplo n.º 8
0
	def find (cls, filter = None):
		""" Find all objects of this type that match a query.

		Parameters:
			- **filter**: filter for the objects to select (optional); see
			  :doc:`queries`.

		Return:
			A generator.

		.. seealso::
			:meth:`~PersistentObject.count`, :meth:`~PersistentObject.find_one`
		"""
		return methods.find(cls.__name__, query = filter)
Ejemplo n.º 9
0
    def find(cls, filter=None):
        """ Find all objects of this type that match a query.

		Parameters:
			- **filter**: filter for the objects to select (optional); see
			  :doc:`queries`.

		Return:
			A generator.

		.. seealso::
			:meth:`~PersistentObject.count`, :meth:`~PersistentObject.find_one`
		"""
        return methods.find(cls.__name__, query=filter)
Ejemplo n.º 10
0
    def _in_vertices(self,
                     neighbor_collection,
                     neighbor_filter=None,
                     relationship_filter=None,
                     count=False):
        """ List (or count) all incoming relationships between objects and this object.

		.. note::
			This method should not be called directly.
		"""
        # if the present object has never been committed,
        # no object can possibly be linked to it.
        if (not "_id" in self._properties):
            logger.debug(
                "Attempt to list in-neighbors of %s while this object has never been committed."
                % self)
            if (count):
                return 0
            else:
                return []

        object_id = str(self._properties["_id"])

        query = {"_relationship_with": object_id}

        if (relationship_filter != None):
            query["_relationships.%s" % object_id] = {
                "$elemMatch": utils.tree.flatten(relationship_filter)
            }

        if (neighbor_filter != None):
            neighbor_filter = utils.tree.expand(neighbor_filter)
            for key in neighbor_filter:
                query[key] = neighbor_filter[key]

        return methods.find(neighbor_collection, query, count=count)
Ejemplo n.º 11
0
	def _disconnect_from (self, target, relationship_filter):
		""" Disconnect this object from another.

		.. note::
			- This method should not be called directly.
			- The target MUST have been committed at least once. However, the
			  source (i.e., the present object) can exist in memory only.
			- Throw a :class:`MetagenomeDB.errors.UncommittedObjectError` exception if the
			  target has never been committed, or if attempting to use
			  **relationship_filter** while the source is not committed.
			- Throw a :class:`MetagenomeDB.errors.InvalidObjectOperationError` if the
			  source is not connected to the target.
		"""
		if (not "_id" in target._properties):
			raise errors.UncommittedObjectError("Cannot disconnect %s from %s: target has never been committed." % target)

		target_id = str(target._properties["_id"])

		if (not target_id in self._properties["_relationships"]):
			raise errors.InvalidObjectOperationError("%s is not connected to %s." % (self, target))

		# case 1: we remove all relationships between the object and target
		if (relationship_filter == None):
			del self._properties["_relationships"][target_id]
			self._properties["_relationship_with"].remove(target_id)
			self._committed = False

			logger.debug("Removed all relationships between %s and %s." % (self, target))

		# case 2: we remove all relationships matching a criteria
		else:
			if (not self._committed):
				raise errors.UncommittedObjectError("Cannot disconnect %s from %s: the source is not committed." % (self, target))

			n_relationships = len(self._properties["_relationships"][target_id])
			clazz = self.__class__.__name__
			to_remove = []

			for n in range(n_relationships):
				query = {"_id": self._properties["_id"]}

				for key, value in utils.tree.flatten(relationship_filter).iteritems():
					query["_relationships.%s.%s.%s" % (target_id, n, key)] = value

				if (methods.find(clazz, query, count = True) == 0):
					continue

				to_remove.append(n)

			if (len(to_remove) == 0):
				raise errors.InvalidObjectOperationError("%s is not connected to %s by any relationship matching %s." % (self, target, utils.tree.flatten(relationship_filter)))

			for n in sorted(to_remove, reverse = True):
				logger.debug("Removed relationship %s between %s and %s." % (self._properties["_relationships"][target_id][n], self, target))

				del self._properties["_relationships"][target_id][n]

			if (len(to_remove) == n_relationships):
				del self._properties["_relationships"][target_id]
				self._properties["_relationship_with"].remove(target_id)

			self._committed = False
Ejemplo n.º 12
0
    def _out_vertices(self,
                      neighbor_collection,
                      neighbor_filter=None,
                      relationship_filter=None,
                      count=False):
        """ List (or count) all outgoing relationships between this object and others.

		.. note::
			- This method should not be called directly.
			- If relationship_filter is not None, a query is performed in the
			  database; hence, the source object must be committed. If not a
			  :class:`MetagenomeDB.errors.UncommittedObjectError` exception is thrown.
		"""
        targets = self._properties["_relationship_with"]

        if (len(targets) == 0):
            if (count):
                return 0
            else:
                return []

        # consider neighbors regardless of their relationship
        if (relationship_filter == None):
            candidates = targets

        # consider neighbors matching relationship_filter
        else:
            if (not self._committed):
                raise errors.UncommittedObjectError(
                    "Cannot list relationships from %s to other objects: the source is not committed."
                    % self)

            candidates = []
            for target_id in targets:
                query = {
                    "_id": self._properties["_id"],
                    "_relationships.%s" % target_id: {
                        "$elemMatch": utils.tree.flatten(relationship_filter)
                    }
                }

                if (methods.find(self.__class__.__name__, query,
                                 count=True) == 0):
                    continue

                candidates.append(target_id)

        if (len(candidates) == 0):
            if (count):
                return 0
            else:
                return []

        # select candidates matching neighbor_filter
        query = {
            "_id": {
                "$in": [bson.objectid.ObjectId(id) for id in candidates]
            }
        }

        if (neighbor_filter != None):
            neighbor_filter = utils.tree.expand(neighbor_filter)
            for key in neighbor_filter:
                query[key] = neighbor_filter[key]

        return methods.find(neighbor_collection, query, count=count)
Ejemplo n.º 13
0
    def _disconnect_from(self, target, relationship_filter):
        """ Disconnect this object from another.

		.. note::
			- This method should not be called directly.
			- The target MUST have been committed at least once. However, the
			  source (i.e., the present object) can exist in memory only.
			- Throw a :class:`MetagenomeDB.errors.UncommittedObjectError` exception if the
			  target has never been committed, or if attempting to use
			  **relationship_filter** while the source is not committed.
			- Throw a :class:`MetagenomeDB.errors.InvalidObjectOperationError` if the
			  source is not connected to the target.
		"""
        if (not "_id" in target._properties):
            raise errors.UncommittedObjectError(
                "Cannot disconnect %s from %s: target has never been committed."
                % target)

        target_id = str(target._properties["_id"])

        if (not target_id in self._properties["_relationships"]):
            raise errors.InvalidObjectOperationError(
                "%s is not connected to %s." % (self, target))

        # case 1: we remove all relationships between the object and target
        if (relationship_filter == None):
            del self._properties["_relationships"][target_id]
            self._properties["_relationship_with"].remove(target_id)
            self._committed = False

            logger.debug("Removed all relationships between %s and %s." %
                         (self, target))

        # case 2: we remove all relationships matching a criteria
        else:
            if (not self._committed):
                raise errors.UncommittedObjectError(
                    "Cannot disconnect %s from %s: the source is not committed."
                    % (self, target))

            n_relationships = len(
                self._properties["_relationships"][target_id])
            clazz = self.__class__.__name__
            to_remove = []

            for n in range(n_relationships):
                query = {"_id": self._properties["_id"]}

                for key, value in utils.tree.flatten(
                        relationship_filter).iteritems():
                    query["_relationships.%s.%s.%s" %
                          (target_id, n, key)] = value

                if (methods.find(clazz, query, count=True) == 0):
                    continue

                to_remove.append(n)

            if (len(to_remove) == 0):
                raise errors.InvalidObjectOperationError(
                    "%s is not connected to %s by any relationship matching %s."
                    % (self, target, utils.tree.flatten(relationship_filter)))

            for n in sorted(to_remove, reverse=True):
                logger.debug("Removed relationship %s between %s and %s." %
                             (self._properties["_relationships"][target_id][n],
                              self, target))

                del self._properties["_relationships"][target_id][n]

            if (len(to_remove) == n_relationships):
                del self._properties["_relationships"][target_id]
                self._properties["_relationship_with"].remove(target_id)

            self._committed = False