r72870 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r72869‎ | r72870 | r72871 >
Date:16:24, 12 September 2010
Author:ialex
Status:resolved
Tags:
Comment:
GOOD BYE, dear old updaters.inc!
* Moved update functions to MysqlUpdater and DatabaseUpdater (and archive() to install-utils.inc just in case someone is still using it)
* Moved update_row_exists() to DatabaseUpdater
* Added cl_collation patch for SQLite, was missing and also run collationUpdate.php while updation SQLite
Modified paths:
  • /trunk/phase3/includes/installer/DatabaseUpdater.php (modified) (history)
  • /trunk/phase3/includes/installer/MysqlUpdater.php (modified) (history)
  • /trunk/phase3/includes/installer/SqliteUpdater.php (modified) (history)
  • /trunk/phase3/maintenance/install-utils.inc (modified) (history)
  • /trunk/phase3/maintenance/sqlite/archives/patch-categorylinks-better-collation.sql (added) (history)
  • /trunk/phase3/maintenance/updaters.inc (deleted) (history)

Diff [purge]

Index: trunk/phase3/maintenance/updaters.inc
@@ -1,727 +0,0 @@
2 -<?php
3 -/**
4 - * @file
5 - * @ingroup Maintenance
6 - */
7 -
8 -if ( !defined( 'MEDIAWIKI' ) ) {
9 - echo "This file is not a valid entry point\n";
10 - exit( 1 );
11 -}
12 -
13 -function archive( $name ) {
14 - return DatabaseBase::patchPath( $name );
15 -}
16 -
17 -function do_interwiki_update() {
18 - # Check that interwiki table exists; if it doesn't source it
19 - global $IP;
20 - $dbw = wfGetDB( DB_MASTER );
21 - if ( $dbw->tableExists( "interwiki" ) ) {
22 - wfOut( "...already have interwiki table\n" );
23 - return true;
24 - }
25 - wfOut( "Creating interwiki table: " );
26 - $dbw->sourceFile( archive( "patch-interwiki.sql" ) );
27 - wfOut( "ok\n" );
28 - wfOut( "Adding default interwiki definitions: " );
29 - $dbw->sourceFile( "$IP/maintenance/interwiki.sql" );
30 - wfOut( "ok\n" );
31 -}
32 -
33 -function do_index_update() {
34 - # Check that proper indexes are in place
35 - $dbw = wfGetDB( DB_MASTER );
36 - $meta = $dbw->fieldInfo( "recentchanges", "rc_timestamp" );
37 - if ( !$meta->isMultipleKey() ) {
38 - wfOut( "Updating indexes to 20031107: " );
39 - $dbw->sourceFile( archive( "patch-indexes.sql" ) );
40 - wfOut( "ok\n" );
41 - return true;
42 - }
43 - wfOut( "...indexes seem up to 20031107 standards\n" );
44 - return false;
45 -}
46 -
47 -function do_image_name_unique_update() {
48 - $dbw = wfGetDB( DB_MASTER );
49 - if ( $dbw->indexExists( 'image', 'PRIMARY' ) ) {
50 - wfOut( "...image primary key already set.\n" );
51 - } else {
52 - wfOut( "Making img_name the primary key... " );
53 - $dbw->sourceFile( archive( "patch-image_name_primary.sql" ) );
54 - wfOut( "ok\n" );
55 - }
56 -}
57 -
58 -function do_watchlist_update() {
59 - $dbw = wfGetDB( DB_MASTER );
60 - # Check if we need to add talk page rows to the watchlist
61 - $talk = $dbw->selectField( 'watchlist', 'count(*)', 'wl_namespace & 1', __METHOD__ );
62 - $nontalk = $dbw->selectField( 'watchlist', 'count(*)', 'NOT (wl_namespace & 1)', __METHOD__ );
63 - if ( $talk != $nontalk ) {
64 - wfOut( "Adding missing watchlist talk page rows... " );
65 -
66 - $dbw->insertSelect( 'watchlist', 'watchlist',
67 - array(
68 - 'wl_user' => 'wl_user',
69 - 'wl_namespace' => 'wl_namespace | 1',
70 - 'wl_title' => 'wl_title',
71 - 'wl_notificationtimestamp' => 'wl_notificationtimestamp'
72 - ), array( 'NOT (wl_namespace & 1)' ), __METHOD__, 'IGNORE' );
73 - wfOut( "ok\n" );
74 - } else {
75 - wfOut( "...watchlist talk page rows already present\n" );
76 - }
77 -}
78 -
79 -/**
80 - * 1.4 betas were missing the 'binary' marker from logging.log_title,
81 - * which causes a collation mismatch error on joins in MySQL 4.1.
82 - */
83 -function check_bin( $table, $field, $patchFile ) {
84 - $dbw = wfGetDB( DB_MASTER );
85 - if ( $dbw->getType() != 'mysql' )
86 - return;
87 - $tableName = $dbw->tableName( $table );
88 - $res = $dbw->query( "SELECT $field FROM $tableName LIMIT 0", __METHOD__ );
89 - $flags = explode( ' ', mysql_field_flags( $res->result, 0 ) );
90 -
91 - if ( in_array( 'binary', $flags ) ) {
92 - wfOut( "...$table table has correct $field encoding.\n" );
93 - } else {
94 - wfOut( "Fixing $field encoding on $table table... " );
95 - $dbw->sourceFile( archive( $patchFile ) );
96 - wfOut( "ok\n" );
97 - }
98 -}
99 -
100 -function do_schema_restructuring() {
101 - $dbw = wfGetDB( DB_MASTER );
102 - if ( $dbw->tableExists( 'page' ) ) {
103 - wfOut( "...page table already exists.\n" );
104 - } else {
105 - wfOut( "...converting from cur/old to page/revision/text DB structure.\n" );
106 - wfOut( wfTimestamp( TS_DB ) );
107 - wfOut( "......checking for duplicate entries.\n" );
108 -
109 - list ( $cur, $old, $page, $revision, $text ) = $dbw->tableNamesN( 'cur', 'old', 'page', 'revision', 'text' );
110 -
111 - $rows = $dbw->query( "SELECT cur_title, cur_namespace, COUNT(cur_namespace) AS c
112 - FROM $cur GROUP BY cur_title, cur_namespace HAVING c>1", __METHOD__ );
113 -
114 - if ( $dbw->numRows( $rows ) > 0 ) {
115 - wfOut( wfTimestamp( TS_DB ) );
116 - wfOut( "......<b>Found duplicate entries</b>\n" );
117 - wfOut( sprintf( "<b> %-60s %3s %5s</b>\n", 'Title', 'NS', 'Count' ) );
118 - while ( $row = $dbw->fetchObject( $rows ) ) {
119 - if ( ! isset( $duplicate[$row->cur_namespace] ) ) {
120 - $duplicate[$row->cur_namespace] = array();
121 - }
122 - $duplicate[$row->cur_namespace][] = $row->cur_title;
123 - wfOut( sprintf( " %-60s %3s %5s\n", $row->cur_title, $row->cur_namespace, $row->c ) );
124 - }
125 - $sql = "SELECT cur_title, cur_namespace, cur_id, cur_timestamp FROM $cur WHERE ";
126 - $firstCond = true;
127 - foreach ( $duplicate as $ns => $titles ) {
128 - if ( $firstCond ) {
129 - $firstCond = false;
130 - } else {
131 - $sql .= ' OR ';
132 - }
133 - $sql .= "( cur_namespace = {$ns} AND cur_title in (";
134 - $first = true;
135 - foreach ( $titles as $t ) {
136 - if ( $first ) {
137 - $sql .= $dbw->addQuotes( $t );
138 - $first = false;
139 - } else {
140 - $sql .= ', ' . $dbw->addQuotes( $t );
141 - }
142 - }
143 - $sql .= ") ) \n";
144 - }
145 - # By sorting descending, the most recent entry will be the first in the list.
146 - # All following entries will be deleted by the next while-loop.
147 - $sql .= 'ORDER BY cur_namespace, cur_title, cur_timestamp DESC';
148 -
149 - $rows = $dbw->query( $sql, __METHOD__ );
150 -
151 - $prev_title = $prev_namespace = false;
152 - $deleteId = array();
153 -
154 - while ( $row = $dbw->fetchObject( $rows ) ) {
155 - if ( $prev_title == $row->cur_title && $prev_namespace == $row->cur_namespace ) {
156 - $deleteId[] = $row->cur_id;
157 - }
158 - $prev_title = $row->cur_title;
159 - $prev_namespace = $row->cur_namespace;
160 - }
161 - $sql = "DELETE FROM $cur WHERE cur_id IN ( " . join( ',', $deleteId ) . ')';
162 - $rows = $dbw->query( $sql, __METHOD__ );
163 - wfOut( wfTimestamp( TS_DB ) );
164 - wfOut( "......<b>Deleted</b> " . $dbw->affectedRows() . " records.\n" );
165 - }
166 -
167 -
168 - wfOut( wfTimestamp( TS_DB ) );
169 - wfOut( "......Creating tables.\n" );
170 - $dbw->query( "CREATE TABLE $page (
171 - page_id int(8) unsigned NOT NULL auto_increment,
172 - page_namespace int NOT NULL,
173 - page_title varchar(255) binary NOT NULL,
174 - page_restrictions tinyblob NOT NULL,
175 - page_counter bigint(20) unsigned NOT NULL default '0',
176 - page_is_redirect tinyint(1) unsigned NOT NULL default '0',
177 - page_is_new tinyint(1) unsigned NOT NULL default '0',
178 - page_random real unsigned NOT NULL,
179 - page_touched char(14) binary NOT NULL default '',
180 - page_latest int(8) unsigned NOT NULL,
181 - page_len int(8) unsigned NOT NULL,
182 -
183 - PRIMARY KEY page_id (page_id),
184 - UNIQUE INDEX name_title (page_namespace,page_title),
185 - INDEX (page_random),
186 - INDEX (page_len)
187 - ) ENGINE=InnoDB", __METHOD__ );
188 - $dbw->query( "CREATE TABLE $revision (
189 - rev_id int(8) unsigned NOT NULL auto_increment,
190 - rev_page int(8) unsigned NOT NULL,
191 - rev_comment tinyblob NOT NULL,
192 - rev_user int(5) unsigned NOT NULL default '0',
193 - rev_user_text varchar(255) binary NOT NULL default '',
194 - rev_timestamp char(14) binary NOT NULL default '',
195 - rev_minor_edit tinyint(1) unsigned NOT NULL default '0',
196 - rev_deleted tinyint(1) unsigned NOT NULL default '0',
197 - rev_len int(8) unsigned,
198 - rev_parent_id int(8) unsigned default NULL,
199 - PRIMARY KEY rev_page_id (rev_page, rev_id),
200 - UNIQUE INDEX rev_id (rev_id),
201 - INDEX rev_timestamp (rev_timestamp),
202 - INDEX page_timestamp (rev_page,rev_timestamp),
203 - INDEX user_timestamp (rev_user,rev_timestamp),
204 - INDEX usertext_timestamp (rev_user_text,rev_timestamp)
205 - ) ENGINE=InnoDB", __METHOD__ );
206 -
207 - wfOut( wfTimestamp( TS_DB ) );
208 - wfOut( "......Locking tables.\n" );
209 - $dbw->query( "LOCK TABLES $page WRITE, $revision WRITE, $old WRITE, $cur WRITE", __METHOD__ );
210 -
211 - $maxold = intval( $dbw->selectField( 'old', 'max(old_id)', '', __METHOD__ ) );
212 - wfOut( wfTimestamp( TS_DB ) );
213 - wfOut( "......maxold is {$maxold}\n" );
214 -
215 - wfOut( wfTimestamp( TS_DB ) );
216 - global $wgLegacySchemaConversion;
217 - if ( $wgLegacySchemaConversion ) {
218 - // Create HistoryBlobCurStub entries.
219 - // Text will be pulled from the leftover 'cur' table at runtime.
220 - wfOut( "......Moving metadata from cur; using blob references to text in cur table.\n" );
221 - $cur_text = "concat('O:18:\"historyblobcurstub\":1:{s:6:\"mCurId\";i:',cur_id,';}')";
222 - $cur_flags = "'object'";
223 - } else {
224 - // Copy all cur text in immediately: this may take longer but avoids
225 - // having to keep an extra table around.
226 - wfOut( "......Moving text from cur.\n" );
227 - $cur_text = 'cur_text';
228 - $cur_flags = "''";
229 - }
230 - $dbw->query( "INSERT INTO $old (old_namespace, old_title, old_text, old_comment, old_user, old_user_text,
231 - old_timestamp, old_minor_edit, old_flags)
232 - SELECT cur_namespace, cur_title, $cur_text, cur_comment, cur_user, cur_user_text, cur_timestamp, cur_minor_edit, $cur_flags
233 - FROM $cur", __METHOD__ );
234 -
235 - wfOut( wfTimestamp( TS_DB ) );
236 - wfOut( "......Setting up revision table.\n" );
237 - $dbw->query( "INSERT INTO $revision (rev_id, rev_page, rev_comment, rev_user, rev_user_text, rev_timestamp,
238 - rev_minor_edit)
239 - SELECT old_id, cur_id, old_comment, old_user, old_user_text,
240 - old_timestamp, old_minor_edit
241 - FROM $old,$cur WHERE old_namespace=cur_namespace AND old_title=cur_title", __METHOD__ );
242 -
243 - wfOut( wfTimestamp( TS_DB ) );
244 - wfOut( "......Setting up page table.\n" );
245 - $dbw->query( "INSERT INTO $page (page_id, page_namespace, page_title, page_restrictions, page_counter,
246 - page_is_redirect, page_is_new, page_random, page_touched, page_latest, page_len)
247 - SELECT cur_id, cur_namespace, cur_title, cur_restrictions, cur_counter, cur_is_redirect, cur_is_new,
248 - cur_random, cur_touched, rev_id, LENGTH(cur_text)
249 - FROM $cur,$revision
250 - WHERE cur_id=rev_page AND rev_timestamp=cur_timestamp AND rev_id > {$maxold}", __METHOD__ );
251 -
252 - wfOut( wfTimestamp( TS_DB ) );
253 - wfOut( "......Unlocking tables.\n" );
254 - $dbw->query( "UNLOCK TABLES", __METHOD__ );
255 -
256 - wfOut( wfTimestamp( TS_DB ) );
257 - wfOut( "......Renaming old.\n" );
258 - $dbw->query( "ALTER TABLE $old RENAME TO $text", __METHOD__ );
259 -
260 - wfOut( wfTimestamp( TS_DB ) );
261 - wfOut( "...done.\n" );
262 - }
263 -}
264 -
265 -function do_pagelinks_update() {
266 - $dbw = wfGetDB( DB_MASTER );
267 - if ( $dbw->tableExists( 'pagelinks' ) ) {
268 - wfOut( "...already have pagelinks table.\n" );
269 - } else {
270 - wfOut( "Converting links and brokenlinks tables to pagelinks... " );
271 - $dbw->sourceFile( archive( 'patch-pagelinks.sql' ) );
272 - wfOut( "ok\n" );
273 -
274 - global $wgCanonicalNamespaceNames;
275 - foreach ( $wgCanonicalNamespaceNames as $ns => $name ) {
276 - if ( $ns != 0 ) {
277 - do_pagelinks_namespace( $ns );
278 - }
279 - }
280 - }
281 -}
282 -
283 -function do_pagelinks_namespace( $namespace ) {
284 - global $wgContLang;
285 -
286 - $dbw = wfGetDB( DB_MASTER );
287 - $ns = intval( $namespace );
288 - wfOut( "Cleaning up broken links for namespace $ns... " );
289 -
290 - $pagelinks = $dbw->tableName( 'pagelinks' );
291 - $name = $wgContLang->getNsText( $ns );
292 - $prefix = $dbw->strencode( $name );
293 - $likeprefix = str_replace( '_', '\\_', $prefix );
294 -
295 - $sql = "UPDATE $pagelinks
296 - SET pl_namespace=$ns,
297 - pl_title=TRIM(LEADING '$prefix:' FROM pl_title)
298 - WHERE pl_namespace=0
299 - AND pl_title LIKE '$likeprefix:%'";
300 -
301 - $dbw->query( $sql, 'do_pagelinks_namespace' );
302 - wfOut( "ok\n" );
303 -}
304 -
305 -function do_old_links_update() {
306 - $cl = new ConvertLinks();
307 - $cl->execute();
308 -}
309 -
310 -function fix_ancient_imagelinks() {
311 - $dbw = wfGetDB( DB_MASTER );
312 - $info = $dbw->fieldInfo( 'imagelinks', 'il_from' );
313 - if ( $info && $info->type() === 'string' ) {
314 - wfOut( "Fixing ancient broken imagelinks table.\n" );
315 - wfOut( "NOTE: you will have to run maintenance/refreshLinks.php after this.\n" );
316 - $dbw->sourceFile( archive( 'patch-fix-il_from.sql' ) );
317 - wfOut( "ok\n" );
318 - } else {
319 - wfOut( "...il_from OK\n" );
320 - }
321 -}
322 -
323 -function do_user_unique_update() {
324 - $dbw = wfGetDB( DB_MASTER );
325 - $duper = new UserDupes( $dbw );
326 - if ( $duper->hasUniqueIndex() ) {
327 - wfOut( "...already have unique user_name index.\n" );
328 - } else {
329 - if ( !$duper->clearDupes() ) {
330 - wfOut( "WARNING: This next step will probably fail due to unfixed duplicates...\n" );
331 - }
332 - wfOut( "Adding unique index on user_name... " );
333 - $dbw->sourceFile( archive( 'patch-user_nameindex.sql' ) );
334 - wfOut( "ok\n" );
335 - }
336 -}
337 -
338 -function do_user_groups_update() {
339 - $dbw = wfGetDB( DB_MASTER );
340 -
341 - if ( $dbw->tableExists( 'user_groups' ) ) {
342 - wfOut( "...user_groups table already exists.\n" );
343 - return do_user_groups_reformat();
344 - }
345 -
346 - wfOut( "Adding user_groups table... " );
347 - $dbw->sourceFile( archive( 'patch-user_groups.sql' ) );
348 - wfOut( "ok\n" );
349 -
350 - if ( !$dbw->tableExists( 'user_rights' ) ) {
351 - if ( $dbw->fieldExists( 'user', 'user_rights' ) ) {
352 - wfOut( "Upgrading from a 1.3 or older database? Breaking out user_rights for conversion..." );
353 - $dbw->sourceFile( archive( 'patch-user_rights.sql' ) );
354 - wfOut( "ok\n" );
355 - } else {
356 - wfOut( "*** WARNING: couldn't locate user_rights table or field for upgrade.\n" );
357 - wfOut( "*** You may need to manually configure some sysops by manipulating\n" );
358 - wfOut( "*** the user_groups table.\n" );
359 - return;
360 - }
361 - }
362 -
363 - wfOut( "Converting user_rights table to user_groups... " );
364 - $result = $dbw->select( 'user_rights',
365 - array( 'ur_user', 'ur_rights' ),
366 - array( "ur_rights != ''" ),
367 - __METHOD__ );
368 -
369 - while ( $row = $dbw->fetchObject( $result ) ) {
370 - $groups = array_unique(
371 - array_map( 'trim',
372 - explode( ',', $row->ur_rights ) ) );
373 -
374 - foreach ( $groups as $group ) {
375 - $dbw->insert( 'user_groups',
376 - array(
377 - 'ug_user' => $row->ur_user,
378 - 'ug_group' => $group ),
379 - __METHOD__ );
380 - }
381 - }
382 - wfOut( "ok\n" );
383 -}
384 -
385 -function do_user_groups_reformat() {
386 - # Check for bogus formats from previous 1.5 alpha code.
387 - $dbw = wfGetDB( DB_MASTER );
388 - $info = $dbw->fieldInfo( 'user_groups', 'ug_group' );
389 -
390 - if ( $info->type() == 'int' ) {
391 - $oldug = $dbw->tableName( 'user_groups' );
392 - $newug = $dbw->tableName( 'user_groups_bogus' );
393 - wfOut( "user_groups is in bogus intermediate format. Renaming to $newug... " );
394 - $dbw->query( "ALTER TABLE $oldug RENAME TO $newug" );
395 - wfOut( "ok\n" );
396 -
397 - wfOut( "Re-adding fresh user_groups table... " );
398 - $dbw->sourceFile( archive( 'patch-user_groups.sql' ) );
399 - wfOut( "ok\n" );
400 -
401 - wfOut( "***\n" );
402 - wfOut( "*** WARNING: You will need to manually fix up user permissions in the user_groups\n" );
403 - wfOut( "*** table. Old 1.5 alpha versions did some pretty funky stuff...\n" );
404 - wfOut( "***\n" );
405 - } else {
406 - wfOut( "...user_groups is in current format.\n" );
407 - }
408 -
409 -}
410 -
411 -function do_watchlist_null() {
412 - # Make sure wl_notificationtimestamp can be NULL,
413 - # and update old broken items.
414 - $dbw = wfGetDB( DB_MASTER );
415 - $info = $dbw->fieldInfo( 'watchlist', 'wl_notificationtimestamp' );
416 -
417 - if ( !$info->nullable() ) {
418 - wfOut( "Making wl_notificationtimestamp nullable... " );
419 - $dbw->sourceFile( archive( 'patch-watchlist-null.sql' ) );
420 - wfOut( "ok\n" );
421 - } else {
422 - wfOut( "...wl_notificationtimestamp is already nullable.\n" );
423 - }
424 -
425 -}
426 -
427 -/**
428 - * @bug 3946
429 - */
430 -function do_page_random_update() {
431 - wfOut( "Setting page_random to a random value on rows where it equals 0..." );
432 -
433 - $dbw = wfGetDB( DB_MASTER );
434 - $page = $dbw->tableName( 'page' );
435 - $dbw->query( "UPDATE $page SET page_random = RAND() WHERE page_random = 0", 'do_page_random_update' );
436 - $rows = $dbw->affectedRows();
437 -
438 - wfOut( "changed $rows rows\n" );
439 -}
440 -
441 -function do_templatelinks_update() {
442 - $dbw = wfGetDB( DB_MASTER );
443 -
444 - if ( $dbw->tableExists( 'templatelinks' ) ) {
445 - wfOut( "...templatelinks table already exists\n" );
446 - return;
447 - }
448 - wfOut( "Creating templatelinks table...\n" );
449 - $dbw->sourceFile( archive( 'patch-templatelinks.sql' ) );
450 - wfOut( "Populating...\n" );
451 - if ( wfGetLB()->getServerCount() > 1 ) {
452 - // Slow, replication-friendly update
453 - $res = $dbw->select( 'pagelinks', array( 'pl_from', 'pl_namespace', 'pl_title' ),
454 - array( 'pl_namespace' => NS_TEMPLATE ), __METHOD__ );
455 - $count = 0;
456 - while ( $row = $dbw->fetchObject( $res ) ) {
457 - $count = ( $count + 1 ) % 100;
458 - if ( $count == 0 ) {
459 - if ( function_exists( 'wfWaitForSlaves' ) ) {
460 - wfWaitForSlaves( 10 );
461 - } else {
462 - sleep( 1 );
463 - }
464 - }
465 - $dbw->insert( 'templatelinks',
466 - array(
467 - 'tl_from' => $row->pl_from,
468 - 'tl_namespace' => $row->pl_namespace,
469 - 'tl_title' => $row->pl_title,
470 - ), __METHOD__
471 - );
472 -
473 - }
474 - } else {
475 - // Fast update
476 - $dbw->insertSelect( 'templatelinks', 'pagelinks',
477 - array(
478 - 'tl_from' => 'pl_from',
479 - 'tl_namespace' => 'pl_namespace',
480 - 'tl_title' => 'pl_title'
481 - ), array(
482 - 'pl_namespace' => 10
483 - ), __METHOD__
484 - );
485 - }
486 - wfOut( "Done. Please run maintenance/refreshLinks.php for a more thorough templatelinks update.\n" );
487 -}
488 -
489 -// Add index on ( rc_namespace, rc_user_text ) [Jul. 2006]
490 -// Add index on ( rc_user_text, rc_timestamp ) [Nov. 2006]
491 -function do_rc_indices_update() {
492 - $dbw = wfGetDB( DB_MASTER );
493 - wfOut( "Checking for additional recent changes indices...\n" );
494 -
495 - $indexes = array(
496 - 'rc_ns_usertext' => 'patch-recentchanges-utindex.sql',
497 - 'rc_user_text' => 'patch-rc_user_text-index.sql',
498 - );
499 -
500 - foreach ( $indexes as $index => $patch ) {
501 - $info = $dbw->indexInfo( 'recentchanges', $index, __METHOD__ );
502 - if ( !$info ) {
503 - wfOut( "...index `{$index}` not found; adding..." );
504 - $dbw->sourceFile( archive( $patch ) );
505 - wfOut( "done.\n" );
506 - } else {
507 - wfOut( "...index `{$index}` seems ok.\n" );
508 - }
509 - }
510 -}
511 -
512 -function index_has_field( $table, $index, $field ) {
513 - wfOut( "Checking if $table index $index includes field $field...\n" );
514 - $info = wfGetDB( DB_MASTER )->indexInfo( $table, $index, __METHOD__ );
515 - if ( $info ) {
516 - foreach ( $info as $row ) {
517 - if ( $row->Column_name == $field ) {
518 - wfOut( "...index $index on table $table seems to be ok\n" );
519 - return true;
520 - }
521 - }
522 - }
523 - wfOut( "...index $index on table $table has no field $field; adding\n" );
524 - return false;
525 -}
526 -
527 -function do_backlinking_indices_update() {
528 - wfOut( "Checking for backlinking indices...\n" );
529 - if ( !index_has_field( 'pagelinks', 'pl_namespace', 'pl_from' ) ||
530 - !index_has_field( 'templatelinks', 'tl_namespace', 'tl_from' ) ||
531 - !index_has_field( 'imagelinks', 'il_to', 'il_from' ) )
532 - {
533 - wfGetDB( DB_MASTER )->sourceFile( archive( 'patch-backlinkindexes.sql' ) );
534 - wfOut( "...backlinking indices updated\n" );
535 - }
536 -}
537 -
538 -function do_categorylinks_indices_update() {
539 - wfOut( "Checking for categorylinks indices...\n" );
540 - if ( !index_has_field( 'categorylinks', 'cl_sortkey', 'cl_from' ) )
541 - {
542 - wfGetDB( DB_MASTER )->sourceFile( archive( 'patch-categorylinksindex.sql' ) );
543 - wfOut( "...categorylinks indices updated\n" );
544 - }
545 -}
546 -
547 -function do_filearchive_indices_update() {
548 - $dbw = wfGetDB( DB_MASTER );
549 - wfOut( "Checking filearchive indices...\n" );
550 - $info = $dbw->indexInfo( 'filearchive', 'fa_user_timestamp', __METHOD__ );
551 - if ( !$info )
552 - {
553 - $dbw->sourceFile( archive( 'patch-filearchive-user-index.sql' ) );
554 - wfOut( "...filearchive indices updated\n" );
555 - }
556 -}
557 -
558 -function maybe_do_profiling_memory_update() {
559 - $dbw = wfGetDB( DB_MASTER );
560 - if ( !$dbw->tableExists( 'profiling' ) ) {
561 - // Simply ignore
562 - } elseif ( $dbw->fieldExists( 'profiling', 'pf_memory' ) ) {
563 - wfOut( "...profiling table has pf_memory field.\n" );
564 - } else {
565 - wfOut( "Adding pf_memory field to table profiling..." );
566 - $dbw->sourceFile( archive( 'patch-profiling-memory.sql' ) );
567 - wfOut( "ok\n" );
568 - }
569 -}
570 -
571 -function do_active_users_init() {
572 - $dbw = wfGetDB( DB_MASTER );
573 - $activeUsers = $dbw->selectField( 'site_stats', 'ss_active_users', false, __METHOD__ );
574 - if ( $activeUsers == -1 ) {
575 - $activeUsers = $dbw->selectField( 'recentchanges',
576 - 'COUNT( DISTINCT rc_user_text )',
577 - array( 'rc_user != 0', 'rc_bot' => 0, "rc_log_type != 'newusers'" ), __METHOD__
578 - );
579 - $dbw->update( 'site_stats',
580 - array( 'ss_active_users' => intval( $activeUsers ) ),
581 - array( 'ss_row_id' => 1 ), __METHOD__, array( 'LIMIT' => 1 )
582 - );
583 - }
584 - wfOut( "...ss_active_users user count set...\n" );
585 -}
586 -
587 -/**
588 - * Adding page_restrictions table, obsoleting page.page_restrictions.
589 - * Migrating old restrictions to new table
590 - * -- Andrew Garrett, January 2007.
591 - */
592 -function do_restrictions_update() {
593 - $dbw = wfGetDB( DB_MASTER );
594 - if ( $dbw->tableExists( 'page_restrictions' ) ) {
595 - wfOut( "...page_restrictions table already exists.\n" );
596 - } else {
597 - wfOut( "Creating page_restrictions table..." );
598 - $dbw->sourceFile( archive( 'patch-page_restrictions.sql' ) );
599 - $dbw->sourceFile( archive( 'patch-page_restrictions_sortkey.sql' ) );
600 - wfOut( "ok\n" );
601 -
602 - wfOut( "Migrating old restrictions to new table...\n" );
603 - $task = new UpdateRestrictions();
604 - $task->execute();
605 - }
606 -}
607 -
608 -function do_category_population() {
609 - if ( update_row_exists( 'populate category' ) ) {
610 - wfOut( "...category table already populated.\n" );
611 - return;
612 - }
613 -
614 - wfOut(
615 - "Populating category table, printing progress markers. " .
616 - "For large databases, you\n" .
617 - "may want to hit Ctrl-C and do this manually with maintenance/\n" .
618 - "populateCategory.php.\n"
619 - );
620 - $task = new PopulateCategory();
621 - $task->execute();
622 - wfOut( "Done populating category table.\n" );
623 -}
624 -
625 -function do_populate_parent_id() {
626 - if ( update_row_exists( 'populate rev_parent_id' ) ) {
627 - wfOut( "...rev_parent_id column already populated.\n" );
628 - return;
629 - }
630 -
631 - $task = new PopulateParentId();
632 - $task->execute();
633 -}
634 -
635 -function do_populate_rev_len() {
636 - if ( update_row_exists( 'populate rev_len' ) ) {
637 - wfOut( "...rev_len column already populated.\n" );
638 - return;
639 - }
640 -
641 - $task = new PopulateRevisionLength();
642 - $task->execute();
643 -}
644 -
645 -function do_cl_fields_update() {
646 - if ( update_row_exists( 'cl_fields_update' ) ) {
647 - wfOut( "...categorylinks up-to-date.\n" );
648 - return;
649 - }
650 - wfOut( 'Updating categorylinks (again)...' );
651 - wfGetDB( DB_MASTER )->sourceFile( archive( 'patch-categorylinks-better-collation2.sql' ) );
652 - wfOut( "done.\n" );
653 -}
654 -
655 -function do_collation_update() {
656 - global $wgCategoryCollation;
657 - $dbw = wfGetDB( DB_MASTER );
658 - if ( $dbw->selectField(
659 - 'categorylinks',
660 - 'COUNT(*)',
661 - 'cl_collation != ' . $dbw->addQuotes( $wgCategoryCollation ),
662 - __FUNCTION__
663 - ) == 0 ) {
664 - wfOut( "...collations up-to-date.\n" );
665 - return;
666 - }
667 -
668 - $task = new UpdateCollation();
669 - $task->execute();
670 -}
671 -
672 -function do_unique_pl_tl_il() {
673 - $dbw = wfGetDB( DB_MASTER );
674 - $info = $dbw->indexInfo( 'pagelinks', 'pl_namespace' );
675 - if ( is_array( $info ) && !$info[0]->Non_unique ) {
676 - wfOut( "...pl_namespace, tl_namespace, il_to indices are already UNIQUE.\n" );
677 - } else {
678 - wfOut( "Making pl_namespace, tl_namespace and il_to indices UNIQUE... " );
679 - $dbw->sourceFile( archive( 'patch-pl-tl-il-unique.sql' ) );
680 - wfOut( "ok\n" );
681 - }
682 -}
683 -
684 -function do_log_search_population() {
685 - if ( update_row_exists( 'populate log_search' ) ) {
686 - wfOut( "...log_search table already populated.\n" );
687 - return;
688 - }
689 - wfOut(
690 -"Populating log_search table, printing progress markers. For large\n" .
691 -"databases, you may want to hit Ctrl-C and do this manually with\n" .
692 -"maintenance/populateLogSearch.php.\n" );
693 - $task = new PopulateLogSearch();
694 - $task->execute();
695 - wfOut( "Done populating log_search table.\n" );
696 -}
697 -
698 -function rename_eu_wiki_id() {
699 - $dbw = wfGetDB( DB_MASTER );
700 - if ( $dbw->fieldExists( 'external_user', 'eu_local_id' ) ) {
701 - wfOut( "...eu_wiki_id already renamed to eu_local_id.\n" );
702 - return;
703 - }
704 - wfOut( "Renaming eu_wiki_id -> eu_local_id... " );
705 - $dbw->sourceFile( archive( 'patch-eu_local_id.sql' ) );
706 - wfOut( "ok\n" );
707 -}
708 -
709 -function do_update_transcache_field() {
710 - if ( update_row_exists( 'convert transcache field' ) ) {
711 - wfOut( "...transcache tc_time already converted.\n" );
712 - return;
713 - } else {
714 - wfOut( "Converting tc_time from UNIX epoch to MediaWiki timestamp... " );
715 - wfGetDB( DB_MASTER )->sourceFile( archive( 'patch-tc-timestamp.sql' ) );
716 - wfOut( "ok\n" );
717 - }
718 -}
719 -
720 -function do_update_mime_minor_field() {
721 - if ( update_row_exists( 'mime_minor_length' ) ) {
722 - wfOut( "...*_mime_minor fields are already long enough.\n" );
723 - } else {
724 - wfOut( "Altering all *_mime_minor fields to 100 bytes in size ... " );
725 - wfGetDB( DB_MASTER )->sourceFile( archive( 'patch-mime_minor_length.sql' ) );
726 - wfOut( "ok\n" );
727 - }
728 -}
Index: trunk/phase3/maintenance/sqlite/archives/patch-categorylinks-better-collation.sql
@@ -0,0 +1,7 @@
 2+ALTER TABLE /*_*/categorylinks ADD COLUMN cl_sortkey_prefix TEXT binary NOT NULL default '';
 3+ALTER TABLE /*_*/categorylinks ADD COLUMN cl_collation BLOB NOT NULL default '';
 4+ALTER TABLE /*_*/categorylinks ADD COLUMN cl_type ENUM('page', 'subcat', 'file') NOT NULL default 'page';
 5+CREATE INDEX cl_collation ON /*_*/categorylinks (cl_collation);
 6+DROP INDEX cl_sortkey;
 7+CREATE INDEX cl_sortkey ON /*_*/categorylinks (cl_to, cl_type, cl_sortkey, cl_from);
 8+INSERT IGNORE INTO /*_*/updatelog (ul_key) VALUES ('cl_fields_update');
Property changes on: trunk/phase3/maintenance/sqlite/archives/patch-categorylinks-better-collation.sql
___________________________________________________________________
Added: svn:eol-style
19 + native
Index: trunk/phase3/maintenance/install-utils.inc
@@ -189,19 +189,9 @@
190190 }
191191 }
192192
193 -/**
194 - * Helper function: check if the given key is present in the updatelog table.
195 - * Obviously, only use this for updates that occur after the updatelog table was
196 - * created!
197 - */
198 -function update_row_exists( $key ) {
199 - $row = wfGetDB( DB_MASTER )->selectRow(
200 - 'updatelog',
201 - '1',
202 - array( 'ul_key' => $key ),
203 - __FUNCTION__
204 - );
205 - return (bool)$row;
 193+function archive( $name ) {
 194+ wfDeprecated( __METHOD__ );
 195+ return DatabaseBase::patchPath( $name );
206196 }
207197
208198 /**
Index: trunk/phase3/includes/installer/DatabaseUpdater.php
@@ -123,8 +123,7 @@
124124 * @param $purge Boolean: whether to clear the objectcache table after updates
125125 */
126126 public function doUpdates( $purge = true ) {
127 - global $IP, $wgVersion;
128 - require_once( "$IP/maintenance/updaters.inc" );
 127+ global $wgVersion;
129128
130129 $this->runUpdates( $this->getCoreUpdateList(), false );
131130 $this->runUpdates( $this->getOldGlobalUpdates(), false );
@@ -170,6 +169,21 @@
171170 }
172171
173172 /**
 173+ * Helper function: check if the given key is present in the updatelog table.
 174+ * Obviously, only use this for updates that occur after the updatelog table was
 175+ * created!
 176+ */
 177+ public function updateRowExists( $key ) {
 178+ $row = $this->db->selectRow(
 179+ 'updatelog',
 180+ '1',
 181+ array( 'ul_key' => $key ),
 182+ __METHOD__
 183+ );
 184+ return (bool)$row;
 185+ }
 186+
 187+ /**
174188 * Updatelog was changed in 1.17 to have a ul_value column so we can record
175189 * more information about what kind of updates we've done (that's what this
176190 * class does). Pre-1.17 wikis won't have this column, and really old wikis
@@ -395,4 +409,62 @@
396410 SiteStatsInit::doAllAndCommit( false );
397411 }
398412
 413+ # Common updater functions
 414+
 415+ protected function doActiveUsersInit() {
 416+ $activeUsers = $this->db->selectField( 'site_stats', 'ss_active_users', false, __METHOD__ );
 417+ if ( $activeUsers == -1 ) {
 418+ $activeUsers = $this->db->selectField( 'recentchanges',
 419+ 'COUNT( DISTINCT rc_user_text )',
 420+ array( 'rc_user != 0', 'rc_bot' => 0, "rc_log_type != 'newusers'" ), __METHOD__
 421+ );
 422+ $this->db->update( 'site_stats',
 423+ array( 'ss_active_users' => intval( $activeUsers ) ),
 424+ array( 'ss_row_id' => 1 ), __METHOD__, array( 'LIMIT' => 1 )
 425+ );
 426+ }
 427+ wfOut( "...ss_active_users user count set...\n" );
 428+ }
 429+
 430+ protected function doLogSearchPopulation() {
 431+ if ( $this->updateRowExists( 'populate log_search' ) ) {
 432+ wfOut( "...log_search table already populated.\n" );
 433+ return;
 434+ }
 435+
 436+ wfOut(
 437+ "Populating log_search table, printing progress markers. For large\n" .
 438+ "databases, you may want to hit Ctrl-C and do this manually with\n" .
 439+ "maintenance/populateLogSearch.php.\n" );
 440+ $task = new PopulateLogSearch();
 441+ $task->execute();
 442+ wfOut( "Done populating log_search table.\n" );
 443+ }
 444+
 445+ function doUpdateTranscacheField() {
 446+ if ( $this->updateRowExists( 'convert transcache field' ) ) {
 447+ wfOut( "...transcache tc_time already converted.\n" );
 448+ return;
 449+ }
 450+
 451+ wfOut( "Converting tc_time from UNIX epoch to MediaWiki timestamp... " );
 452+ $this->applyPatch( 'patch-tc-timestamp.sql' );
 453+ wfOut( "ok\n" );
 454+ }
 455+
 456+ protected function doCollationUpdate() {
 457+ global $wgCategoryCollation;
 458+ if ( $this->db->selectField(
 459+ 'categorylinks',
 460+ 'COUNT(*)',
 461+ 'cl_collation != ' . $this->db->addQuotes( $wgCategoryCollation ),
 462+ __METHOD__
 463+ ) == 0 ) {
 464+ wfOut( "...collations up-to-date.\n" );
 465+ return;
 466+ }
 467+
 468+ $task = new UpdateCollation();
 469+ $task->execute();
 470+ }
399471 }
Index: trunk/phase3/includes/installer/MysqlUpdater.php
@@ -19,8 +19,8 @@
2020 // 1.2
2121 array( 'addField', 'ipblocks', 'ipb_id', 'patch-ipblocks.sql' ),
2222 array( 'addField', 'ipblocks', 'ipb_expiry', 'patch-ipb_expiry.sql' ),
23 - array( 'do_interwiki_update' ),
24 - array( 'do_index_update' ),
 23+ array( 'doInterwikiUpdate' ),
 24+ array( 'doIndexUpdate' ),
2525 array( 'addTable', 'hitcounter', 'patch-hitcounter.sql' ),
2626 array( 'addField', 'recentchanges', 'rc_type', 'patch-rc_type.sql' ),
2727
@@ -29,24 +29,24 @@
3030 array( 'addTable', 'querycache', 'patch-querycache.sql' ),
3131 array( 'addTable', 'objectcache', 'patch-objectcache.sql' ),
3232 array( 'addTable', 'categorylinks', 'patch-categorylinks.sql' ),
33 - array( 'do_old_links_update' ),
34 - array( 'fix_ancient_imagelinks' ),
 33+ array( 'doOldLinksUpdate' ),
 34+ array( 'doFixAncientImagelinks' ),
3535 array( 'addField', 'recentchanges', 'rc_ip', 'patch-rc_ip.sql' ),
3636
3737 // 1.4
38 - array( 'do_image_name_unique_update' ),
 38+ array( 'addIndex', 'image', 'PRIMARY', 'patch-image_name_primary.sql' ),
3939 array( 'addField', 'recentchanges', 'rc_id', 'patch-rc_id.sql' ),
4040 array( 'addField', 'recentchanges', 'rc_patrolled', 'patch-rc-patrol.sql' ),
4141 array( 'addTable', 'logging', 'patch-logging.sql' ),
4242 array( 'addField', 'user', 'user_token', 'patch-user_token.sql' ),
4343 array( 'addField', 'watchlist', 'wl_notificationtimestamp', 'patch-email-notification.sql' ),
44 - array( 'do_watchlist_update' ),
 44+ array( 'doWatchlistUpdate' ),
4545 array( 'dropField', 'user', 'user_emailauthenticationtimestamp', 'patch-email-authentication.sql' ),
4646
4747 // 1.5
48 - array( 'do_schema_restructuring' ),
 48+ array( 'doSchemaRestructuring' ),
4949 array( 'addField', 'logging', 'log_params', 'patch-log_params.sql' ),
50 - array( 'check_bin', 'logging', 'log_title', 'patch-logging-title.sql', ),
 50+ array( 'checkBin', 'logging', 'log_title', 'patch-logging-title.sql', ),
5151 array( 'addField', 'archive', 'ar_rev_id', 'patch-archive-rev_id.sql' ),
5252 array( 'addField', 'page', 'page_len', 'patch-page_len.sql' ),
5353 array( 'dropField', 'revision', 'inverse_timestamp', 'patch-inverse_timestamp.sql' ),
@@ -58,10 +58,10 @@
5959 array( 'addField', 'archive', 'ar_text_id', 'patch-archive-text_id.sql' ),
6060 array( 'doNamespaceSize' ),
6161 array( 'addField', 'image', 'img_media_type', 'patch-img_media_type.sql' ),
62 - array( 'do_pagelinks_update' ),
 62+ array( 'doPagelinksUpdate' ),
6363 array( 'dropField', 'image', 'img_type', 'patch-drop_img_type.sql' ),
64 - array( 'do_user_unique_update' ),
65 - array( 'do_user_groups_update' ),
 64+ array( 'doUserUniqueUpdate' ),
 65+ array( 'doUserGroupsUpdate' ),
6666 array( 'addField', 'site_stats', 'ss_total_pages', 'patch-ss_total_articles.sql' ),
6767 array( 'addTable', 'user_newtalk', 'patch-usernewtalk2.sql' ),
6868 array( 'addTable', 'transcache', 'patch-transcache.sql' ),
@@ -69,12 +69,12 @@
7070 array( 'addTable', 'trackbacks', 'patch-trackbacks.sql' ),
7171
7272 // 1.6
73 - array( 'do_watchlist_null' ),
 73+ array( 'doWatchlistNull' ),
7474 array( 'addIndex', 'logging', 'times', 'patch-logging-times-index.sql' ),
7575 array( 'addField', 'ipblocks', 'ipb_range_start', 'patch-ipb_range_start.sql' ),
76 - array( 'do_page_random_update' ),
 76+ array( 'doPageRandomUpdate' ),
7777 array( 'addField', 'user', 'user_registration', 'patch-user_registration.sql' ),
78 - array( 'do_templatelinks_update' ),
 78+ array( 'doTemplatelinksUpdate' ),
7979 array( 'addTable', 'externallinks', 'patch-externallinks.sql' ),
8080 array( 'addTable', 'job', 'patch-job.sql' ),
8181 array( 'addField', 'site_stats', 'ss_images', 'patch-ss_images.sql' ),
@@ -82,19 +82,20 @@
8383 array( 'addTable', 'querycache_info', 'patch-querycacheinfo.sql' ),
8484 array( 'addTable', 'filearchive', 'patch-filearchive.sql' ),
8585 array( 'addField', 'ipblocks', 'ipb_anon_only', 'patch-ipb_anon_only.sql' ),
86 - array( 'do_rc_indices_update' ),
 86+ array( 'addIndex', 'recentchanges', 'rc_ns_usertext', 'patch-recentchanges-utindex.sql' ),
 87+ array( 'addIndex', 'recentchanges', 'rc_user_text', 'patch-rc_user_text-index.sql' ),
8788
8889 // 1.9
8990 array( 'addField', 'user', 'user_newpass_time', 'patch-user_newpass_time.sql' ),
9091 array( 'addTable', 'redirect', 'patch-redirect.sql' ),
9192 array( 'addTable', 'querycachetwo', 'patch-querycachetwo.sql' ),
9293 array( 'addField', 'ipblocks', 'ipb_enable_autoblock', 'patch-ipb_optional_autoblock.sql' ),
93 - array( 'do_backlinking_indices_update' ),
 94+ array( 'doBacklinkingIndicesUpdate' ),
9495 array( 'addField', 'recentchanges', 'rc_old_len', 'patch-rc_len.sql' ),
9596 array( 'addField', 'user', 'user_editcount', 'patch-user_editcount.sql' ),
9697
9798 // 1.10
98 - array( 'do_restrictions_update' ),
 99+ array( 'doRestrictionsUpdate' ),
99100 array( 'addField', 'logging', 'log_id', 'patch-log_id.sql' ),
100101 array( 'addField', 'revision', 'rev_parent_id', 'patch-rev_parent_id.sql' ),
101102 array( 'addField', 'page_restrictions', 'pr_id', 'patch-page_restrictions_sortkey.sql' ),
@@ -108,7 +109,7 @@
109110
110111 // 1.11
111112 array( 'addField', 'ipblocks', 'ipb_block_email', 'patch-ipb_emailban.sql' ),
112 - array( 'do_categorylinks_indices_update' ),
 113+ array( 'doCategorylinksIndicesUpdate' ),
113114 array( 'addField', 'oldimage', 'oi_metadata', 'patch-oi_metadata.sql' ),
114115 array( 'addIndex', 'archive', 'usertext_timestamp', 'patch-archive-user-index.sql' ),
115116 array( 'addIndex', 'image', 'img_usertext_timestamp', 'patch-image-user-index.sql' ),
@@ -124,21 +125,21 @@
125126 array( 'addTable', 'page_props', 'patch-page_props.sql' ),
126127 array( 'addTable', 'updatelog', 'patch-updatelog.sql' ),
127128 array( 'addTable', 'category', 'patch-category.sql' ),
128 - array( 'do_category_population' ),
 129+ array( 'doCategoryPopulation' ),
129130 array( 'addField', 'archive', 'ar_parent_id', 'patch-ar_parent_id.sql' ),
130131 array( 'addField', 'user_newtalk', 'user_last_timestamp', 'patch-user_last_timestamp.sql' ),
131 - array( 'do_populate_parent_id' ),
132 - array( 'check_bin', 'protected_titles', 'pt_title', 'patch-pt_title-encoding.sql', ),
133 - array( 'maybe_do_profiling_memory_update' ),
134 - array( 'do_filearchive_indices_update' ),
 132+ array( 'doPopulateParentId' ),
 133+ array( 'checkBin', 'protected_titles', 'pt_title', 'patch-pt_title-encoding.sql', ),
 134+ array( 'doMaybeProfilingMemoryUpdate' ),
 135+ array( 'doFilearchiveIndicesUpdate' ),
135136
136137 // 1.14
137138 array( 'addField', 'site_stats', 'ss_active_users', 'patch-ss_active_users.sql' ),
138 - array( 'do_active_users_init' ),
 139+ array( 'doActiveUsersInit' ),
139140 array( 'addField', 'ipblocks', 'ipb_allow_usertalk', 'patch-ipb_allow_usertalk.sql' ),
140141
141142 // 1.15
142 - array( 'do_unique_pl_tl_il' ),
 143+ array( 'doUniquePlTlIl' ),
143144 array( 'addTable', 'change_tag', 'patch-change_tag.sql' ),
144145 array( 'addTable', 'tag_summary', 'patch-change_tag.sql' ),
145146 array( 'addTable', 'valid_tag', 'patch-change_tag.sql' ),
@@ -146,17 +147,17 @@
147148 // 1.16
148149 array( 'addTable', 'user_properties', 'patch-user_properties.sql' ),
149150 array( 'addTable', 'log_search', 'patch-log_search.sql' ),
150 - array( 'do_log_search_population' ),
 151+ array( 'doLogSearchPopulation' ),
151152 array( 'addField', 'logging', 'log_user_text', 'patch-log_user_text.sql' ),
152153 array( 'addTable', 'l10n_cache', 'patch-l10n_cache.sql' ),
153154 array( 'addTable', 'external_user', 'patch-external_user.sql' ),
154155 array( 'addIndex', 'log_search', 'ls_field_val', 'patch-log_search-rename-index.sql' ),
155156 array( 'addIndex', 'change_tag', 'change_tag_rc_tag', 'patch-change_tag-indexes.sql' ),
156157 array( 'addField', 'redirect', 'rd_interwiki', 'patch-rd_interwiki.sql' ),
157 - array( 'do_update_transcache_field' ),
158 - array( 'rename_eu_wiki_id' ),
159 - array( 'do_update_mime_minor_field' ),
160 - array( 'do_populate_rev_len' ),
 158+ array( 'doUpdateTranscacheField' ),
 159+ array( 'renameEuWikiId' ),
 160+ array( 'doUpdateMimeMinorField' ),
 161+ array( 'doPopulateRevLen' ),
161162
162163 // 1.17
163164 array( 'addTable', 'iwlinks', 'patch-iwlinks.sql' ),
@@ -166,13 +167,296 @@
167168 array( 'dropIndex', 'iwlinks', 'iwl_prefix', 'patch-kill-iwl_prefix.sql' ),
168169 array( 'dropIndex', 'iwlinks', 'iwl_prefix_from_title', 'patch-kill-iwl_pft.sql' ),
169170 array( 'addField', 'categorylinks', 'cl_collation', 'patch-categorylinks-better-collation.sql' ),
170 - array( 'do_cl_fields_update' ),
171 - array( 'do_collation_update' ),
 171+ array( 'doClFieldsUpdate' ),
 172+ array( 'doCollationUpdate' ),
172173 array( 'addTable', 'msg_resource', 'patch-msg_resource.sql' ),
173174 array( 'addTable', 'module_deps', 'patch-module_deps.sql' ),
174175 );
175176 }
176177
 178+ /**
 179+ * 1.4 betas were missing the 'binary' marker from logging.log_title,
 180+ * which causes a collation mismatch error on joins in MySQL 4.1.
 181+ *
 182+ * @param $table String: table name
 183+ * @param $field String: field name to check
 184+ * @param $patchFile String: path to the patch to correct the field
 185+ */
 186+ protected function checkBin( $table, $field, $patchFile ) {
 187+ $tableName = $this->db->tableName( $table );
 188+ $res = $this->db->query( "SELECT $field FROM $tableName LIMIT 0", __METHOD__ );
 189+ $flags = explode( ' ', mysql_field_flags( $res->result, 0 ) );
 190+
 191+ if ( in_array( 'binary', $flags ) ) {
 192+ wfOut( "...$table table has correct $field encoding.\n" );
 193+ } else {
 194+ wfOut( "Fixing $field encoding on $table table... " );
 195+ $this->db->applyPatch( $patchFile );
 196+ wfOut( "ok\n" );
 197+ }
 198+ }
 199+
 200+ /**
 201+ * Check whether an index contain a field
 202+ *
 203+ * @param $table String: table name
 204+ * @param $index String: index name to check
 205+ * @param $field String: field that should be in the index
 206+ * @return Boolean
 207+ */
 208+ protected function indexHasField( $table, $index, $field ) {
 209+ $info = $this->db->indexInfo( $table, $index, __METHOD__ );
 210+ if ( $info ) {
 211+ foreach ( $info as $row ) {
 212+ if ( $row->Column_name == $field ) {
 213+ wfOut( "...index $index on table $table includes field $field\n" );
 214+ return true;
 215+ }
 216+ }
 217+ }
 218+ wfOut( "...index $index on table $table has no field $field; adding\n" );
 219+ return false;
 220+ }
 221+
 222+ /**
 223+ * Check that interwiki table exists; if it doesn't source it
 224+ */
 225+ protected function doInterwikiUpdate() {
 226+ global $IP;
 227+
 228+ if ( $this->db->tableExists( "interwiki" ) ) {
 229+ wfOut( "...already have interwiki table\n" );
 230+ return;
 231+ }
 232+
 233+ wfOut( 'Creating interwiki table...' );
 234+ $this->applyPatch( 'patch-interwiki.sql' );
 235+ wfOut( "ok\n" );
 236+ wfOut( 'Adding default interwiki definitions...' );
 237+ $this->applyPatch( "$IP/maintenance/interwiki.sql", true );
 238+ wfOut( "ok\n" );
 239+ }
 240+
 241+ /**
 242+ * Check that proper indexes are in place
 243+ */
 244+ protected function doIndexUpdate() {
 245+ $meta = $this->db->fieldInfo( 'recentchanges', 'rc_timestamp' );
 246+ if ( $meta->isMultipleKey() ) {
 247+ wfOut( "...indexes seem up to 20031107 standards\n" );
 248+ return;
 249+ }
 250+
 251+ wfOut( "Updating indexes to 20031107..." );
 252+ $this->applyPatch( 'patch-indexes.sql', true );
 253+ wfOut( "ok\n" );
 254+ }
 255+
 256+ protected function doOldLinksUpdate() {
 257+ $cl = new ConvertLinks();
 258+ $cl->execute();
 259+ }
 260+
 261+ protected function doFixAncientImagelinks() {
 262+ $info = $this->db->fieldInfo( 'imagelinks', 'il_from' );
 263+ if ( !$info || $info->type() !== 'string' ) {
 264+ wfOut( "...il_from OK\n" );
 265+ return;
 266+ }
 267+
 268+ wfOut( "Fixing ancient broken imagelinks table.\n" );
 269+ wfOut( "NOTE: you will have to run maintenance/refreshLinks.php after this.\n" );
 270+ $this->applyPatch( 'patch-fix-il_from.sql' );
 271+ wfOut( "ok\n" );
 272+ }
 273+
 274+ /**
 275+ * Check if we need to add talk page rows to the watchlist
 276+ */
 277+ function doWatchlistUpdate() {
 278+ $talk = $this->db->selectField( 'watchlist', 'count(*)', 'wl_namespace & 1', __METHOD__ );
 279+ $nontalk = $this->db->selectField( 'watchlist', 'count(*)', 'NOT (wl_namespace & 1)', __METHOD__ );
 280+ if ( $talk == $nontalk ) {
 281+ wfOut( "...watchlist talk page rows already present\n" );
 282+ return;
 283+ }
 284+
 285+ wfOut( "Adding missing watchlist talk page rows... " );
 286+ $this->db->insertSelect( 'watchlist', 'watchlist',
 287+ array(
 288+ 'wl_user' => 'wl_user',
 289+ 'wl_namespace' => 'wl_namespace | 1',
 290+ 'wl_title' => 'wl_title',
 291+ 'wl_notificationtimestamp' => 'wl_notificationtimestamp'
 292+ ), array( 'NOT (wl_namespace & 1)' ), __METHOD__, 'IGNORE' );
 293+ wfOut( "ok\n" );
 294+ }
 295+
 296+ function doSchemaRestructuring() {
 297+ if ( $this->db->tableExists( 'page' ) ) {
 298+ wfOut( "...page table already exists.\n" );
 299+ return;
 300+ }
 301+
 302+ wfOut( "...converting from cur/old to page/revision/text DB structure.\n" );
 303+ wfOut( wfTimestamp( TS_DB ) );
 304+ wfOut( "......checking for duplicate entries.\n" );
 305+
 306+ list ( $cur, $old, $page, $revision, $text ) = $this->db->tableNamesN( 'cur', 'old', 'page', 'revision', 'text' );
 307+
 308+ $rows = $this->db->query( "SELECT cur_title, cur_namespace, COUNT(cur_namespace) AS c
 309+ FROM $cur GROUP BY cur_title, cur_namespace HAVING c>1", __METHOD__ );
 310+
 311+ if ( $rows->numRows() > 0 ) {
 312+ wfOut( wfTimestamp( TS_DB ) );
 313+ wfOut( "......<b>Found duplicate entries</b>\n" );
 314+ wfOut( sprintf( "<b> %-60s %3s %5s</b>\n", 'Title', 'NS', 'Count' ) );
 315+ foreach ( $rows as $row ) {
 316+ if ( ! isset( $duplicate[$row->cur_namespace] ) ) {
 317+ $duplicate[$row->cur_namespace] = array();
 318+ }
 319+ $duplicate[$row->cur_namespace][] = $row->cur_title;
 320+ wfOut( sprintf( " %-60s %3s %5s\n", $row->cur_title, $row->cur_namespace, $row->c ) );
 321+ }
 322+ $sql = "SELECT cur_title, cur_namespace, cur_id, cur_timestamp FROM $cur WHERE ";
 323+ $firstCond = true;
 324+ foreach ( $duplicate as $ns => $titles ) {
 325+ if ( $firstCond ) {
 326+ $firstCond = false;
 327+ } else {
 328+ $sql .= ' OR ';
 329+ }
 330+ $sql .= "( cur_namespace = {$ns} AND cur_title in (";
 331+ $first = true;
 332+ foreach ( $titles as $t ) {
 333+ if ( $first ) {
 334+ $sql .= $this->db->addQuotes( $t );
 335+ $first = false;
 336+ } else {
 337+ $sql .= ', ' . $this->db->addQuotes( $t );
 338+ }
 339+ }
 340+ $sql .= ") ) \n";
 341+ }
 342+ # By sorting descending, the most recent entry will be the first in the list.
 343+ # All following entries will be deleted by the next while-loop.
 344+ $sql .= 'ORDER BY cur_namespace, cur_title, cur_timestamp DESC';
 345+
 346+ $rows = $this->db->query( $sql, __METHOD__ );
 347+
 348+ $prev_title = $prev_namespace = false;
 349+ $deleteId = array();
 350+
 351+ foreach ( $rows as $row ) {
 352+ if ( $prev_title == $row->cur_title && $prev_namespace == $row->cur_namespace ) {
 353+ $deleteId[] = $row->cur_id;
 354+ }
 355+ $prev_title = $row->cur_title;
 356+ $prev_namespace = $row->cur_namespace;
 357+ }
 358+ $sql = "DELETE FROM $cur WHERE cur_id IN ( " . join( ',', $deleteId ) . ')';
 359+ $rows = $this->db->query( $sql, __METHOD__ );
 360+ wfOut( wfTimestamp( TS_DB ) );
 361+ wfOut( "......<b>Deleted</b> " . $this->db->affectedRows() . " records.\n" );
 362+ }
 363+
 364+
 365+ wfOut( wfTimestamp( TS_DB ) );
 366+ wfOut( "......Creating tables.\n" );
 367+ $this->db->query( "CREATE TABLE $page (
 368+ page_id int(8) unsigned NOT NULL auto_increment,
 369+ page_namespace int NOT NULL,
 370+ page_title varchar(255) binary NOT NULL,
 371+ page_restrictions tinyblob NOT NULL,
 372+ page_counter bigint(20) unsigned NOT NULL default '0',
 373+ page_is_redirect tinyint(1) unsigned NOT NULL default '0',
 374+ page_is_new tinyint(1) unsigned NOT NULL default '0',
 375+ page_random real unsigned NOT NULL,
 376+ page_touched char(14) binary NOT NULL default '',
 377+ page_latest int(8) unsigned NOT NULL,
 378+ page_len int(8) unsigned NOT NULL,
 379+
 380+ PRIMARY KEY page_id (page_id),
 381+ UNIQUE INDEX name_title (page_namespace,page_title),
 382+ INDEX (page_random),
 383+ INDEX (page_len)
 384+ ) ENGINE=InnoDB", __METHOD__ );
 385+ $this->db->query( "CREATE TABLE $revision (
 386+ rev_id int(8) unsigned NOT NULL auto_increment,
 387+ rev_page int(8) unsigned NOT NULL,
 388+ rev_comment tinyblob NOT NULL,
 389+ rev_user int(5) unsigned NOT NULL default '0',
 390+ rev_user_text varchar(255) binary NOT NULL default '',
 391+ rev_timestamp char(14) binary NOT NULL default '',
 392+ rev_minor_edit tinyint(1) unsigned NOT NULL default '0',
 393+ rev_deleted tinyint(1) unsigned NOT NULL default '0',
 394+ rev_len int(8) unsigned,
 395+ rev_parent_id int(8) unsigned default NULL,
 396+ PRIMARY KEY rev_page_id (rev_page, rev_id),
 397+ UNIQUE INDEX rev_id (rev_id),
 398+ INDEX rev_timestamp (rev_timestamp),
 399+ INDEX page_timestamp (rev_page,rev_timestamp),
 400+ INDEX user_timestamp (rev_user,rev_timestamp),
 401+ INDEX usertext_timestamp (rev_user_text,rev_timestamp)
 402+ ) ENGINE=InnoDB", __METHOD__ );
 403+
 404+ wfOut( wfTimestamp( TS_DB ) );
 405+ wfOut( "......Locking tables.\n" );
 406+ $this->db->query( "LOCK TABLES $page WRITE, $revision WRITE, $old WRITE, $cur WRITE", __METHOD__ );
 407+
 408+ $maxold = intval( $this->db->selectField( 'old', 'max(old_id)', '', __METHOD__ ) );
 409+ wfOut( wfTimestamp( TS_DB ) );
 410+ wfOut( "......maxold is {$maxold}\n" );
 411+
 412+ wfOut( wfTimestamp( TS_DB ) );
 413+ global $wgLegacySchemaConversion;
 414+ if ( $wgLegacySchemaConversion ) {
 415+ // Create HistoryBlobCurStub entries.
 416+ // Text will be pulled from the leftover 'cur' table at runtime.
 417+ wfOut( "......Moving metadata from cur; using blob references to text in cur table.\n" );
 418+ $cur_text = "concat('O:18:\"historyblobcurstub\":1:{s:6:\"mCurId\";i:',cur_id,';}')";
 419+ $cur_flags = "'object'";
 420+ } else {
 421+ // Copy all cur text in immediately: this may take longer but avoids
 422+ // having to keep an extra table around.
 423+ wfOut( "......Moving text from cur.\n" );
 424+ $cur_text = 'cur_text';
 425+ $cur_flags = "''";
 426+ }
 427+ $this->db->query( "INSERT INTO $old (old_namespace, old_title, old_text, old_comment, old_user, old_user_text,
 428+ old_timestamp, old_minor_edit, old_flags)
 429+ SELECT cur_namespace, cur_title, $cur_text, cur_comment, cur_user, cur_user_text, cur_timestamp, cur_minor_edit, $cur_flags
 430+ FROM $cur", __METHOD__ );
 431+
 432+ wfOut( wfTimestamp( TS_DB ) );
 433+ wfOut( "......Setting up revision table.\n" );
 434+ $this->db->query( "INSERT INTO $revision (rev_id, rev_page, rev_comment, rev_user, rev_user_text, rev_timestamp,
 435+ rev_minor_edit)
 436+ SELECT old_id, cur_id, old_comment, old_user, old_user_text,
 437+ old_timestamp, old_minor_edit
 438+ FROM $old,$cur WHERE old_namespace=cur_namespace AND old_title=cur_title", __METHOD__ );
 439+
 440+ wfOut( wfTimestamp( TS_DB ) );
 441+ wfOut( "......Setting up page table.\n" );
 442+ $this->db->query( "INSERT INTO $page (page_id, page_namespace, page_title, page_restrictions, page_counter,
 443+ page_is_redirect, page_is_new, page_random, page_touched, page_latest, page_len)
 444+ SELECT cur_id, cur_namespace, cur_title, cur_restrictions, cur_counter, cur_is_redirect, cur_is_new,
 445+ cur_random, cur_touched, rev_id, LENGTH(cur_text)
 446+ FROM $cur,$revision
 447+ WHERE cur_id=rev_page AND rev_timestamp=cur_timestamp AND rev_id > {$maxold}", __METHOD__ );
 448+
 449+ wfOut( wfTimestamp( TS_DB ) );
 450+ wfOut( "......Unlocking tables.\n" );
 451+ $this->db->query( "UNLOCK TABLES", __METHOD__ );
 452+
 453+ wfOut( wfTimestamp( TS_DB ) );
 454+ wfOut( "......Renaming old.\n" );
 455+ $this->db->query( "ALTER TABLE $old RENAME TO $text", __METHOD__ );
 456+
 457+ wfOut( wfTimestamp( TS_DB ) );
 458+ wfOut( "...done.\n" );
 459+ }
 460+
177461 protected function doNamespaceSize() {
178462 $tables = array(
179463 'page' => 'page',
@@ -198,4 +482,330 @@
199483 }
200484 }
201485 }
 486+
 487+ protected function doPagelinksUpdate() {
 488+ if ( $this->db->tableExists( 'pagelinks' ) ) {
 489+ wfOut( "...already have pagelinks table.\n" );
 490+ return;
 491+ }
 492+
 493+ wfOut( "Converting links and brokenlinks tables to pagelinks... " );
 494+ $this->applyPatch( 'patch-pagelinks.sql' );
 495+ wfOut( "ok\n" );
 496+
 497+ global $wgContLang;
 498+ foreach ( MWNamespace::getCanonicalNamespaces() as $ns => $name ) {
 499+ if ( $ns == 0 ) {
 500+ continue;
 501+ }
 502+
 503+ wfOut( "Cleaning up broken links for namespace $ns... " );
 504+
 505+ $pagelinks = $this->db->tableName( 'pagelinks' );
 506+ $name = $wgContLang->getNsText( $ns );
 507+ $prefix = $this->db->strencode( $name );
 508+ $likeprefix = str_replace( '_', '\\_', $prefix );
 509+
 510+ $sql = "UPDATE $pagelinks
 511+ SET pl_namespace=$ns,
 512+ pl_title=TRIM(LEADING '$prefix:' FROM pl_title)
 513+ WHERE pl_namespace=0
 514+ AND pl_title LIKE '$likeprefix:%'";
 515+
 516+ $this->db->query( $sql, __METHOD__ );
 517+ wfOut( "ok\n" );
 518+ }
 519+ }
 520+
 521+ protected function doUserUniqueUpdate() {
 522+ $duper = new UserDupes( $this->db );
 523+ if ( $duper->hasUniqueIndex() ) {
 524+ wfOut( "...already have unique user_name index.\n" );
 525+ return;
 526+ }
 527+
 528+ if ( !$duper->clearDupes() ) {
 529+ wfOut( "WARNING: This next step will probably fail due to unfixed duplicates...\n" );
 530+ }
 531+ wfOut( "Adding unique index on user_name... " );
 532+ $this->applyPatch( 'patch-user_nameindex.sql' );
 533+ wfOut( "ok\n" );
 534+ }
 535+
 536+ protected function doUserGroupsUpdate() {
 537+ if ( $this->db->tableExists( 'user_groups' ) ) {
 538+ $info = $this->db->fieldInfo( 'user_groups', 'ug_group' );
 539+ if ( $info->type() == 'int' ) {
 540+ $oldug = $this->db->tableName( 'user_groups' );
 541+ $newug = $this->db->tableName( 'user_groups_bogus' );
 542+ wfOut( "user_groups table exists but is in bogus intermediate format. Renaming to $newug... " );
 543+ $this->db->query( "ALTER TABLE $oldug RENAME TO $newug", __METHOD__ );
 544+ wfOut( "ok\n" );
 545+
 546+ wfOut( "Re-adding fresh user_groups table... " );
 547+ $this->applyPatch( 'patch-user_groups.sql' );
 548+ wfOut( "ok\n" );
 549+
 550+ wfOut( "***\n" );
 551+ wfOut( "*** WARNING: You will need to manually fix up user permissions in the user_groups\n" );
 552+ wfOut( "*** table. Old 1.5 alpha versions did some pretty funky stuff...\n" );
 553+ wfOut( "***\n" );
 554+ } else {
 555+ wfOut( "...user_groups table exists and is in current format.\n" );
 556+ }
 557+ return;
 558+ }
 559+
 560+ wfOut( "Adding user_groups table... " );
 561+ $this->applyPatch( 'patch-user_groups.sql' );
 562+ wfOut( "ok\n" );
 563+
 564+ if ( !$this->db->tableExists( 'user_rights' ) ) {
 565+ if ( $this->db->fieldExists( 'user', 'user_rights' ) ) {
 566+ wfOut( "Upgrading from a 1.3 or older database? Breaking out user_rights for conversion..." );
 567+ $this->db->applyPatch( 'patch-user_rights.sql' );
 568+ wfOut( "ok\n" );
 569+ } else {
 570+ wfOut( "*** WARNING: couldn't locate user_rights table or field for upgrade.\n" );
 571+ wfOut( "*** You may need to manually configure some sysops by manipulating\n" );
 572+ wfOut( "*** the user_groups table.\n" );
 573+ return;
 574+ }
 575+ }
 576+
 577+ wfOut( "Converting user_rights table to user_groups... " );
 578+ $result = $this->db->select( 'user_rights',
 579+ array( 'ur_user', 'ur_rights' ),
 580+ array( "ur_rights != ''" ),
 581+ __METHOD__ );
 582+
 583+ foreach ( $result as $row ) {
 584+ $groups = array_unique(
 585+ array_map( 'trim',
 586+ explode( ',', $row->ur_rights ) ) );
 587+
 588+ foreach ( $groups as $group ) {
 589+ $this->db->insert( 'user_groups',
 590+ array(
 591+ 'ug_user' => $row->ur_user,
 592+ 'ug_group' => $group ),
 593+ __METHOD__ );
 594+ }
 595+ }
 596+ wfOut( "ok\n" );
 597+ }
 598+
 599+ /**
 600+ * Make sure wl_notificationtimestamp can be NULL,
 601+ * and update old broken items.
 602+ */
 603+ protected function doWatchlistNull() {
 604+ $info = $this->db->fieldInfo( 'watchlist', 'wl_notificationtimestamp' );
 605+ if ( $info->nullable() ) {
 606+ wfOut( "...wl_notificationtimestamp is already nullable.\n" );
 607+ return;
 608+ }
 609+
 610+ wfOut( "Making wl_notificationtimestamp nullable... " );
 611+ $this->applyPatch( 'patch-watchlist-null.sql' );
 612+ wfOut( "ok\n" );
 613+ }
 614+
 615+ /**
 616+ * Set page_random field to a random value where it is equals to 0.
 617+ *
 618+ * @see bug 3946
 619+ */
 620+ protected function doPageRandomUpdate() {
 621+ wfOut( "Setting page_random to a random value on rows where it equals 0..." );
 622+
 623+ $page = $this->db->tableName( 'page' );
 624+ $this->db->query( "UPDATE $page SET page_random = RAND() WHERE page_random = 0", __METHOD__ );
 625+ $rows = $this->db->affectedRows();
 626+
 627+ wfOut( "changed $rows rows\n" );
 628+ }
 629+
 630+ protected function doTemplatelinksUpdate() {
 631+ if ( $this->db->tableExists( 'templatelinks' ) ) {
 632+ wfOut( "...templatelinks table already exists\n" );
 633+ return;
 634+ }
 635+
 636+ wfOut( "Creating templatelinks table...\n" );
 637+ $this->applyPatch( 'patch-templatelinks.sql' );
 638+ wfOut( "Populating...\n" );
 639+ if ( wfGetLB()->getServerCount() > 1 ) {
 640+ // Slow, replication-friendly update
 641+ $res = $this->db->select( 'pagelinks', array( 'pl_from', 'pl_namespace', 'pl_title' ),
 642+ array( 'pl_namespace' => NS_TEMPLATE ), __METHOD__ );
 643+ $count = 0;
 644+ foreach ( $res as $row ) {
 645+ $count = ( $count + 1 ) % 100;
 646+ if ( $count == 0 ) {
 647+ wfWaitForSlaves( 10 );
 648+ }
 649+ $this->db->insert( 'templatelinks',
 650+ array(
 651+ 'tl_from' => $row->pl_from,
 652+ 'tl_namespace' => $row->pl_namespace,
 653+ 'tl_title' => $row->pl_title,
 654+ ), __METHOD__
 655+ );
 656+
 657+ }
 658+ } else {
 659+ // Fast update
 660+ $this->db->insertSelect( 'templatelinks', 'pagelinks',
 661+ array(
 662+ 'tl_from' => 'pl_from',
 663+ 'tl_namespace' => 'pl_namespace',
 664+ 'tl_title' => 'pl_title'
 665+ ), array(
 666+ 'pl_namespace' => 10
 667+ ), __METHOD__
 668+ );
 669+ }
 670+ wfOut( "Done. Please run maintenance/refreshLinks.php for a more thorough templatelinks update.\n" );
 671+ }
 672+
 673+ protected function doBacklinkingIndicesUpdate() {
 674+ if ( !$this->indexHasField( 'pagelinks', 'pl_namespace', 'pl_from' ) ||
 675+ !$this->indexHasField( 'templatelinks', 'tl_namespace', 'tl_from' ) ||
 676+ !$this->indexHasField( 'imagelinks', 'il_to', 'il_from' ) )
 677+ {
 678+ $this->applyPatch( 'patch-backlinkindexes.sql' );
 679+ wfOut( "...backlinking indices updated\n" );
 680+ }
 681+ }
 682+
 683+ /**
 684+ * Adding page_restrictions table, obsoleting page.page_restrictions.
 685+ * Migrating old restrictions to new table
 686+ * -- Andrew Garrett, January 2007.
 687+ */
 688+ protected function doRestrictionsUpdate() {
 689+ if ( $this->db->tableExists( 'page_restrictions' ) ) {
 690+ wfOut( "...page_restrictions table already exists.\n" );
 691+ return;
 692+ }
 693+
 694+ wfOut( "Creating page_restrictions table..." );
 695+ $this->applyPatch( 'patch-page_restrictions.sql' );
 696+ $this->applyPatch( 'patch-page_restrictions_sortkey.sql' );
 697+ wfOut( "ok\n" );
 698+
 699+ wfOut( "Migrating old restrictions to new table...\n" );
 700+ $task = new UpdateRestrictions();
 701+ $task->execute();
 702+ }
 703+
 704+ protected function doCategorylinksIndicesUpdate() {
 705+ if ( !$this->indexHasField( 'categorylinks', 'cl_sortkey', 'cl_from' ) ) {
 706+ $this->applyPatch( 'patch-categorylinksindex.sql' );
 707+ wfOut( "...categorylinks indices updated\n" );
 708+ }
 709+ }
 710+
 711+ protected function doCategoryPopulation() {
 712+ if ( $this->updateRowExists( 'populate category' ) ) {
 713+ wfOut( "...category table already populated.\n" );
 714+ return;
 715+ }
 716+
 717+ wfOut(
 718+ "Populating category table, printing progress markers. " .
 719+ "For large databases, you\n" .
 720+ "may want to hit Ctrl-C and do this manually with maintenance/\n" .
 721+ "populateCategory.php.\n"
 722+ );
 723+ $task = new PopulateCategory();
 724+ $task->execute();
 725+ wfOut( "Done populating category table.\n" );
 726+ }
 727+
 728+ protected function doPopulateParentId() {
 729+ if ( $this->updateRowExists( 'populate rev_parent_id' ) ) {
 730+ wfOut( "...rev_parent_id column already populated.\n" );
 731+ return;
 732+ }
 733+
 734+ $task = new PopulateParentId();
 735+ $task->execute();
 736+ }
 737+
 738+ protected function doMaybeProfilingMemoryUpdate() {
 739+ if ( !$this->db->tableExists( 'profiling' ) ) {
 740+ // Simply ignore
 741+ } elseif ( $this->db->fieldExists( 'profiling', 'pf_memory' ) ) {
 742+ wfOut( "...profiling table has pf_memory field.\n" );
 743+ } else {
 744+ wfOut( "Adding pf_memory field to table profiling..." );
 745+ $this->applyPatch( 'patch-profiling-memory.sql' );
 746+ wfOut( "ok\n" );
 747+ }
 748+ }
 749+
 750+ protected function doFilearchiveIndicesUpdate() {
 751+ $info = $this->db->indexInfo( 'filearchive', 'fa_user_timestamp', __METHOD__ );
 752+ if ( !$info ) {
 753+ $this->applyPatch( 'patch-filearchive-user-index.sql' );
 754+ wfOut( "...filearchive indices updated\n" );
 755+ }
 756+ }
 757+
 758+ protected function doUniquePlTlIl() {
 759+ $info = $this->db->indexInfo( 'pagelinks', 'pl_namespace' );
 760+ if ( is_array( $info ) && !$info[0]->Non_unique ) {
 761+ wfOut( "...pl_namespace, tl_namespace, il_to indices are already UNIQUE.\n" );
 762+ return;
 763+ }
 764+
 765+ wfOut( "Making pl_namespace, tl_namespace and il_to indices UNIQUE... " );
 766+ $this->applyPatch( 'patch-pl-tl-il-unique.sql' );
 767+ wfOut( "ok\n" );
 768+ }
 769+
 770+ protected function renameEuWikiId() {
 771+ if ( $this->db->fieldExists( 'external_user', 'eu_local_id' ) ) {
 772+ wfOut( "...eu_wiki_id already renamed to eu_local_id.\n" );
 773+ return;
 774+ }
 775+
 776+ wfOut( "Renaming eu_wiki_id -> eu_local_id... " );
 777+ $this->applyPatch( 'patch-eu_local_id.sql' );
 778+ wfOut( "ok\n" );
 779+ }
 780+
 781+ protected function doUpdateMimeMinorField() {
 782+ if ( $this->updateRowExists( 'mime_minor_length' ) ) {
 783+ wfOut( "...*_mime_minor fields are already long enough.\n" );
 784+ return;
 785+ }
 786+
 787+ wfOut( "Altering all *_mime_minor fields to 100 bytes in size ... " );
 788+ $this->applyPatch( 'patch-mime_minor_length.sql' );
 789+ wfOut( "ok\n" );
 790+ }
 791+
 792+ protected function doPopulateRevLen() {
 793+ if ( $this->updateRowExists( 'populate rev_len' ) ) {
 794+ wfOut( "...rev_len column already populated.\n" );
 795+ return;
 796+ }
 797+
 798+ $task = new PopulateRevisionLength();
 799+ $task->execute();
 800+ }
 801+
 802+ protected function doClFieldsUpdate() {
 803+ if ( $this->updateRowExists( 'cl_fields_update' ) ) {
 804+ wfOut( "...categorylinks up-to-date.\n" );
 805+ return;
 806+ }
 807+
 808+ wfOut( 'Updating categorylinks (again)...' );
 809+ $this->applyPatch( 'patch-categorylinks-better-collation2.sql' );
 810+ wfOut( "done.\n" );
 811+ }
202812 }
Index: trunk/phase3/includes/installer/SqliteUpdater.php
@@ -18,7 +18,7 @@
1919 return array(
2020 // 1.14
2121 array( 'addField', 'site_stats', 'ss_active_users', 'patch-ss_active_users.sql' ),
22 - array( 'do_active_users_init' ),
 22+ array( 'doActiveUsersInit' ),
2323 array( 'addField', 'ipblocks', 'ipb_allow_usertalk', 'patch-ipb_allow_usertalk.sql' ),
2424 array( 'sqliteInitialIndexes' ),
2525
@@ -30,14 +30,14 @@
3131 // 1.16
3232 array( 'addTable', 'user_properties', 'patch-user_properties.sql' ),
3333 array( 'addTable', 'log_search', 'patch-log_search.sql' ),
34 - array( 'do_log_search_population' ),
 34+ array( 'doLogSearchPopulation' ),
3535 array( 'addField', 'logging', 'log_user_text', 'patch-log_user_text.sql' ),
3636 array( 'addTable', 'l10n_cache', 'patch-l10n_cache.sql' ),
3737 array( 'addTable', 'external_user', 'patch-external_user.sql' ),
3838 array( 'addIndex', 'log_search', 'ls_field_val', 'patch-log_search-rename-index.sql' ),
3939 array( 'addIndex', 'change_tag', 'change_tag_rc_tag', 'patch-change_tag-indexes.sql' ),
4040 array( 'addField', 'redirect', 'rd_interwiki', 'patch-rd_interwiki.sql' ),
41 - array( 'do_update_transcache_field' ),
 41+ array( 'doUpdateTranscacheField' ),
4242 array( 'sqliteSetupSearchindex' ),
4343
4444 // 1.17
@@ -47,6 +47,8 @@
4848 array( 'addField', 'interwiki', 'iw_api', 'patch-iw_api_and_wikiid.sql' ),
4949 array( 'dropIndex', 'iwlinks', 'iwl_prefix', 'patch-kill-iwl_prefix.sql' ),
5050 array( 'dropIndex', 'iwlinks', 'iwl_prefix_from_title', 'patch-kill-iwl_pft.sql' ),
 51+ array( 'addField', 'categorylinks', 'cl_collation', 'patch-categorylinks-better-collation.sql' ),
 52+ array( 'doCollationUpdate' ),
5153 array( 'addTable', 'msg_resource', 'patch-msg_resource.sql' ),
5254 array( 'addTable', 'module_deps', 'patch-module_deps.sql' ),
5355 );
@@ -54,7 +56,7 @@
5557
5658 protected function sqliteInitialIndexes() {
5759 // initial-indexes.sql fails if the indexes are already present, so we perform a quick check if our database is newer.
58 - if ( update_row_exists( 'initial_indexes' ) || $this->db->indexExists( 'user', 'user_name' ) ) {
 60+ if ( $this->updateRowExists( 'initial_indexes' ) || $this->db->indexExists( 'user', 'user_name' ) ) {
5961 wfOut( "...have initial indexes\n" );
6062 return;
6163 }
@@ -65,7 +67,7 @@
6668
6769 protected function sqliteSetupSearchindex() {
6870 $module = $this->db->getFulltextSearchModule();
69 - $fts3tTable = update_row_exists( 'fts3' );
 71+ $fts3tTable = $this->updateRowExists( 'fts3' );
7072 if ( $fts3tTable && !$module ) {
7173 wfOut( '...PHP is missing FTS3 support, downgrading tables...' );
7274 $this->applyPatch( 'searchindex-no-fts.sql' );

Follow-up revisions

RevisionCommit summaryAuthorDate
r72871Follow-up r72870: converted CodeReview's LoadExtensionSchemaUpdates hook to n...ialex16:28, 12 September 2010
r72873Fix for r72870: seems I didn't see that updaters.inc was included in the conf...ialex17:13, 12 September 2010
r72878Follow-up r72870: fixed patch file so that it actually works, switched it to ...maxsem17:48, 12 September 2010

Status & tagging log