function privatemsg_update_6202 in Privatemsg 6.2
Remove duplicate entries in {pm_index}.
File
- ./
privatemsg.install, line 601 - Install file for privatemsg.module
Code
function privatemsg_update_6202(&$sandbox) {
// First run, initialize sandbox and check if we are ready to run.
if (!isset($sandbox['current_thread_id'])) {
// If privatemsg_filter is enabled, check if the updates that add the Inbox
// tag did already run to make it possible to tag messages users sent to
// themself.
// We cannot detect if privatemsg_filter_update_6004 has been run, so we
// assume that 6004 has been run if 6003 has been.
if (module_exists('privatemsg_filter') && (!($tag_id = variable_get('privatemsg_filter_inbox_tag', '')) || !db_result(db_query('SELECT 1 FROM {pm_tags} WHERE tag_id = %d', $tag_id)))) {
drupal_set_message(t('Some updates are still pending. Please return to <a href="@update-php">update.php</a> and run the remaining updates.', array(
'@update-php' => base_path() . 'update.php?op=selection',
)), 'error', FALSE);
$ret['#abort'] = array(
'success' => FALSE,
'query' => t('Some updates are still pending.<br/>Please re-run the update script.'),
);
return $ret;
}
$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_result(db_query('SELECT MAX(thread_id) FROM {pm_index}'));
}
// Fetch the 10 next thread_ids.
$result = db_query_range('SELECT DISTINCT thread_id FROM {pm_index} WHERE thread_id > %d ORDER BY thread_id ASC', $sandbox['current_thread_id'], 0, 20);
$threads = array();
while ($row = db_fetch_object($result)) {
$threads[] = $row->thread_id;
}
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 (' . db_placeholders($threads) . ') GROUP BY pmi.recipient, pmi.type, pmi.mid, pmi.thread_id HAVING COUNT(*) > 1';
$result = db_query($sql, $threads);
while ($row = db_fetch_object($result)) {
// Delete all occurences of these entries.
db_query("DELETE FROM {pm_index} WHERE mid = %d AND recipient = %d AND type = '%s'", $row->mid, $row->recipient, $row->type);
// Re-insert a single entry. We do this to explicitely keep messages
// unread and undeleted if there are conflicting entries.
db_query('INSERT INTO {pm_index} (mid, thread_id, recipient, type, is_new, deleted) VALUES (%d, %d, %d, "%s", %d, %d)', $row->mid, $row->thread_id, $row->recipient, $row->type, $row->is_new, $row->deleted);
}
$sandbox['current_thread_id'] = max($threads);
}
// Set #finished based on sandbox.
$ret['#finished'] = empty($sandbox['max']) ? 1 : $sandbox['current_thread_id'] / $sandbox['max'];
return $ret;
}