Esempio n. 1
0
/**
 * This method can update the values in mulitple database rows for a colum with
 * a unique index, without violating that constraint.
 *
 * Suppose we have a table with a unique index on (otherid, sortorder), and
 * for a particular value of otherid, we want to change all the sort orders.
 * You have to do this carefully or you will violate the unique index at some time.
 * This method takes care of the details for you.
 *
 * Note that, it is the responsibility of the caller to make sure that the
 * requested rename is legal. For example, if you ask for [1 => 2, 2 => 2]
 * then you will get a unique key violation error from the database.
 *
 * @param string $table The database table to modify.
 * @param string $field the field that contains the values we are going to change.
 * @param array $newvalues oldvalue => newvalue how to change the values.
 *      E.g. [1 => 4, 2 => 1, 3 => 3, 4 => 2].
 * @param array $otherconditions array fieldname => requestedvalue extra WHERE clause
 *      conditions to restrict which rows are affected. E.g. array('otherid' => 123).
 * @param int $unusedvalue (defaults to -1) a value that is never used in $ordercol.
 */
function update_field_with_unique_index($table, $field, array $newvalues, array $otherconditions, $unusedvalue = -1)
{
    global $DB;
    $safechanges = decompose_update_into_safe_changes($newvalues, $unusedvalue);
    $transaction = $DB->start_delegated_transaction();
    foreach ($safechanges as $change) {
        list($from, $to) = $change;
        $otherconditions[$field] = $from;
        $DB->set_field($table, $field, $to, $otherconditions);
    }
    $transaction->allow_commit();
}
 public function test_decompose_update_into_safe_changes_string_values()
 {
     // Sometimes this happens when data has been loaded from the database.
     $this->assertEquals(array(array(1, -1), array(2, 1), array(3, 2), array(4, 3), array(-1, 4)), decompose_update_into_safe_changes(array(1 => '4', 2 => '1', 3 => '2', 4 => '3'), -1));
 }