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__)
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__)
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)
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)
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)
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)
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)
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)
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)
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)
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
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)
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