Follow-up r72827: do_image_index_update() is also unused since r11360
[lhc/web/wiklou.git] / maintenance / updaters.inc
1 <?php
2 /**
3 * @file
4 * @ingroup Maintenance
5 */
6
7 if ( !defined( 'MEDIAWIKI' ) ) {
8 echo "This file is not a valid entry point\n";
9 exit( 1 );
10 }
11
12 function archive( $name ) {
13 return DatabaseBase::patchPath( $name );
14 }
15
16 function do_interwiki_update() {
17 # Check that interwiki table exists; if it doesn't source it
18 global $IP;
19 $dbw = wfGetDB( DB_MASTER );
20 if ( $dbw->tableExists( "interwiki" ) ) {
21 wfOut( "...already have interwiki table\n" );
22 return true;
23 }
24 wfOut( "Creating interwiki table: " );
25 $dbw->sourceFile( archive( "patch-interwiki.sql" ) );
26 wfOut( "ok\n" );
27 wfOut( "Adding default interwiki definitions: " );
28 $dbw->sourceFile( "$IP/maintenance/interwiki.sql" );
29 wfOut( "ok\n" );
30 }
31
32 function do_index_update() {
33 # Check that proper indexes are in place
34 $dbw = wfGetDB( DB_MASTER );
35 $meta = $dbw->fieldInfo( "recentchanges", "rc_timestamp" );
36 if ( !$meta->isMultipleKey() ) {
37 wfOut( "Updating indexes to 20031107: " );
38 $dbw->sourceFile( archive( "patch-indexes.sql" ) );
39 wfOut( "ok\n" );
40 return true;
41 }
42 wfOut( "...indexes seem up to 20031107 standards\n" );
43 return false;
44 }
45
46 function do_image_name_unique_update() {
47 $dbw = wfGetDB( DB_MASTER );
48 if ( $dbw->indexExists( 'image', 'PRIMARY' ) ) {
49 wfOut( "...image primary key already set.\n" );
50 } else {
51 wfOut( "Making img_name the primary key... " );
52 $dbw->sourceFile( archive( "patch-image_name_primary.sql" ) );
53 wfOut( "ok\n" );
54 }
55 }
56
57 function do_watchlist_update() {
58 $dbw = wfGetDB( DB_MASTER );
59 if ( $dbw->fieldExists( 'watchlist', 'wl_notificationtimestamp' ) ) {
60 wfOut( "...the watchlist table is already set up for email notification.\n" );
61 } else {
62 wfOut( "Adding wl_notificationtimestamp field for email notification management." );
63 /* ALTER TABLE watchlist ADD (wl_notificationtimestamp varchar(14) binary NOT NULL default '0'); */
64 $dbw->sourceFile( archive( 'patch-email-notification.sql' ) );
65 wfOut( "ok\n" );
66 }
67 # Check if we need to add talk page rows to the watchlist
68 $talk = $dbw->selectField( 'watchlist', 'count(*)', 'wl_namespace & 1', __METHOD__ );
69 $nontalk = $dbw->selectField( 'watchlist', 'count(*)', 'NOT (wl_namespace & 1)', __METHOD__ );
70 if ( $talk != $nontalk ) {
71 wfOut( "Adding missing watchlist talk page rows... " );
72 flush();
73
74 $dbw->insertSelect( 'watchlist', 'watchlist',
75 array(
76 'wl_user' => 'wl_user',
77 'wl_namespace' => 'wl_namespace | 1',
78 'wl_title' => 'wl_title',
79 'wl_notificationtimestamp' => 'wl_notificationtimestamp'
80 ), array( 'NOT (wl_namespace & 1)' ), __METHOD__, 'IGNORE' );
81 wfOut( "ok\n" );
82 } else {
83 wfOut( "...watchlist talk page rows already present\n" );
84 }
85 }
86
87 /**
88 * 1.4 betas were missing the 'binary' marker from logging.log_title,
89 * which causes a collation mismatch error on joins in MySQL 4.1.
90 */
91 function check_bin( $table, $field, $patchFile ) {
92 $dbw = wfGetDB( DB_MASTER );
93 if ( $dbw->getType() != 'mysql' )
94 return;
95 $tableName = $dbw->tableName( $table );
96 $res = $dbw->query( "SELECT $field FROM $tableName LIMIT 0", __METHOD__ );
97 $flags = explode( ' ', mysql_field_flags( $res->result, 0 ) );
98
99 if ( in_array( 'binary', $flags ) ) {
100 wfOut( "...$table table has correct $field encoding.\n" );
101 } else {
102 wfOut( "Fixing $field encoding on $table table... " );
103 $dbw->sourceFile( archive( $patchFile ) );
104 wfOut( "ok\n" );
105 }
106 }
107
108 function do_schema_restructuring() {
109 $dbw = wfGetDB( DB_MASTER );
110 if ( $dbw->tableExists( 'page' ) ) {
111 wfOut( "...page table already exists.\n" );
112 } else {
113 wfOut( "...converting from cur/old to page/revision/text DB structure.\n" );
114 wfOut( wfTimestamp( TS_DB ) );
115 wfOut( "......checking for duplicate entries.\n" );
116
117 list ( $cur, $old, $page, $revision, $text ) = $dbw->tableNamesN( 'cur', 'old', 'page', 'revision', 'text' );
118
119 $rows = $dbw->query( "SELECT cur_title, cur_namespace, COUNT(cur_namespace) AS c
120 FROM $cur GROUP BY cur_title, cur_namespace HAVING c>1", __METHOD__ );
121
122 if ( $dbw->numRows( $rows ) > 0 ) {
123 wfOut( wfTimestamp( TS_DB ) );
124 wfOut( "......<b>Found duplicate entries</b>\n" );
125 wfOut( sprintf( "<b> %-60s %3s %5s</b>\n", 'Title', 'NS', 'Count' ) );
126 while ( $row = $dbw->fetchObject( $rows ) ) {
127 if ( ! isset( $duplicate[$row->cur_namespace] ) ) {
128 $duplicate[$row->cur_namespace] = array();
129 }
130 $duplicate[$row->cur_namespace][] = $row->cur_title;
131 wfOut( sprintf( " %-60s %3s %5s\n", $row->cur_title, $row->cur_namespace, $row->c ) );
132 }
133 $sql = "SELECT cur_title, cur_namespace, cur_id, cur_timestamp FROM $cur WHERE ";
134 $firstCond = true;
135 foreach ( $duplicate as $ns => $titles ) {
136 if ( $firstCond ) {
137 $firstCond = false;
138 } else {
139 $sql .= ' OR ';
140 }
141 $sql .= "( cur_namespace = {$ns} AND cur_title in (";
142 $first = true;
143 foreach ( $titles as $t ) {
144 if ( $first ) {
145 $sql .= $dbw->addQuotes( $t );
146 $first = false;
147 } else {
148 $sql .= ', ' . $dbw->addQuotes( $t );
149 }
150 }
151 $sql .= ") ) \n";
152 }
153 # By sorting descending, the most recent entry will be the first in the list.
154 # All following entries will be deleted by the next while-loop.
155 $sql .= 'ORDER BY cur_namespace, cur_title, cur_timestamp DESC';
156
157 $rows = $dbw->query( $sql, __METHOD__ );
158
159 $prev_title = $prev_namespace = false;
160 $deleteId = array();
161
162 while ( $row = $dbw->fetchObject( $rows ) ) {
163 if ( $prev_title == $row->cur_title && $prev_namespace == $row->cur_namespace ) {
164 $deleteId[] = $row->cur_id;
165 }
166 $prev_title = $row->cur_title;
167 $prev_namespace = $row->cur_namespace;
168 }
169 $sql = "DELETE FROM $cur WHERE cur_id IN ( " . join( ',', $deleteId ) . ')';
170 $rows = $dbw->query( $sql, __METHOD__ );
171 wfOut( wfTimestamp( TS_DB ) );
172 wfOut( "......<b>Deleted</b> " . $dbw->affectedRows() . " records.\n" );
173 }
174
175
176 wfOut( wfTimestamp( TS_DB ) );
177 wfOut( "......Creating tables.\n" );
178 $dbw->query( "CREATE TABLE $page (
179 page_id int(8) unsigned NOT NULL auto_increment,
180 page_namespace int NOT NULL,
181 page_title varchar(255) binary NOT NULL,
182 page_restrictions tinyblob NOT NULL,
183 page_counter bigint(20) unsigned NOT NULL default '0',
184 page_is_redirect tinyint(1) unsigned NOT NULL default '0',
185 page_is_new tinyint(1) unsigned NOT NULL default '0',
186 page_random real unsigned NOT NULL,
187 page_touched char(14) binary NOT NULL default '',
188 page_latest int(8) unsigned NOT NULL,
189 page_len int(8) unsigned NOT NULL,
190
191 PRIMARY KEY page_id (page_id),
192 UNIQUE INDEX name_title (page_namespace,page_title),
193 INDEX (page_random),
194 INDEX (page_len)
195 ) ENGINE=InnoDB", __METHOD__ );
196 $dbw->query( "CREATE TABLE $revision (
197 rev_id int(8) unsigned NOT NULL auto_increment,
198 rev_page int(8) unsigned NOT NULL,
199 rev_comment tinyblob NOT NULL,
200 rev_user int(5) unsigned NOT NULL default '0',
201 rev_user_text varchar(255) binary NOT NULL default '',
202 rev_timestamp char(14) binary NOT NULL default '',
203 rev_minor_edit tinyint(1) unsigned NOT NULL default '0',
204 rev_deleted tinyint(1) unsigned NOT NULL default '0',
205 rev_len int(8) unsigned,
206 rev_parent_id int(8) unsigned default NULL,
207 PRIMARY KEY rev_page_id (rev_page, rev_id),
208 UNIQUE INDEX rev_id (rev_id),
209 INDEX rev_timestamp (rev_timestamp),
210 INDEX page_timestamp (rev_page,rev_timestamp),
211 INDEX user_timestamp (rev_user,rev_timestamp),
212 INDEX usertext_timestamp (rev_user_text,rev_timestamp)
213 ) ENGINE=InnoDB", __METHOD__ );
214
215 wfOut( wfTimestamp( TS_DB ) );
216 wfOut( "......Locking tables.\n" );
217 $dbw->query( "LOCK TABLES $page WRITE, $revision WRITE, $old WRITE, $cur WRITE", __METHOD__ );
218
219 $maxold = intval( $dbw->selectField( 'old', 'max(old_id)', '', __METHOD__ ) );
220 wfOut( wfTimestamp( TS_DB ) );
221 wfOut( "......maxold is {$maxold}\n" );
222
223 wfOut( wfTimestamp( TS_DB ) );
224 global $wgLegacySchemaConversion;
225 if ( $wgLegacySchemaConversion ) {
226 // Create HistoryBlobCurStub entries.
227 // Text will be pulled from the leftover 'cur' table at runtime.
228 wfOut( "......Moving metadata from cur; using blob references to text in cur table.\n" );
229 $cur_text = "concat('O:18:\"historyblobcurstub\":1:{s:6:\"mCurId\";i:',cur_id,';}')";
230 $cur_flags = "'object'";
231 } else {
232 // Copy all cur text in immediately: this may take longer but avoids
233 // having to keep an extra table around.
234 wfOut( "......Moving text from cur.\n" );
235 $cur_text = 'cur_text';
236 $cur_flags = "''";
237 }
238 $dbw->query( "INSERT INTO $old (old_namespace, old_title, old_text, old_comment, old_user, old_user_text,
239 old_timestamp, old_minor_edit, old_flags)
240 SELECT cur_namespace, cur_title, $cur_text, cur_comment, cur_user, cur_user_text, cur_timestamp, cur_minor_edit, $cur_flags
241 FROM $cur", __METHOD__ );
242
243 wfOut( wfTimestamp( TS_DB ) );
244 wfOut( "......Setting up revision table.\n" );
245 $dbw->query( "INSERT INTO $revision (rev_id, rev_page, rev_comment, rev_user, rev_user_text, rev_timestamp,
246 rev_minor_edit)
247 SELECT old_id, cur_id, old_comment, old_user, old_user_text,
248 old_timestamp, old_minor_edit
249 FROM $old,$cur WHERE old_namespace=cur_namespace AND old_title=cur_title", __METHOD__ );
250
251 wfOut( wfTimestamp( TS_DB ) );
252 wfOut( "......Setting up page table.\n" );
253 $dbw->query( "INSERT INTO $page (page_id, page_namespace, page_title, page_restrictions, page_counter,
254 page_is_redirect, page_is_new, page_random, page_touched, page_latest, page_len)
255 SELECT cur_id, cur_namespace, cur_title, cur_restrictions, cur_counter, cur_is_redirect, cur_is_new,
256 cur_random, cur_touched, rev_id, LENGTH(cur_text)
257 FROM $cur,$revision
258 WHERE cur_id=rev_page AND rev_timestamp=cur_timestamp AND rev_id > {$maxold}", __METHOD__ );
259
260 wfOut( wfTimestamp( TS_DB ) );
261 wfOut( "......Unlocking tables.\n" );
262 $dbw->query( "UNLOCK TABLES", __METHOD__ );
263
264 wfOut( wfTimestamp( TS_DB ) );
265 wfOut( "......Renaming old.\n" );
266 $dbw->query( "ALTER TABLE $old RENAME TO $text", __METHOD__ );
267
268 wfOut( wfTimestamp( TS_DB ) );
269 wfOut( "...done.\n" );
270 }
271 }
272
273 function do_pagelinks_update() {
274 $dbw = wfGetDB( DB_MASTER );
275 if ( $dbw->tableExists( 'pagelinks' ) ) {
276 wfOut( "...already have pagelinks table.\n" );
277 } else {
278 wfOut( "Converting links and brokenlinks tables to pagelinks... " );
279 $dbw->sourceFile( archive( 'patch-pagelinks.sql' ) );
280 wfOut( "ok\n" );
281 flush();
282
283 global $wgCanonicalNamespaceNames;
284 foreach ( $wgCanonicalNamespaceNames as $ns => $name ) {
285 if ( $ns != 0 ) {
286 do_pagelinks_namespace( $ns );
287 }
288 }
289 }
290 }
291
292 function do_pagelinks_namespace( $namespace ) {
293 global $wgContLang;
294
295 $dbw = wfGetDB( DB_MASTER );
296 $ns = intval( $namespace );
297 wfOut( "Cleaning up broken links for namespace $ns... " );
298
299 $pagelinks = $dbw->tableName( 'pagelinks' );
300 $name = $wgContLang->getNsText( $ns );
301 $prefix = $dbw->strencode( $name );
302 $likeprefix = str_replace( '_', '\\_', $prefix );
303
304 $sql = "UPDATE $pagelinks
305 SET pl_namespace=$ns,
306 pl_title=TRIM(LEADING '$prefix:' FROM pl_title)
307 WHERE pl_namespace=0
308 AND pl_title LIKE '$likeprefix:%'";
309
310 $dbw->query( $sql, 'do_pagelinks_namespace' );
311 wfOut( "ok\n" );
312 }
313
314 function do_old_links_update() {
315 $cl = new ConvertLinks();
316 $cl->execute();
317 }
318
319 function fix_ancient_imagelinks() {
320 $dbw = wfGetDB( DB_MASTER );
321 $info = $dbw->fieldInfo( 'imagelinks', 'il_from' );
322 if ( $info && $info->type() === 'string' ) {
323 wfOut( "Fixing ancient broken imagelinks table.\n" );
324 wfOut( "NOTE: you will have to run maintenance/refreshLinks.php after this.\n" );
325 $dbw->sourceFile( archive( 'patch-fix-il_from.sql' ) );
326 wfOut( "ok\n" );
327 } else {
328 wfOut( "...il_from OK\n" );
329 }
330 }
331
332 function do_user_unique_update() {
333 $dbw = wfGetDB( DB_MASTER );
334 $duper = new UserDupes( $dbw );
335 if ( $duper->hasUniqueIndex() ) {
336 wfOut( "...already have unique user_name index.\n" );
337 } else {
338 if ( !$duper->clearDupes() ) {
339 wfOut( "WARNING: This next step will probably fail due to unfixed duplicates...\n" );
340 }
341 wfOut( "Adding unique index on user_name... " );
342 $dbw->sourceFile( archive( 'patch-user_nameindex.sql' ) );
343 wfOut( "ok\n" );
344 }
345 }
346
347 function do_user_groups_update() {
348 $dbw = wfGetDB( DB_MASTER );
349
350 if ( $dbw->tableExists( 'user_groups' ) ) {
351 wfOut( "...user_groups table already exists.\n" );
352 return do_user_groups_reformat();
353 }
354
355 wfOut( "Adding user_groups table... " );
356 $dbw->sourceFile( archive( 'patch-user_groups.sql' ) );
357 wfOut( "ok\n" );
358
359 if ( !$dbw->tableExists( 'user_rights' ) ) {
360 if ( $dbw->fieldExists( 'user', 'user_rights' ) ) {
361 wfOut( "Upgrading from a 1.3 or older database? Breaking out user_rights for conversion..." );
362 $dbw->sourceFile( archive( 'patch-user_rights.sql' ) );
363 wfOut( "ok\n" );
364 } else {
365 wfOut( "*** WARNING: couldn't locate user_rights table or field for upgrade.\n" );
366 wfOut( "*** You may need to manually configure some sysops by manipulating\n" );
367 wfOut( "*** the user_groups table.\n" );
368 return;
369 }
370 }
371
372 wfOut( "Converting user_rights table to user_groups... " );
373 $result = $dbw->select( 'user_rights',
374 array( 'ur_user', 'ur_rights' ),
375 array( "ur_rights != ''" ),
376 __METHOD__ );
377
378 while ( $row = $dbw->fetchObject( $result ) ) {
379 $groups = array_unique(
380 array_map( 'trim',
381 explode( ',', $row->ur_rights ) ) );
382
383 foreach ( $groups as $group ) {
384 $dbw->insert( 'user_groups',
385 array(
386 'ug_user' => $row->ur_user,
387 'ug_group' => $group ),
388 __METHOD__ );
389 }
390 }
391 wfOut( "ok\n" );
392 }
393
394 function do_user_groups_reformat() {
395 # Check for bogus formats from previous 1.5 alpha code.
396 $dbw = wfGetDB( DB_MASTER );
397 $info = $dbw->fieldInfo( 'user_groups', 'ug_group' );
398
399 if ( $info->type() == 'int' ) {
400 $oldug = $dbw->tableName( 'user_groups' );
401 $newug = $dbw->tableName( 'user_groups_bogus' );
402 wfOut( "user_groups is in bogus intermediate format. Renaming to $newug... " );
403 $dbw->query( "ALTER TABLE $oldug RENAME TO $newug" );
404 wfOut( "ok\n" );
405
406 wfOut( "Re-adding fresh user_groups table... " );
407 $dbw->sourceFile( archive( 'patch-user_groups.sql' ) );
408 wfOut( "ok\n" );
409
410 wfOut( "***\n" );
411 wfOut( "*** WARNING: You will need to manually fix up user permissions in the user_groups\n" );
412 wfOut( "*** table. Old 1.5 alpha versions did some pretty funky stuff...\n" );
413 wfOut( "***\n" );
414 } else {
415 wfOut( "...user_groups is in current format.\n" );
416 }
417
418 }
419
420 function do_watchlist_null() {
421 # Make sure wl_notificationtimestamp can be NULL,
422 # and update old broken items.
423 $dbw = wfGetDB( DB_MASTER );
424 $info = $dbw->fieldInfo( 'watchlist', 'wl_notificationtimestamp' );
425
426 if ( !$info->nullable() ) {
427 wfOut( "Making wl_notificationtimestamp nullable... " );
428 $dbw->sourceFile( archive( 'patch-watchlist-null.sql' ) );
429 wfOut( "ok\n" );
430 } else {
431 wfOut( "...wl_notificationtimestamp is already nullable.\n" );
432 }
433
434 }
435
436 /**
437 * @bug 3946
438 */
439 function do_page_random_update() {
440 wfOut( "Setting page_random to a random value on rows where it equals 0..." );
441
442 $dbw = wfGetDB( DB_MASTER );
443 $page = $dbw->tableName( 'page' );
444 $dbw->query( "UPDATE $page SET page_random = RAND() WHERE page_random = 0", 'do_page_random_update' );
445 $rows = $dbw->affectedRows();
446
447 wfOut( "changed $rows rows\n" );
448 }
449
450 function do_templatelinks_update() {
451 $dbw = wfGetDB( DB_MASTER );
452
453 if ( $dbw->tableExists( 'templatelinks' ) ) {
454 wfOut( "...templatelinks table already exists\n" );
455 return;
456 }
457 wfOut( "Creating templatelinks table...\n" );
458 $dbw->sourceFile( archive( 'patch-templatelinks.sql' ) );
459 wfOut( "Populating...\n" );
460 if ( wfGetLB()->getServerCount() > 1 ) {
461 // Slow, replication-friendly update
462 $res = $dbw->select( 'pagelinks', array( 'pl_from', 'pl_namespace', 'pl_title' ),
463 array( 'pl_namespace' => NS_TEMPLATE ), __METHOD__ );
464 $count = 0;
465 while ( $row = $dbw->fetchObject( $res ) ) {
466 $count = ( $count + 1 ) % 100;
467 if ( $count == 0 ) {
468 if ( function_exists( 'wfWaitForSlaves' ) ) {
469 wfWaitForSlaves( 10 );
470 } else {
471 sleep( 1 );
472 }
473 }
474 $dbw->insert( 'templatelinks',
475 array(
476 'tl_from' => $row->pl_from,
477 'tl_namespace' => $row->pl_namespace,
478 'tl_title' => $row->pl_title,
479 ), __METHOD__
480 );
481
482 }
483 } else {
484 // Fast update
485 $dbw->insertSelect( 'templatelinks', 'pagelinks',
486 array(
487 'tl_from' => 'pl_from',
488 'tl_namespace' => 'pl_namespace',
489 'tl_title' => 'pl_title'
490 ), array(
491 'pl_namespace' => 10
492 ), __METHOD__
493 );
494 }
495 wfOut( "Done. Please run maintenance/refreshLinks.php for a more thorough templatelinks update.\n" );
496 }
497
498 // Add index on ( rc_namespace, rc_user_text ) [Jul. 2006]
499 // Add index on ( rc_user_text, rc_timestamp ) [Nov. 2006]
500 function do_rc_indices_update() {
501 $dbw = wfGetDB( DB_MASTER );
502 wfOut( "Checking for additional recent changes indices...\n" );
503
504 $indexes = array(
505 'rc_ns_usertext' => 'patch-recentchanges-utindex.sql',
506 'rc_user_text' => 'patch-rc_user_text-index.sql',
507 );
508
509 foreach ( $indexes as $index => $patch ) {
510 $info = $dbw->indexInfo( 'recentchanges', $index, __METHOD__ );
511 if ( !$info ) {
512 wfOut( "...index `{$index}` not found; adding..." );
513 $dbw->sourceFile( archive( $patch ) );
514 wfOut( "done.\n" );
515 } else {
516 wfOut( "...index `{$index}` seems ok.\n" );
517 }
518 }
519 }
520
521 function index_has_field( $table, $index, $field ) {
522 wfOut( "Checking if $table index $index includes field $field...\n" );
523 $info = wfGetDB( DB_MASTER )->indexInfo( $table, $index, __METHOD__ );
524 if ( $info ) {
525 foreach ( $info as $row ) {
526 if ( $row->Column_name == $field ) {
527 wfOut( "...index $index on table $table seems to be ok\n" );
528 return true;
529 }
530 }
531 }
532 wfOut( "...index $index on table $table has no field $field; adding\n" );
533 return false;
534 }
535
536 function do_backlinking_indices_update() {
537 wfOut( "Checking for backlinking indices...\n" );
538 if ( !index_has_field( 'pagelinks', 'pl_namespace', 'pl_from' ) ||
539 !index_has_field( 'templatelinks', 'tl_namespace', 'tl_from' ) ||
540 !index_has_field( 'imagelinks', 'il_to', 'il_from' ) )
541 {
542 wfGetDB( DB_MASTER )->sourceFile( archive( 'patch-backlinkindexes.sql' ) );
543 wfOut( "...backlinking indices updated\n" );
544 }
545 }
546
547 function do_categorylinks_indices_update() {
548 wfOut( "Checking for categorylinks indices...\n" );
549 if ( !index_has_field( 'categorylinks', 'cl_sortkey', 'cl_from' ) )
550 {
551 wfGetDB( DB_MASTER )->sourceFile( archive( 'patch-categorylinksindex.sql' ) );
552 wfOut( "...categorylinks indices updated\n" );
553 }
554 }
555
556 function do_filearchive_indices_update() {
557 $dbw = wfGetDB( DB_MASTER );
558 wfOut( "Checking filearchive indices...\n" );
559 $info = $dbw->indexInfo( 'filearchive', 'fa_user_timestamp', __METHOD__ );
560 if ( !$info )
561 {
562 $dbw->sourceFile( archive( 'patch-filearchive-user-index.sql' ) );
563 wfOut( "...filearchive indices updated\n" );
564 }
565 }
566
567 function maybe_do_profiling_memory_update() {
568 $dbw = wfGetDB( DB_MASTER );
569 if ( !$dbw->tableExists( 'profiling' ) ) {
570 // Simply ignore
571 } elseif ( $dbw->fieldExists( 'profiling', 'pf_memory' ) ) {
572 wfOut( "...profiling table has pf_memory field.\n" );
573 } else {
574 wfOut( "Adding pf_memory field to table profiling..." );
575 $dbw->sourceFile( archive( 'patch-profiling-memory.sql' ) );
576 wfOut( "ok\n" );
577 }
578 }
579
580 function do_stats_init() {
581 // Sometimes site_stats table is not properly populated.
582 wfOut( "\nChecking site_stats row..." );
583 $row = wfGetDB( DB_MASTER )->selectRow( 'site_stats', '*', array( 'ss_row_id' => 1 ), __METHOD__ );
584 if ( $row === false ) {
585 wfOut( "data is missing! rebuilding...\n" );
586 } elseif ( isset( $row->site_stats ) && $row->ss_total_pages == -1 ) {
587 wfOut( "missing ss_total_pages, rebuilding...\n" );
588 } else {
589 wfOut( "ok.\n" );
590 return;
591 }
592 SiteStatsInit::doAllAndCommit( false );
593 }
594
595 function do_active_users_init() {
596 $dbw = wfGetDB( DB_MASTER );
597 $activeUsers = $dbw->selectField( 'site_stats', 'ss_active_users', false, __METHOD__ );
598 if ( $activeUsers == -1 ) {
599 $activeUsers = $dbw->selectField( 'recentchanges',
600 'COUNT( DISTINCT rc_user_text )',
601 array( 'rc_user != 0', 'rc_bot' => 0, "rc_log_type != 'newusers'" ), __METHOD__
602 );
603 $dbw->update( 'site_stats',
604 array( 'ss_active_users' => intval( $activeUsers ) ),
605 array( 'ss_row_id' => 1 ), __METHOD__, array( 'LIMIT' => 1 )
606 );
607 }
608 wfOut( "...ss_active_users user count set...\n" );
609 }
610
611 /**
612 * Adding page_restrictions table, obsoleting page.page_restrictions.
613 * Migrating old restrictions to new table
614 * -- Andrew Garrett, January 2007.
615 */
616 function do_restrictions_update() {
617 $dbw = wfGetDB( DB_MASTER );
618 if ( $dbw->tableExists( 'page_restrictions' ) ) {
619 wfOut( "...page_restrictions table already exists.\n" );
620 } else {
621 wfOut( "Creating page_restrictions table..." );
622 $dbw->sourceFile( archive( 'patch-page_restrictions.sql' ) );
623 $dbw->sourceFile( archive( 'patch-page_restrictions_sortkey.sql' ) );
624 wfOut( "ok\n" );
625
626 wfOut( "Migrating old restrictions to new table...\n" );
627 $task = new UpdateRestrictions();
628 $task->execute();
629 }
630 }
631
632 function do_category_population() {
633 if ( update_row_exists( 'populate category' ) ) {
634 wfOut( "...category table already populated.\n" );
635 return;
636 }
637
638 wfOut(
639 "Populating category table, printing progress markers. " .
640 "For large databases, you\n" .
641 "may want to hit Ctrl-C and do this manually with maintenance/\n" .
642 "populateCategory.php.\n"
643 );
644 $task = new PopulateCategory();
645 $task->execute();
646 wfOut( "Done populating category table.\n" );
647 }
648
649 function do_populate_parent_id() {
650 if ( update_row_exists( 'populate rev_parent_id' ) ) {
651 wfOut( "...rev_parent_id column already populated.\n" );
652 return;
653 }
654
655 $task = new PopulateParentId();
656 $task->execute();
657 }
658
659 function do_populate_rev_len() {
660 if ( update_row_exists( 'populate rev_len' ) ) {
661 wfOut( "...rev_len column already populated.\n" );
662 return;
663 }
664
665 $task = new PopulateRevisionLength();
666 $task->execute();
667 }
668
669 function do_cl_fields_update() {
670 if ( update_row_exists( 'cl_fields_update' ) ) {
671 wfOut( "...categorylinks up-to-date.\n" );
672 return;
673 }
674 wfOut( 'Updating categorylinks (again)...' );
675 wfGetDB( DB_MASTER )->sourceFile( archive( 'patch-categorylinks-better-collation2.sql' ) );
676 wfOut( "done.\n" );
677 }
678
679 function do_collation_update() {
680 global $wgCategoryCollation;
681 $dbw = wfGetDB( DB_MASTER );
682 if ( $dbw->selectField(
683 'categorylinks',
684 'COUNT(*)',
685 'cl_collation != ' . $dbw->addQuotes( $wgCategoryCollation ),
686 __FUNCTION__
687 ) == 0 ) {
688 wfOut( "...collations up-to-date.\n" );
689 return;
690 }
691
692 $task = new UpdateCollation();
693 $task->execute();
694 }
695
696 function do_unique_pl_tl_il() {
697 $dbw = wfGetDB( DB_MASTER );
698 $info = $dbw->indexInfo( 'pagelinks', 'pl_namespace' );
699 if ( is_array( $info ) && !$info[0]->Non_unique ) {
700 wfOut( "...pl_namespace, tl_namespace, il_to indices are already UNIQUE.\n" );
701 } else {
702 wfOut( "Making pl_namespace, tl_namespace and il_to indices UNIQUE... " );
703 $dbw->sourceFile( archive( 'patch-pl-tl-il-unique.sql' ) );
704 wfOut( "ok\n" );
705 }
706 }
707
708 function do_log_search_population() {
709 if ( update_row_exists( 'populate log_search' ) ) {
710 wfOut( "...log_search table already populated.\n" );
711 return;
712 }
713 wfOut(
714 "Populating log_search table, printing progress markers. For large\n" .
715 "databases, you may want to hit Ctrl-C and do this manually with\n" .
716 "maintenance/populateLogSearch.php.\n" );
717 $task = new PopulateLogSearch();
718 $task->execute();
719 wfOut( "Done populating log_search table.\n" );
720 }
721
722 function rename_eu_wiki_id() {
723 $dbw = wfGetDB( DB_MASTER );
724 if ( $dbw->fieldExists( 'external_user', 'eu_local_id' ) ) {
725 wfOut( "...eu_wiki_id already renamed to eu_local_id.\n" );
726 return;
727 }
728 wfOut( "Renaming eu_wiki_id -> eu_local_id... " );
729 $dbw->sourceFile( archive( 'patch-eu_local_id.sql' ) );
730 wfOut( "ok\n" );
731 }
732
733 function do_update_transcache_field() {
734 if ( update_row_exists( 'convert transcache field' ) ) {
735 wfOut( "...transcache tc_time already converted.\n" );
736 return;
737 } else {
738 wfOut( "Converting tc_time from UNIX epoch to MediaWiki timestamp... " );
739 wfGetDB( DB_MASTER )->sourceFile( archive( 'patch-tc-timestamp.sql' ) );
740 wfOut( "ok\n" );
741 }
742 }
743
744 function do_update_mime_minor_field() {
745 if ( update_row_exists( 'mime_minor_length' ) ) {
746 wfOut( "...*_mime_minor fields are already long enough.\n" );
747 } else {
748 wfOut( "Altering all *_mime_minor fields to 100 bytes in size ... " );
749 wfGetDB( DB_MASTER )->sourceFile( archive( 'patch-mime_minor_length.sql' ) );
750 wfOut( "ok\n" );
751 }
752 }