Example #1
0
    def update_worksheet(self, worksheet_uuid, last_item_id, length, new_items):
        '''
        Updates the worksheet with the given uuid. If there were exactly
        `last_length` items with database id less than `last_id`, replaces them all
        with the items in new_items. Does NOT affect items in this worksheet with
        database id greater than last_id.

        Does NOT affect items that were added to the worksheet in between the
        time it was retrieved and it was updated.

        If this worksheet were updated between the time it was retrieved and
        updated, this method will raise a UsageError.
        '''
        clause = and_(
          cl_worksheet_item.c.worksheet_uuid == worksheet_uuid,
          cl_worksheet_item.c.id <= last_item_id,
        )
        # See codalab.objects.worksheet for an explanation of the sort_key protocol.
        # We need to produce sort keys here that are strictly upper-bounded by the
        # last known item id in this worksheet, and which monotonically increase.
        # The expression last_item_id + i - len(new_items) works. It can produce
        # negative sort keys, but that's fine.
        new_item_values = [{
          'worksheet_uuid': worksheet_uuid,
          'bundle_uuid': bundle_uuid,
          'value': value,
          'sort_key': (last_item_id + i - len(new_items)),
        } for (i, (bundle_uuid, value)) in enumerate(new_items)]
        with self.engine.begin() as connection:
            result = connection.execute(cl_worksheet_item.delete().where(clause))
            message = 'Found extra items for worksheet %s' % (worksheet_uuid,)
            precondition(result.rowcount <= length, message)
            if result.rowcount < length:
                raise UsageError('Worksheet %s was updated concurrently!' % (worksheet_uuid,))
            self.do_multirow_insert(connection, cl_worksheet_item, new_item_values)
Example #2
0
 def delete_worksheet(self, worksheet_uuid):
     '''
     Delete the worksheet with the given uuid.
     '''
     with self.engine.begin() as connection:
         connection.execute(cl_group_object_permission.delete().\
             where(cl_group_object_permission.c.object_uuid == worksheet_uuid)
         )
         connection.execute(cl_worksheet_item.delete().where(
           cl_worksheet_item.c.worksheet_uuid == worksheet_uuid
         ))
         connection.execute(cl_worksheet_item.delete().where(
           cl_worksheet_item.c.subworksheet_uuid == worksheet_uuid
         ))
         connection.execute(cl_worksheet.delete().where(
           cl_worksheet.c.uuid == worksheet_uuid
         ))
Example #3
0
 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)
         ))