def delete_bundles(self, uuids): ''' Delete bundles with the given uuids. ''' self._check_not_running(uuids) with self.engine.begin() as connection: # We must delete bundles rows in the opposite order that we create them # to avoid foreign-key constraint failures. connection.execute(cl_worksheet_item.delete().where( cl_worksheet_item.c.bundle_uuid.in_(uuids) )) connection.execute(cl_bundle_metadata.delete().where( cl_bundle_metadata.c.bundle_uuid.in_(uuids) )) connection.execute(cl_bundle_dependency.delete().where( cl_bundle_dependency.c.child_uuid.in_(uuids) )) connection.execute(cl_bundle.delete().where( cl_bundle.c.uuid.in_(uuids) ))
def delete_bundle_tree(self, uuids, force=False): ''' Delete bundles with the given uuids and all bundles that are (direct or indirect) descendents of them. If force is False, there should be no descendents of the given bundles. ''' children = self.get_children(uuid=uuids) if children: precondition(force, 'Bundles depend on %s:\n %s' % ( self.get_bundle(uuids[0]), '\n '.join(str(child) for child in children), )) self.delete_bundle_tree([child.uuid for child in children], force=True) with self.engine.begin() as connection: # We must delete bundles rows in the opposite order that we create them # to avoid foreign-key constraint failures. connection.execute(cl_bundle_metadata.delete().where( cl_bundle_metadata.c.bundle_uuid.in_(uuids) )) connection.execute(cl_bundle_dependency.delete().where( cl_bundle_dependency.c.child_uuid.in_(uuids) )) connection.execute(cl_bundle.delete().where(cl_bundle.c.uuid.in_(uuids)))
def update_bundle(self, bundle, update): ''' Update a bundle's columns and metadata in the database and in memory. The update is done as a diff: columns that do not appear in the update dict and metadata keys that do not appear in the metadata sub-dict are unaffected. This method validates all updates to the bundle, so it is appropriate to use this method to update bundles based on user input (eg: cl edit). ''' message = 'Illegal update: %s' % (update,) precondition('id' not in update and 'uuid' not in update, message) # Apply the column and metadata updates in memory and validate the result. metadata_update = update.pop('metadata', {}) bundle.update_in_memory(update) for (key, value) in metadata_update.iteritems(): bundle.metadata.set_metadata_key(key, value) bundle.validate() # Construct clauses and update lists for updating certain bundle columns. if update: clause = cl_bundle.c.uuid == bundle.uuid if metadata_update: metadata_clause = and_( cl_bundle_metadata.c.bundle_uuid == bundle.uuid, cl_bundle_metadata.c.metadata_key.in_(metadata_update) ) metadata_values = [ row_dict for row_dict in bundle.to_dict().pop('metadata') if row_dict['metadata_key'] in metadata_update ] # Perform the actual updates. with self.engine.begin() as connection: if update: connection.execute(cl_bundle.update().where(clause).values(update)) if metadata_update: connection.execute(cl_bundle_metadata.delete().where(metadata_clause)) self.do_multirow_insert(connection, cl_bundle_metadata, metadata_values)