Stripping CVS keywords
[project/privatemsg.git] / privatemsg.install
CommitLineData
4c08b7c3 1<?php
7318daab
SG
2
3/**
4 * @file
5 * Install file for privatemsg.module
6 */
7
4c08b7c3
OT
8
9function privatemsg_schema() {
10 $schema = array();
11 $schema['pm_index'] = array(
7318daab 12 'description' => '{pm_index} holds indexing information about messages and recepients for fast retrieval',
4c08b7c3 13 'fields' => array(
78db22eb 14 'mid' => array(
7318daab 15 'description' => 'Private Message ID',
4c08b7c3
OT
16 'type' => 'int',
17 'not null' => TRUE,
18 'unsigned' => TRUE,
19 ),
20 'thread_id' => array(
7318daab 21 'description' => 'Messages thread ID',
4c08b7c3
OT
22 'type' => 'int',
23 'not null' => TRUE,
24 'unsigned' => TRUE,
25 ),
44127886
SG
26 'recipient' => array(
27 'description' => 'ID of the recipient object, typically user',
4c08b7c3
OT
28 'type' => 'int',
29 'not null' => TRUE,
30 'unsigned' => TRUE,
31 ),
6ff1ba22 32 'is_new' => array(
7318daab 33 'description' => 'Whether the user has read this message',
ef43588d
OT
34 'type' => 'int',
35 'default' => 1,
36 'not null' => TRUE,
37 'unsigned' => TRUE,
38 ),
d0f4ee87 39 'deleted' => array(
7318daab 40 'description' => 'Whether the user has deleted this message',
d0f4ee87
OT
41 'type' => 'int',
42 'unsigned' => TRUE,
43 'not null' => TRUE,
44 'default' => 0
45 ),
44127886
SG
46 'type' => array(
47 'description' => 'Type of recipient object',
48 'type' => 'varchar',
49 'length' => 255,
50 'not null' => TRUE,
51 'default' => 'user'
52 ),
4c08b7c3 53 ),
20425f54 54 'primary key' => array('mid', 'recipient', 'type'),
4c08b7c3 55 'indexes' => array(
c11a01b2
SG
56 'list' => array('recipient', 'type', 'deleted', 'is_new'),
57 'messages' => array('mid', 'recipient', 'type'),
58 'participants' => array('thread_id', 'recipient', 'type', 'deleted'),
4c08b7c3
OT
59 ),
60 );
7318daab 61
4c08b7c3 62 $schema['pm_message'] = array(
7318daab 63 'description' => '{pm_messages} holds the message information',
4c08b7c3 64 'fields' => array(
78db22eb 65 'mid' => array(
7318daab 66 'description' => 'Private Message ID',
4c08b7c3
OT
67 'type' => 'serial',
68 'not null' => TRUE,
69 'unsigned' => TRUE,
70 ),
71 'author' => array(
7318daab 72 'description' => 'UID of the author',
4c08b7c3
OT
73 'type' => 'int',
74 'not null' => TRUE,
75 'unsigned' => TRUE,
76 ),
77 'subject' => array(
7318daab 78 'description' => 'Subject text of the message',
4c08b7c3
OT
79 'type' => 'varchar',
80 'length' => 255,
81 'not null' => TRUE,
82 ),
83 'body' => array(
7318daab 84 'description' => 'Body of the message',
4c08b7c3
OT
85 'type' => 'text',
86 'not null' => TRUE,
87 'size' => 'big',
88 ),
7318daab
SG
89 'format' => array(
90 'type' => 'int',
91 'size' => 'small',
92 'not null' => TRUE,
93 'default' => FILTER_FORMAT_DEFAULT,
94 'description' => 'The {filter_formats}.format of the message text.',
95 ),
d0f4ee87 96 'timestamp' => array(
7318daab 97 'description' => 'Time when the message was sent',
d0f4ee87
OT
98 'type' => 'int',
99 'not null' => TRUE,
100 'unsigned' => TRUE,
101 ),
4c08b7c3 102 ),
78db22eb 103 'primary key' => array('mid'),
4c08b7c3 104 );
7318daab 105
11992973
SG
106 $schema['pm_disable'] = array(
107 'description' => '{pm_disable} holds the list of users that have disabled private messaging',
108 'fields' => array(
109 'uid' => array(
110 'description' => 'ID of the user',
111 'type' => 'int',
112 'not null' => TRUE,
113 'unsigned' => TRUE,
114 ),
115 ),
116 'primary key' => array('uid'),
117 );
7318daab 118
4c08b7c3
OT
119 return $schema;
120}
11992973 121
4c08b7c3
OT
122function privatemsg_install() {
123 drupal_install_schema('privatemsg');
7318daab 124
4c08b7c3
OT
125}
126
127function privatemsg_uninstall() {
7318daab
SG
128 variable_del('private_message_view_template');
129 variable_del('privatemsg_per_page');
130 variable_del('privatemsg_display_loginmessage');
131 variable_del('privatemsg_display_fields');
dfb93e25 132 variable_del('privatemsg_display_link_self');
7318daab
SG
133 variable_del('privatemsg_view_default_amount');
134 variable_del('privatemsg_view_max_amount');
135 variable_del('privatemsg_view_use_max_as_default');
7452710a
SG
136 variable_del('privatemsg_display_profile_links');
137 variable_del('privatemsg_link_node_types');
138 variable_del('privatemsg_display_on_teaser');
139 variable_del('privatemsg_display_on_comments');
3abe891a 140 variable_del('privatemsg_no_messages_notification');
4c08b7c3
OT
141 drupal_uninstall_schema('privatemsg');
142}
6ff1ba22 143
6ff1ba22
OT
144function privatemsg_update_6000() {
145 // Give update unlimited time to complete.
146 set_time_limit(0);
7318daab 147
6ff1ba22
OT
148 // Update the database schema and transfer data to new tables.
149 $schema = array();
150 $schema['pm_index'] = array(
7318daab 151 'description' => '{pm_index} holds indexing information about messages and recepients for fast retrieval',
6ff1ba22
OT
152 'fields' => array(
153 'mid' => array(
7318daab 154 'description' => 'Private Message ID',
6ff1ba22
OT
155 'type' => 'int',
156 'not null' => TRUE,
157 'unsigned' => TRUE,
158 ),
159 'thread_id' => array(
7318daab 160 'description' => 'Messages thread ID',
6ff1ba22
OT
161 'type' => 'int',
162 'not null' => TRUE,
163 'unsigned' => TRUE,
164 ),
165 'uid' => array(
7318daab 166 'description' => 'UID of either the author or the recipient',
6ff1ba22
OT
167 'type' => 'int',
168 'not null' => TRUE,
169 'unsigned' => TRUE,
170 ),
171 'is_new' => array(
7318daab 172 'description' => 'Whether the user has read this message',
6ff1ba22
OT
173 'type' => 'int',
174 'default' => 1,
175 'not null' => TRUE,
176 'unsigned' => TRUE,
177 ),
178 'deleted' => array(
7318daab 179 'description' => 'Whether the user has deleted this message',
6ff1ba22
OT
180 'type' => 'int',
181 'unsigned' => TRUE,
182 'not null' => TRUE,
183 'default' => 0
184 ),
185
186 ),
187 'indexes' => array(
188 'mid' => array('mid'),
189 'thread_id' => array('thread_id'),
190 'uid' => array('uid'),
7318daab 191 'is_new' => array('mid', 'uid', 'is_new', ),
6ff1ba22
OT
192 ),
193 );
7318daab 194
6ff1ba22 195 $schema['temp_pm_index'] = array(
7318daab 196 'description' => '{pm_index} holds indexing information about messages and recepients for fast retrieval',
6ff1ba22
OT
197 'fields' => array(
198 'mid' => array(
7318daab 199 'description' => 'Private Message ID',
6ff1ba22
OT
200 'type' => 'int',
201 'not null' => TRUE,
202 'unsigned' => TRUE,
203 ),
204 'folder' => array(
7318daab 205 'description' => 'ID of drupal 5 folder',
6ff1ba22
OT
206 'type' => 'int',
207 'not null' => TRUE,
208 'unsigned' => TRUE,
209 ),
210 'thread' => array(
7318daab 211 'description' => 'Messages old thread ID',
6ff1ba22
OT
212 'type' => 'int',
213 'not null' => TRUE,
214 'unsigned' => TRUE,
215 ),
216 'thread_id' => array(
7318daab 217 'description' => 'Messages new thread ID',
6ff1ba22
OT
218 'type' => 'int',
219 'not null' => TRUE,
220 'unsigned' => TRUE,
221 ),
222 'uid' => array(
7318daab 223 'description' => 'UID of either the author or the recipient',
6ff1ba22
OT
224 'type' => 'int',
225 'not null' => TRUE,
226 'unsigned' => TRUE,
227 ),
228 'is_new' => array(
7318daab 229 'description' => 'Whether the user has read this message',
6ff1ba22
OT
230 'type' => 'int',
231 'default' => 1,
232 'not null' => TRUE,
233 'unsigned' => TRUE,
234 ),
235 'deleted' => array(
7318daab 236 'description' => 'Whether the user has deleted this message',
6ff1ba22
OT
237 'type' => 'int',
238 'unsigned' => TRUE,
239 'not null' => TRUE,
240 'default' => 0
241 ),
242 ),
243 );
7318daab 244
6ff1ba22 245 $schema['pm_message'] = array(
7318daab 246 'description' => '{pm_messages} holds the message information',
6ff1ba22
OT
247 'fields' => array(
248 'mid' => array(
7318daab 249 'description' => 'Private Message ID',
6ff1ba22
OT
250 'type' => 'serial',
251 'not null' => TRUE,
252 'unsigned' => TRUE,
253 ),
254 'author' => array(
7318daab 255 'description' => 'UID of the author',
6ff1ba22
OT
256 'type' => 'int',
257 'not null' => TRUE,
258 'unsigned' => TRUE,
259 ),
260 'subject' => array(
7318daab 261 'description' => 'Subject text of the message',
6ff1ba22
OT
262 'type' => 'varchar',
263 'length' => 255,
264 'not null' => TRUE,
265 ),
266 'body' => array(
7318daab 267 'description' => 'Body of the message',
6ff1ba22
OT
268 'type' => 'text',
269 'not null' => TRUE,
270 'size' => 'big',
271 ),
272 'timestamp' => array(
7318daab 273 'description' => 'Time when the message was sent',
6ff1ba22
OT
274 'type' => 'int',
275 'not null' => TRUE,
276 'unsigned' => TRUE,
277 ),
278 ),
279 'primary key' => array('mid'),
280 'indexes' => array(
281 'author' => array('author'),
282 'subject' => array(array('subject', 20)),
283 'timestamp' => array('timestamp'),
284 ),
285 );
286 $ret = array();
7318daab
SG
287
288 // Step 1: Preparation
289 // Create the privatemsg tables.
6ff1ba22
OT
290 if (!(db_table_exists('pm_message'))) {
291 db_create_table($ret, 'pm_message', $schema['pm_message']);
292 }
293 if (!(db_table_exists('pm_index'))) {
294 db_create_table($ret, 'pm_index', $schema['pm_index']);
295 }
296 if (!(db_table_exists('temp_pm_index'))) {
297 db_create_table($ret, 'temp_pm_index', $schema['temp_pm_index']);
298 }
7318daab
SG
299 // Enable the privatemsg module as otherwise the enable box will be unclickable after update.
300 if (!module_exists('privatemsg')) {
301 module_enable('privatemsg');
302 }
303
304 // Install relevant submodules as we need theit tables to drop the data into.
6ff1ba22 305 $modules = array();
7318daab 306 if (!(module_exists('privatemsg_filter'))) {
6ff1ba22
OT
307 $modules[] = 'privatemsg_filter';
308 }
7318daab 309 if (!(module_exists('pm_block_user'))) {
6ff1ba22
OT
310 $modules[] = 'pm_block_user';
311 }
312 if (count($modules) > 0) {
313 drupal_install_modules($modules);
314 }
7318daab 315
6ff1ba22 316 // Step 2: Get the data
7318daab 317
6ff1ba22
OT
318 // Step 2a: get the folder/tagging data first.
319 if (db_table_exists('privatemsg_folder')) {
320 $data = db_query("SELECT * FROM {privatemsg_folder}");
321 while ($result = db_fetch_array($data)) {
7318daab
SG
322 if (db_result(db_query("SELECT COUNT(*) FROM {pm_tags} WHERE tag = '%s'", $result['name'])) == 0) {
323 db_query("INSERT INTO {pm_tags} (tag) VALUES ('%s')", $result['name']);
6ff1ba22
OT
324 }
325 }
326 }
7318daab
SG
327
328 // Step 2b: Next, copy the user blocking data.
6ff1ba22
OT
329 if (db_table_exists('privatemsg_block_user')) {
330 $data = db_query("SELECT * FROM {privatemsg_block_user}");
331 while ($result = db_fetch_array($data)) {
332 db_query("INSERT INTO {pm_block_user} (author, recipient) VALUES ( %d, %d )", $result['author'], $result['recipient']);
333 }
334 }
7318daab
SG
335
336 // Step 2c: Next the data from the archive table - notice all these messages have been deleted both by the author and the recipient.
6ff1ba22
OT
337 if (db_table_exists('privatemsg_archive')) {
338 $data = db_query("SELECT * FROM {privatemsg_archive}");
339 while ($result = db_fetch_array($data)) {
340 if ($result['thread'] == 0) {
341 $result['thread_id'] = $result['id'];
342 }
343 else{
344 $result['thread_id'] = 0;
345 }
346 if ($result['author'] <> $result['recipient']) {
347 db_query("INSERT INTO {pm_message} (mid, author, subject, body, timestamp) VALUES ( %d, %d, '%s', '%s', %d )", $result['id'], $result['author'], $result['subject'], $result['message'], $result['timestamp']);
348 db_query("INSERT INTO {temp_pm_index} (mid, thread, folder, thread_id, uid, is_new, deleted) VALUES ( %d, %d, %d, %d, %d, %d, %d )", $result['id'], $result['thread'], $result['folder'], $result['thread_id'], $result['recipient'], 0, 1);
349 }
350 db_query("INSERT INTO {temp_pm_index} (mid, thread, folder, thread_id, uid, is_new, deleted) VALUES ( %d, %d, %d, %d, %d, %d, %d )", $result['id'], $result['thread'], 0, $result['thread_id'], $result['author'], 0, 1);
351 }
352 }
353
7318daab 354 // Step 2d: Finally, get the data from the privatemsg table.
6ff1ba22
OT
355 if (db_table_exists('privatemsg')) {
356 $data = db_query("SELECT * FROM {privatemsg}");
357 while ($result = db_fetch_array($data)) {
358 if ($result['thread'] == 0) {
359 $result['thread_id'] = $result['id'];
360 }
361 else{
362 $result['thread_id'] = 0;
363 }
364 if ($result['author'] <> $result['recipient']) {
365 db_query("INSERT INTO {pm_message} (mid, author, subject, body, timestamp) VALUES ( %d, %d, '%s', '%s', %d )", $result['id'], $result['author'], $result['subject'], $result['message'], $result['timestamp']);
366 db_query("INSERT INTO {temp_pm_index} (mid, thread, folder, thread_id, uid, is_new, deleted) VALUES ( %d, %d, %d, %d, %d, %d, %d )", $result['id'], $result['thread'], $result['folder'], $result['thread_id'], $result['recipient'], $result['newmsg'], $result['recipient_del']);
367 }
368 db_query("INSERT INTO {temp_pm_index} (mid, thread, folder, thread_id, uid, is_new, deleted) VALUES ( %d, %d, %d, %d, %d, %d, %d )", $result['id'], $result['thread'], 0, $result['thread_id'], $result['author'], 0, $result['author_del']);
369 }
370 }
7318daab 371
6ff1ba22
OT
372 // Step 3: Process the Data.
373 // Step 3a: Fix the thread data.
374 $data = db_query("SELECT thread, MIN(mid) as new_thread FROM {temp_pm_index} WHERE thread_id = %d GROUP BY thread", 0);
375 while ($result = db_fetch_array($data)) {
376 db_query("UPDATE {temp_pm_index} SET thread_id = %d WHERE thread = %d", $result['new_thread'], $result['thread']);
377 }
7318daab 378
6ff1ba22
OT
379 // Step 3b: Fix and import the tagging data.
380 $data = db_query("SELECT thread_id, folder, uid FROM {temp_pm_index} WHERE folder <> %d", 0);
381 while ($result = db_fetch_array($data)) {
7318daab
SG
382 $tag_id = db_result(db_query('SELECT pmt.tag_id FROM {pm_tags} pmt INNER JOIN {privatemsg_folder} pmf ON pmt.tag = pmf.name WHERE pmf.fid = %d', $result['folder']));
383 if (db_result(db_query("SELECT COUNT(*) FROM {pm_tags_index} WHERE uid = %d AND (thread_id = %d AND tag_id = %d)", $result['uid'], $result['thread_id'], $tag_id)) == 0) {
384 db_query("INSERT INTO {pm_tags_index} (uid, tag_id, thread_id) VALUES (%d, %d, %d)", $result['uid'], $tag_id, $result['thread_id']);
6ff1ba22
OT
385 }
386 }
7318daab 387
6ff1ba22
OT
388 // Step 3c: Copy the index data.
389 $data = db_query("SELECT * FROM {temp_pm_index}");
390 while ($result = db_fetch_array($data)) {
391 db_query("INSERT INTO {pm_index} (mid, thread_id, uid, is_new, deleted) VALUES ( %d, %d, %d, %d, %d )", $result['mid'], $result['thread_id'], $result['uid'], $result['is_new'], $result['deleted']);
392 }
7318daab 393
6ff1ba22
OT
394 // Step 4: Clean up.
395 db_drop_table($ret, 'privatemsg');
396 db_drop_table($ret, 'privatemsg_archive');
397 db_drop_table($ret, 'privatemsg_folder');
7318daab
SG
398 if (db_table_exists('privatemsg_block_user')) {
399 db_drop_table($ret, 'privatemsg_block_user');
400 }
6ff1ba22 401 db_drop_table($ret, 'temp_pm_index');
7318daab
SG
402
403 return $ret;
404}
405
406function privatemsg_update_6001() {
407 $ret = array();
408
409 if (!db_column_exists('pm_index', 'is_new')) {
410
411 if (db_column_exists('pm_index', 'new')) {
412 $old_column = 'new';
413 }
414 elseif (db_column_exists('pm_index', 'new_flag')) {
415 $old_column = 'new_flag';
416 }
417 else {
418 return $ret;
419 }
420
421 db_drop_index($ret, 'pm_index', $old_column);
422 db_change_field($ret, 'pm_index', $old_column, 'is_new', array(
423 'description' => 'Whether the user has read this message',
424 'type' => 'int',
425 'default' => 1,
426 'not null' => TRUE,
427 'unsigned' => TRUE));
428 db_add_index($ret, 'pm_index', 'is_new', array('mid', 'uid', 'is_new'));
429 }
430
431 return $ret;
432}
433
434function privatemsg_update_6002() {
435 $ret = array();
436 // update_sql does not support parameters, we need to use db_query
437 $sql = "UPDATE {blocks} SET cache = %d WHERE module='privatemsg'";
438 $result = db_query($sql, BLOCK_NO_CACHE);
439 $ret[] = array('success' => $result !== FALSE, 'query' => check_plain($sql));
440 return $ret;
441}
442
443/**
444 * Update function to resolve "forever new" messages.
11992973 445 *
7318daab
SG
446 * As described in http://drupal.org/node/490650
447 */
448function privatemsg_update_6003() {
449 $ret = array();
450 // Find messages that have aformentioned problem
451 $sql = "SELECT DISTINCT p1.mid, p1.uid FROM {pm_index} p1 INNER JOIN {pm_index} p2 ON p1.thread_id = p2.thread_id AND p1.mid = p2.mid INNER JOIN {pm_message} pm ON p1.uid = pm.author AND p2.uid = pm.author WHERE p1.is_new <> p2.is_new";
452 $result = db_query($sql);
453 while ($row = db_fetch_object($result)) {
454 privatemsg_message_change_status($row->mid, PRIVATEMSG_READ, $row );
455 }
456 $ret[] = array('success' => $result !== FALSE, 'query' => check_plain($sql));
457 return $ret;
458}
459
460/**
461 * Create a format column.
462 *
463 * Copied from system_update_6051
464 */
465function privatemsg_update_6004() {
466 $ret = array();
467 if (!db_column_exists('pm_message', 'format')) {
468 $schema = array(
469 'type' => 'int',
470 'size' => 'small',
471 'not null' => TRUE,
472 'default' => FILTER_FORMAT_DEFAULT,
473 'description' => 'The {filter_formats}.format of the message text.',
474 );
475
476 db_add_field($ret, 'pm_message', 'format', $schema);
477
478 // Set the format of existing signatures to the current default input format.
479 if ($current_default_filter = (int)variable_get('filter_default_format', 1)) {
480 $ret[] = update_sql("UPDATE {pm_message} SET format = ". $current_default_filter);
481 }
482 }
483 return $ret;
484}
485
486/**
487 * Enable delete permission for all users that are allowed to read them.
488 */
489function privatemsg_update_6005() {
490 $ret = array();
491 $ret[] = update_sql("UPDATE {permission} SET perm = REPLACE(perm, 'read privatemsg', 'read privatemsg, delete privatemsg') WHERE perm LIKE '%read privatemsg%'");
492 return $ret;
493}
494
495/**
496 * Set the deleted timestamp of all messages to now.
497 */
498function privatemsg_update_6006() {
499 $ret = array();
500
501 $sql = "UPDATE {pm_index} SET deleted = %d WHERE deleted = 1";
502 $result = db_query($sql, time());
503 $ret[] = array('success' => $result !== FALSE, 'query' => check_plain($sql));
6ff1ba22 504 return $ret;
11992973
SG
505}
506
507/**
508 * Add {pm_disable} table.
509 */
55290827 510function privatemsg_update_6200() {
11992973
SG
511 $ret = array();
512
513 $schema['pm_disable'] = array(
514 'description' => '{pm_disable} holds the list of users that have disabled private messaging',
515 'fields' => array(
516 'uid' => array(
517 'description' => 'ID of the user',
518 'type' => 'int',
519 'not null' => TRUE,
520 'unsigned' => TRUE,
521 ),
522 ),
523 'primary key' => array('uid'),
524 );
525
526 if (!(db_table_exists('pm_disable'))) {
527 db_create_table($ret, 'pm_disable', $schema['pm_disable']);
528 }
529
530 return $ret;
531}
44127886
SG
532
533/**
534 * Change schema to allow other recipients than single users.
535 */
55290827 536function privatemsg_update_6201() {
44127886 537 $ret = array();
55290827
SG
538
539 // Make sure to not run this update twice.
540 if (db_column_exists('pm_index', 'recipient')) {
541 return $ret;
542 }
c11a01b2
SG
543 db_drop_index($ret, 'pm_index', 'list');
544 db_drop_index($ret, 'pm_index', 'messages');
545 db_drop_index($ret, 'pm_index', 'participants');
44127886
SG
546 db_change_field($ret, 'pm_index', 'uid', 'recipient', array(
547 'description' => 'ID of the recipient object, typically user',
548 'type' => 'int',
549 'not null' => TRUE,
550 'unsigned' => TRUE,
551 ));
552 db_add_field($ret, 'pm_index', 'type', array(
c11a01b2
SG
553 'description' => 'Type of recipient object',
554 'type' => 'varchar',
555 'not null' => TRUE,
556 'length' => '255',
557 'default' => 'user'
558 ), array(
559 'indexes' => array(
560 'list' => array('recipient', 'type', 'deleted', 'is_new'),
561 'messages' => array('mid', 'recipient', 'type'),
562 'participants' => array('thread_id', 'recipient', 'type', 'deleted'),
563 ),
564 ));
44127886
SG
565 return $ret;
566}
20425f54
SG
567
568/**
569 * Remove duplicate entries in {pm_index}.
570 */
55290827 571function privatemsg_update_6202(&$sandbox) {
20425f54
SG
572 // First run, initialize sandbox and check if we are ready to run.
573 if (!isset($sandbox['current_thread_id'])) {
574 // If privatemsg_filter is enabled, check if the updates that add the Inbox
575 // tag did already run to make it possible to tag messages users sent to
576 // themself.
577 // We cannot detect if privatemsg_filter_update_6004 has been run, so we
578 // assume that 6004 has been run if 6003 has been.
579 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))))) {
580 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);
581 $ret['#abort'] = array('success' => FALSE, 'query' => t('Some updates are still pending.<br/>Please re-run the update script.'));
582 return $ret;
583 }
584
585 $sandbox['current_thread_id'] = 0;
586 // Assume that the thread ids are distributed more or less equally over the
587 // whole data set. This allows us to calculate the approximate progress.
588 $sandbox['max'] = db_result(db_query('SELECT MAX(thread_id) FROM {pm_index}'));
589 }
590
591 // Fetch the 10 next thread_ids.
592 $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);
593 $threads = array();
594 while ($row = db_fetch_object($result)) {
595 $threads[] = $row->thread_id;
596 }
597
598 if (!empty($threads)) {
599 // By limiting this slow query (having condition) on a specific set of
600 // threads, this allows us to process the slow having part on a relatively
601 // small subset of pm_index that can be selected based on the thread_id
602 // index. There might also be cases where is_new and/or deleted are not
603 // equal, use MAX(is_new) and MIN(deleted) for these cases.
604 $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';
605 $result = db_query($sql, $threads);
606 while ($row = db_fetch_object($result)) {
607 // Delete all occurences of these entries.
608 db_query("DELETE FROM {pm_index} WHERE mid = %d AND recipient = %d AND type = '%s'", $row->mid, $row->recipient, $row->type);
609 // Re-insert a single entry. We do this to explicitely keep messages
610 // unread and undeleted if there are conflicting entries.
4482ff57 611 db_query('INSERT INTO {pm_index} (mid, thread_id, recipient, type, is_new, deleted) VALUES (%d, %d, %d, %d, %d, %d)', $row->mid, $row->thread_id, $row->recipient, $row->type, $row->is_new, $row->deleted);
20425f54
SG
612 }
613 $sandbox['current_thread_id'] = max($threads);
614 }
615 // Set #finished based on sandbox.
616 $ret['#finished'] = empty($sandbox['max']) ? 1 : ($sandbox['current_thread_id'] / $sandbox['max']);
617 return $ret;
618}
619
620/**
621 * Add primary key to {pm_index}.
622 */
55290827 623function privatemsg_update_6203() {
20425f54 624 $ret = array();
c11a01b2
SG
625 if (!privatemsg_db_index_exists('pm_index', 'PRIMARY')) {
626 db_add_primary_key($ret, 'pm_index', array('mid', 'recipient', 'type'));
55290827 627 }
20425f54
SG
628 return $ret;
629}
c11a01b2
SG
630
631/**
632 * Update indexes for 6.x-2.x instances.
633 */
634function privatemsg_update_6204() {
635 $ret = array();
636
637 // Remove whatever old indexes are on the tables.
638 $old = array(
639 'pm_index' => array('mid', 'thread_id', 'recipient', 'is_new'),
640 'pm_message' => array('author', 'subject', 'timestamp'),
641 );
642 foreach ($old as $table => $indexes) {
643 foreach ($indexes as $name) {
644 if (privatemsg_db_index_exists($table, $name)) {
645 db_drop_index($ret, $table, $name);
646 }
647 }
648 }
649
650 $new = array(
651 'list' => array('recipient', 'type', 'deleted', 'is_new'),
652 'messages' => array('mid', 'recipient', 'type'),
653 'participants' => array('thread_id', 'recipient', 'type', 'deleted'),
654 );
655 foreach ($new as $name => $fields) {
656 if (!privatemsg_db_index_exists('pm_index', $name)) {
657 db_add_index($ret, 'pm_index', $name, $fields);
658 }
659 }
660
661 return $ret;
662}
663
664/**
665 * Checks if an index exists in the given table.
666 *
667 * @param $table
668 * The name of the table in drupal (no prefixing).
669 * @param $name
670 * The name of the index in drupal (no prefixing).
671 *
672 * @return
673 * TRUE if the given index exists, otherwise FALSE.
674 */
675function privatemsg_db_index_exists($table, $name) {
676 global $db_type;
677
678 if ($db_type == 'pgsql') {
679 $index_name = '{' . $table . '}_' . $name . '_idx';
680 return (bool) db_result(db_query("SELECT 1 FROM pg_indexes WHERE indexname = '$index_name'"));
681 }
682 else {
683 return (bool)db_fetch_array(db_query('SHOW INDEX FROM {' . $table . "} WHERE key_name = '$name'"));
684 }
685}