function privatemsg_update_7004 in Privatemsg 7
Same name and namespace in other branches
- 7.2 privatemsg.install \privatemsg_update_7004()
Remove duplicate entries in {pm_index}.
File
- ./
privatemsg.install, line 269 - Install file for privatemsg.module
Code
function privatemsg_update_7004(&$sandbox) {
// If the primary key already exists, this doesn't need to run.
if (db_index_exists('pm_index', 'PRIMARY')) {
return;
}
// First run, initialize sandbox and check if we are ready to run.
if (!isset($sandbox['current_thread_id'])) {
$sandbox['current_thread_id'] = 0;
// Assume that the thread ids are distributed more or less equally over the
// whole data set. This allows us to calculate the approximate progress.
$sandbox['max'] = db_query('SELECT MAX(thread_id) FROM {pm_index}')
->fetchField();
}
// Fetch the next 10 thread_ids.
$result = db_query_range('SELECT DISTINCT thread_id FROM {pm_index} WHERE thread_id > :thread_id ORDER BY thread_id ASC', 0, 20, array(
':thread_id' => $sandbox['current_thread_id'],
));
$threads = $result
->fetchCol();
if (!empty($threads)) {
// By limiting this slow query (having condition) on a specific set of
// threads, this allows us to process the slow having part on a relatively
// small subset of pm_index that can be selected based on the thread_id
// index. There might also be cases where is_new and/or deleted are not
// equal, use MAX(is_new) and MIN(deleted) for these cases.
$sql = 'SELECT COUNT(*) AS count, pmi.recipient, pmi.type, pmi.mid, pmi.thread_id, MAX(pmi.is_new) As is_new, MIN(pmi.deleted) AS deleted FROM {pm_index} pmi WHERE thread_id IN (:threads) GROUP BY pmi.recipient, pmi.type, pmi.mid, pmi.thread_id HAVING COUNT(*) > 1';
$result = db_query($sql, array(
':threads' => $threads,
));
foreach ($result as $row) {
// Delete all occurrences of these entries.
db_delete('pm_index')
->condition('mid', $row->mid)
->condition('recipient', $row->recipient)
->condition('type', $row->type)
->execute();
// Re-insert a single entry. We do this to explicitly keep messages
// unread and undeleted if there are conflicting entries.
db_insert('pm_index')
->fields(array(
'mid' => $row->mid,
'thread_id' => $row->thread_id,
'recipient' => $row->recipient,
'type' => $row->type,
'is_new' => $row->is_new,
'deleted' => $row->deleted,
))
->execute();
}
$sandbox['current_thread_id'] = max($threads);
}
// Set #finished based on sandbox.
$sandbox['#finished'] = empty($sandbox['max']) ? 1 : $sandbox['current_thread_id'] / $sandbox['max'];
}