/**
* Updates rows in given table from a set of values to a new value.
* If this results in rows violating uniqueness constraints, the duplicate
* rows are merged respecting notify_status (0 takes precedence over 1).
*
* The only supported table is topics_watch.
*
* @param dbal $db Database object
* @param string $table Table on which to perform the update
* @param string $column Column whose values to change
* @param array $from_values An array of values that should be changed
* @param int $to_value The new value
* @return null
*/
function phpbb_update_rows_avoiding_duplicates_notify_status($db, $table, $column, $from_values, $to_value)
{
    $sql = "SELECT {$column}, user_id, notify_status\n\t\tFROM {$table}\n\t\tWHERE " . $db->sql_in_set($column, $from_values);
    $result = $db->sql_query($sql);
    $old_user_ids = array();
    while ($row = $db->sql_fetchrow($result)) {
        $old_user_ids[(int) $row['notify_status']][$row[$column]][] = (int) $row['user_id'];
    }
    $db->sql_freeresult($result);
    $sql = "SELECT {$column}, user_id\n\t\tFROM {$table}\n\t\tWHERE {$column} = " . (int) $to_value;
    $result = $db->sql_query($sql);
    $new_user_ids = array();
    while ($row = $db->sql_fetchrow($result)) {
        $new_user_ids[$row[$column]][] = (int) $row['user_id'];
    }
    $db->sql_freeresult($result);
    $queries = array();
    $extra_updates = array(0 => 'notify_status = 0', 1 => '');
    foreach ($from_values as $from_value) {
        foreach ($extra_updates as $notify_status => $extra_update) {
            if (!isset($old_user_ids[$notify_status][$from_value])) {
                continue;
            }
            if (empty($new_user_ids)) {
                $sql = "UPDATE {$table}\n\t\t\t\t\tSET {$column} = " . (int) $to_value . "\n\t\t\t\t\tWHERE {$column} = '" . $db->sql_escape($from_value) . "'";
                $queries[] = $sql;
            } else {
                $different_user_ids = array_diff($old_user_ids[$notify_status][$from_value], $new_user_ids[$to_value]);
                if (!empty($different_user_ids)) {
                    $sql = "UPDATE {$table}\n\t\t\t\t\t\tSET {$column} = " . (int) $to_value . "\n\t\t\t\t\t\tWHERE {$column} = '" . $db->sql_escape($from_value) . "'\n\t\t\t\t\t\tAND " . $db->sql_in_set('user_id', $different_user_ids);
                    $queries[] = $sql;
                }
                if ($extra_update) {
                    $same_user_ids = array_diff($old_user_ids[$notify_status][$from_value], $different_user_ids);
                    if (!empty($same_user_ids)) {
                        $sql = "UPDATE {$table}\n\t\t\t\t\t\t\tSET {$extra_update}\n\t\t\t\t\t\t\tWHERE {$column} = '" . (int) $to_value . "'\n\t\t\t\t\t\t\tAND " . $db->sql_in_set('user_id', $same_user_ids);
                        $queries[] = $sql;
                    }
                }
            }
        }
    }
    if (!empty($queries)) {
        $db->sql_transaction('begin');
        foreach ($queries as $sql) {
            $db->sql_query($sql);
        }
        $sql = "DELETE FROM {$table}\n\t\t\tWHERE " . $db->sql_in_set($column, $from_values);
        $db->sql_query($sql);
        $db->sql_transaction('commit');
    }
}