33 array(
'disableContentHandlerUseDB' ),
36 array(
'addField',
'ipblocks',
'ipb_id',
'patch-ipblocks.sql' ),
37 array(
'addField',
'ipblocks',
'ipb_expiry',
'patch-ipb_expiry.sql' ),
38 array(
'doInterwikiUpdate' ),
39 array(
'doIndexUpdate' ),
40 array(
'addTable',
'hitcounter',
'patch-hitcounter.sql' ),
41 array(
'addField',
'recentchanges',
'rc_type',
'patch-rc_type.sql' ),
42 array(
'addIndex',
'recentchanges',
'new_name_timestamp',
'patch-rc-newindex.sql' ),
45 array(
'addField',
'user',
'user_real_name',
'patch-user-realname.sql' ),
46 array(
'addTable',
'querycache',
'patch-querycache.sql' ),
47 array(
'addTable',
'objectcache',
'patch-objectcache.sql' ),
48 array(
'addTable',
'categorylinks',
'patch-categorylinks.sql' ),
49 array(
'doOldLinksUpdate' ),
50 array(
'doFixAncientImagelinks' ),
51 array(
'addField',
'recentchanges',
'rc_ip',
'patch-rc_ip.sql' ),
54 array(
'addIndex',
'image',
'PRIMARY',
'patch-image_name_primary.sql' ),
55 array(
'addField',
'recentchanges',
'rc_id',
'patch-rc_id.sql' ),
56 array(
'addField',
'recentchanges',
'rc_patrolled',
'patch-rc-patrol.sql' ),
57 array(
'addTable',
'logging',
'patch-logging.sql' ),
58 array(
'addField',
'user',
'user_token',
'patch-user_token.sql' ),
59 array(
'addField',
'watchlist',
'wl_notificationtimestamp',
'patch-email-notification.sql' ),
60 array(
'doWatchlistUpdate' ),
61 array(
'dropField',
'user',
'user_emailauthenticationtimestamp',
62 'patch-email-authentication.sql' ),
65 array(
'doSchemaRestructuring' ),
66 array(
'addField',
'logging',
'log_params',
'patch-log_params.sql' ),
67 array(
'checkBin',
'logging',
'log_title',
'patch-logging-title.sql', ),
68 array(
'addField',
'archive',
'ar_rev_id',
'patch-archive-rev_id.sql' ),
69 array(
'addField',
'page',
'page_len',
'patch-page_len.sql' ),
70 array(
'dropField',
'revision',
'inverse_timestamp',
'patch-inverse_timestamp.sql' ),
71 array(
'addField',
'revision',
'rev_text_id',
'patch-rev_text_id.sql' ),
72 array(
'addField',
'revision',
'rev_deleted',
'patch-rev_deleted.sql' ),
73 array(
'addField',
'image',
'img_width',
'patch-img_width.sql' ),
74 array(
'addField',
'image',
'img_metadata',
'patch-img_metadata.sql' ),
75 array(
'addField',
'user',
'user_email_token',
'patch-user_email_token.sql' ),
76 array(
'addField',
'archive',
'ar_text_id',
'patch-archive-text_id.sql' ),
77 array(
'doNamespaceSize' ),
78 array(
'addField',
'image',
'img_media_type',
'patch-img_media_type.sql' ),
79 array(
'doPagelinksUpdate' ),
80 array(
'dropField',
'image',
'img_type',
'patch-drop_img_type.sql' ),
81 array(
'doUserUniqueUpdate' ),
82 array(
'doUserGroupsUpdate' ),
83 array(
'addField',
'site_stats',
'ss_total_pages',
'patch-ss_total_articles.sql' ),
84 array(
'addTable',
'user_newtalk',
'patch-usernewtalk2.sql' ),
85 array(
'addTable',
'transcache',
'patch-transcache.sql' ),
86 array(
'addField',
'interwiki',
'iw_trans',
'patch-interwiki-trans.sql' ),
89 array(
'doWatchlistNull' ),
90 array(
'addIndex',
'logging',
'times',
'patch-logging-times-index.sql' ),
91 array(
'addField',
'ipblocks',
'ipb_range_start',
'patch-ipb_range_start.sql' ),
92 array(
'doPageRandomUpdate' ),
93 array(
'addField',
'user',
'user_registration',
'patch-user_registration.sql' ),
94 array(
'doTemplatelinksUpdate' ),
95 array(
'addTable',
'externallinks',
'patch-externallinks.sql' ),
96 array(
'addTable',
'job',
'patch-job.sql' ),
97 array(
'addField',
'site_stats',
'ss_images',
'patch-ss_images.sql' ),
98 array(
'addTable',
'langlinks',
'patch-langlinks.sql' ),
99 array(
'addTable',
'querycache_info',
'patch-querycacheinfo.sql' ),
100 array(
'addTable',
'filearchive',
'patch-filearchive.sql' ),
101 array(
'addField',
'ipblocks',
'ipb_anon_only',
'patch-ipb_anon_only.sql' ),
102 array(
'addIndex',
'recentchanges',
'rc_ns_usertext',
'patch-recentchanges-utindex.sql' ),
103 array(
'addIndex',
'recentchanges',
'rc_user_text',
'patch-rc_user_text-index.sql' ),
106 array(
'addField',
'user',
'user_newpass_time',
'patch-user_newpass_time.sql' ),
107 array(
'addTable',
'redirect',
'patch-redirect.sql' ),
108 array(
'addTable',
'querycachetwo',
'patch-querycachetwo.sql' ),
109 array(
'addField',
'ipblocks',
'ipb_enable_autoblock',
'patch-ipb_optional_autoblock.sql' ),
110 array(
'doBacklinkingIndicesUpdate' ),
111 array(
'addField',
'recentchanges',
'rc_old_len',
'patch-rc_len.sql' ),
112 array(
'addField',
'user',
'user_editcount',
'patch-user_editcount.sql' ),
115 array(
'doRestrictionsUpdate' ),
116 array(
'addField',
'logging',
'log_id',
'patch-log_id.sql' ),
117 array(
'addField',
'revision',
'rev_parent_id',
'patch-rev_parent_id.sql' ),
118 array(
'addField',
'page_restrictions',
'pr_id',
'patch-page_restrictions_sortkey.sql' ),
119 array(
'addField',
'revision',
'rev_len',
'patch-rev_len.sql' ),
120 array(
'addField',
'recentchanges',
'rc_deleted',
'patch-rc_deleted.sql' ),
121 array(
'addField',
'logging',
'log_deleted',
'patch-log_deleted.sql' ),
122 array(
'addField',
'archive',
'ar_deleted',
'patch-ar_deleted.sql' ),
123 array(
'addField',
'ipblocks',
'ipb_deleted',
'patch-ipb_deleted.sql' ),
124 array(
'addField',
'filearchive',
'fa_deleted',
'patch-fa_deleted.sql' ),
125 array(
'addField',
'archive',
'ar_len',
'patch-ar_len.sql' ),
128 array(
'addField',
'ipblocks',
'ipb_block_email',
'patch-ipb_emailban.sql' ),
129 array(
'doCategorylinksIndicesUpdate' ),
130 array(
'addField',
'oldimage',
'oi_metadata',
'patch-oi_metadata.sql' ),
131 array(
'addIndex',
'archive',
'usertext_timestamp',
'patch-archive-user-index.sql' ),
132 array(
'addIndex',
'image',
'img_usertext_timestamp',
'patch-image-user-index.sql' ),
133 array(
'addIndex',
'oldimage',
'oi_usertext_timestamp',
'patch-oldimage-user-index.sql' ),
134 array(
'addField',
'archive',
'ar_page_id',
'patch-archive-page_id.sql' ),
135 array(
'addField',
'image',
'img_sha1',
'patch-img_sha1.sql' ),
138 array(
'addTable',
'protected_titles',
'patch-protected_titles.sql' ),
141 array(
'addField',
'ipblocks',
'ipb_by_text',
'patch-ipb_by_text.sql' ),
142 array(
'addTable',
'page_props',
'patch-page_props.sql' ),
143 array(
'addTable',
'updatelog',
'patch-updatelog.sql' ),
144 array(
'addTable',
'category',
'patch-category.sql' ),
145 array(
'doCategoryPopulation' ),
146 array(
'addField',
'archive',
'ar_parent_id',
'patch-ar_parent_id.sql' ),
147 array(
'addField',
'user_newtalk',
'user_last_timestamp',
'patch-user_last_timestamp.sql' ),
148 array(
'doPopulateParentId' ),
149 array(
'checkBin',
'protected_titles',
'pt_title',
'patch-pt_title-encoding.sql', ),
150 array(
'doMaybeProfilingMemoryUpdate' ),
151 array(
'doFilearchiveIndicesUpdate' ),
154 array(
'addField',
'site_stats',
'ss_active_users',
'patch-ss_active_users.sql' ),
155 array(
'doActiveUsersInit' ),
156 array(
'addField',
'ipblocks',
'ipb_allow_usertalk',
'patch-ipb_allow_usertalk.sql' ),
159 array(
'doUniquePlTlIl' ),
160 array(
'addTable',
'change_tag',
'patch-change_tag.sql' ),
161 array(
'addTable',
'tag_summary',
'patch-tag_summary.sql' ),
162 array(
'addTable',
'valid_tag',
'patch-valid_tag.sql' ),
165 array(
'addTable',
'user_properties',
'patch-user_properties.sql' ),
166 array(
'addTable',
'log_search',
'patch-log_search.sql' ),
167 array(
'addField',
'logging',
'log_user_text',
'patch-log_user_text.sql' ),
168 # listed separately
from the previous update because 1.16 was released without
this update
169 array(
'doLogUsertextPopulation' ),
170 array(
'doLogSearchPopulation' ),
171 array(
'addTable',
'l10n_cache',
'patch-l10n_cache.sql' ),
172 array(
'addIndex',
'log_search',
'ls_field_val',
'patch-log_search-rename-index.sql' ),
173 array(
'addIndex',
'change_tag',
'change_tag_rc_tag',
'patch-change_tag-indexes.sql' ),
174 array(
'addField',
'redirect',
'rd_interwiki',
'patch-rd_interwiki.sql' ),
175 array(
'doUpdateTranscacheField' ),
176 array(
'doUpdateMimeMinorField' ),
179 array(
'addTable',
'iwlinks',
'patch-iwlinks.sql' ),
180 array(
'addIndex',
'iwlinks',
'iwl_prefix_title_from',
'patch-rename-iwl_prefix.sql' ),
181 array(
'addField',
'updatelog',
'ul_value',
'patch-ul_value.sql' ),
182 array(
'addField',
'interwiki',
'iw_api',
'patch-iw_api_and_wikiid.sql' ),
183 array(
'dropIndex',
'iwlinks',
'iwl_prefix',
'patch-kill-iwl_prefix.sql' ),
184 array(
'addField',
'categorylinks',
'cl_collation',
'patch-categorylinks-better-collation.sql' ),
185 array(
'doClFieldsUpdate' ),
186 array(
'doCollationUpdate' ),
187 array(
'addTable',
'msg_resource',
'patch-msg_resource.sql' ),
188 array(
'addTable',
'module_deps',
'patch-module_deps.sql' ),
189 array(
'dropIndex',
'archive',
'ar_page_revid',
'patch-archive_kill_ar_page_revid.sql' ),
190 array(
'addIndex',
'archive',
'ar_revid',
'patch-archive_ar_revid.sql' ),
191 array(
'doLangLinksLengthUpdate' ),
194 array(
'doUserNewTalkTimestampNotNull' ),
195 array(
'addIndex',
'user',
'user_email',
'patch-user_email_index.sql' ),
196 array(
'modifyField',
'user_properties',
'up_property',
'patch-up_property.sql' ),
197 array(
'addTable',
'uploadstash',
'patch-uploadstash.sql' ),
198 array(
'addTable',
'user_former_groups',
'patch-user_former_groups.sql' ),
201 array(
'addIndex',
'logging',
'type_action',
'patch-logging-type-action-index.sql' ),
202 array(
'addField',
'revision',
'rev_sha1',
'patch-rev_sha1.sql' ),
203 array(
'doMigrateUserOptions' ),
204 array(
'dropField',
'user',
'user_options',
'patch-drop-user_options.sql' ),
205 array(
'addField',
'archive',
'ar_sha1',
'patch-ar_sha1.sql' ),
206 array(
'addIndex',
'page',
'page_redirect_namespace_len',
207 'patch-page_redirect_namespace_len.sql' ),
208 array(
'addField',
'uploadstash',
'us_chunk_inx',
'patch-uploadstash_chunk.sql' ),
209 array(
'addfield',
'job',
'job_timestamp',
'patch-jobs-add-timestamp.sql' ),
212 array(
'addIndex',
'revision',
'page_user_timestamp',
'patch-revision-user-page-index.sql' ),
213 array(
'addField',
'ipblocks',
'ipb_parent_block_id',
'patch-ipb-parent-block-id.sql' ),
214 array(
'addIndex',
'ipblocks',
'ipb_parent_block_id',
'patch-ipb-parent-block-id-index.sql' ),
215 array(
'dropField',
'category',
'cat_hidden',
'patch-cat_hidden.sql' ),
218 array(
'addField',
'revision',
'rev_content_format',
'patch-revision-rev_content_format.sql' ),
219 array(
'addField',
'revision',
'rev_content_model',
'patch-revision-rev_content_model.sql' ),
220 array(
'addField',
'archive',
'ar_content_format',
'patch-archive-ar_content_format.sql' ),
221 array(
'addField',
'archive',
'ar_content_model',
'patch-archive-ar_content_model.sql' ),
222 array(
'addField',
'page',
'page_content_model',
'patch-page-page_content_model.sql' ),
223 array(
'enableContentHandlerUseDB' ),
224 array(
'dropField',
'site_stats',
'ss_admins',
'patch-drop-ss_admins.sql' ),
225 array(
'dropField',
'recentchanges',
'rc_moved_to_title',
'patch-rc_moved.sql' ),
226 array(
'addTable',
'sites',
'patch-sites.sql' ),
227 array(
'addField',
'filearchive',
'fa_sha1',
'patch-fa_sha1.sql' ),
228 array(
'addField',
'job',
'job_token',
'patch-job_token.sql' ),
229 array(
'addField',
'job',
'job_attempts',
'patch-job_attempts.sql' ),
230 array(
'doEnableProfiling' ),
231 array(
'addField',
'uploadstash',
'us_props',
'patch-uploadstash-us_props.sql' ),
232 array(
'modifyField',
'user_groups',
'ug_group',
'patch-ug_group-length-increase-255.sql' ),
233 array(
'modifyField',
'user_former_groups',
'ufg_group',
234 'patch-ufg_group-length-increase-255.sql' ),
235 array(
'addIndex',
'page_props',
'pp_propname_page',
236 'patch-page_props-propname-page-index.sql' ),
237 array(
'addIndex',
'image',
'img_media_mime',
'patch-img_media_mime-index.sql' ),
240 array(
'doIwlinksIndexNonUnique' ),
241 array(
'addIndex',
'iwlinks',
'iwl_prefix_from_title',
242 'patch-iwlinks-from-title-index.sql' ),
243 array(
'addField',
'archive',
'ar_id',
'patch-archive-ar_id.sql' ),
244 array(
'addField',
'externallinks',
'el_id',
'patch-externallinks-el_id.sql' ),
247 array(
'addField',
'recentchanges',
'rc_source',
'patch-rc_source.sql' ),
248 array(
'addIndex',
'logging',
'log_user_text_type_time',
249 'patch-logging_user_text_type_time_index.sql' ),
250 array(
'addIndex',
'logging',
'log_user_text_time',
'patch-logging_user_text_time_index.sql' ),
251 array(
'addField',
'page',
'page_links_updated',
'patch-page_links_updated.sql' ),
252 array(
'addField',
'user',
'user_password_expires',
'patch-user_password_expire.sql' ),
265 protected function checkBin( $table, $field, $patchFile ) {
266 if ( !$this->
doTable( $table ) ) {
271 $fieldInfo = $this->db->fieldInfo( $table, $field );
272 if ( $fieldInfo->isBinary() ) {
273 $this->
output(
"...$table table has correct $field encoding.\n" );
275 $this->
applyPatch( $patchFile,
false,
"Fixing $field encoding on $table table" );
288 if ( !$this->
doTable( $table ) ) {
292 $info = $this->db->indexInfo( $table, $index, __METHOD__ );
294 foreach ( $info
as $row ) {
295 if ( $row->Column_name == $field ) {
296 $this->
output(
"...index $index on table $table includes field $field.\n" );
302 $this->
output(
"...index $index on table $table has no field $field; added.\n" );
313 if ( !$this->
doTable(
'interwiki' ) ) {
317 if ( $this->db->tableExists(
"interwiki", __METHOD__ ) ) {
318 $this->
output(
"...already have interwiki table\n" );
323 $this->
applyPatch(
'patch-interwiki.sql',
false,
'Creating interwiki table' );
325 "$IP/maintenance/interwiki.sql",
327 'Adding default interwiki definitions'
335 $meta = $this->db->fieldInfo(
'recentchanges',
'rc_timestamp' );
336 if ( $meta ===
false ) {
337 throw new MWException(
'Missing rc_timestamp field of recentchanges table. Should not happen.' );
339 if ( $meta->isMultipleKey() ) {
340 $this->
output(
"...indexes seem up to 20031107 standards.\n" );
345 $this->
applyPatch(
'patch-indexes.sql',
true,
"Updating indexes to 20031107" );
349 $cl = $this->maintenance->runChild(
'ConvertLinks' );
354 $info = $this->db->fieldInfo(
'imagelinks',
'il_from' );
355 if ( !$info || $info->type() !==
'string' ) {
356 $this->
output(
"...il_from OK\n" );
362 'patch-fix-il_from.sql',
364 'Fixing ancient broken imagelinks table.'
368 $this->
output(
"NOTE: you will have to run maintenance/refreshLinks.php after this." );
376 $talk = $this->db->selectField(
'watchlist',
'count(*)',
'wl_namespace & 1', __METHOD__ );
377 $nontalk = $this->db->selectField(
380 'NOT (wl_namespace & 1)',
383 if ( $talk == $nontalk ) {
384 $this->
output(
"...watchlist talk page rows already present.\n" );
389 $this->
output(
"Adding missing watchlist talk page rows... " );
390 $this->db->insertSelect(
'watchlist',
'watchlist',
392 'wl_user' =>
'wl_user',
393 'wl_namespace' =>
'wl_namespace | 1',
394 'wl_title' =>
'wl_title',
395 'wl_notificationtimestamp' =>
'wl_notificationtimestamp'
396 ),
array(
'NOT (wl_namespace & 1)' ), __METHOD__,
'IGNORE' );
397 $this->
output(
"done.\n" );
399 $this->
output(
"Adding missing watchlist subject page rows... " );
400 $this->db->insertSelect(
'watchlist',
'watchlist',
402 'wl_user' =>
'wl_user',
403 'wl_namespace' =>
'wl_namespace & ~1',
404 'wl_title' =>
'wl_title',
405 'wl_notificationtimestamp' =>
'wl_notificationtimestamp'
406 ),
array(
'wl_namespace & 1' ), __METHOD__,
'IGNORE' );
407 $this->
output(
"done.\n" );
411 if ( $this->db->tableExists(
'page', __METHOD__ ) ) {
412 $this->
output(
"...page table already exists.\n" );
417 $this->
output(
"...converting from cur/old to page/revision/text DB structure.\n" );
419 $this->
output(
"......checking for duplicate entries.\n" );
421 list( $cur, $old, $page, $revision, $text ) = $this->db->tableNamesN(
429 $rows = $this->db->query(
"
430 SELECT cur_title, cur_namespace, COUNT(cur_namespace) AS c
432 GROUP BY cur_title, cur_namespace
437 if ( $rows->numRows() > 0 ) {
439 $this->
output(
"......<b>Found duplicate entries</b>\n" );
440 $this->
output( sprintf(
"<b> %-60s %3s %5s</b>\n",
'Title',
'NS',
'Count' ) );
441 $duplicate =
array();
442 foreach ( $rows
as $row ) {
443 if ( !isset( $duplicate[$row->cur_namespace] ) ) {
444 $duplicate[$row->cur_namespace] =
array();
447 $duplicate[$row->cur_namespace][] = $row->cur_title;
450 $row->cur_title, $row->cur_namespace,
454 $sql =
"SELECT cur_title, cur_namespace, cur_id, cur_timestamp FROM $cur WHERE ";
456 foreach ( $duplicate
as $ns =>
$titles ) {
462 $sql .=
"( cur_namespace = {$ns} AND cur_title in (";
466 $sql .= $this->db->addQuotes(
$t );
469 $sql .=
', ' . $this->db->addQuotes(
$t );
474 # By sorting descending, the most recent entry will be the first in the list.
475 # All following entries will be deleted by the next while-loop.
476 $sql .=
'ORDER BY cur_namespace, cur_title, cur_timestamp DESC';
478 $rows = $this->db->query( $sql, __METHOD__ );
480 $prev_title = $prev_namespace =
false;
483 foreach ( $rows
as $row ) {
484 if ( $prev_title == $row->cur_title && $prev_namespace == $row->cur_namespace ) {
485 $deleteId[] = $row->cur_id;
487 $prev_title = $row->cur_title;
488 $prev_namespace = $row->cur_namespace;
490 $sql =
"DELETE FROM $cur WHERE cur_id IN ( " . join(
',', $deleteId ) .
')';
491 $this->db->query( $sql, __METHOD__ );
493 $this->
output(
"......<b>Deleted</b> " . $this->db->affectedRows() .
" records.\n" );
497 $this->
output(
"......Creating tables.\n" );
498 $this->db->query(
"CREATE TABLE $page (
499 page_id int(8) unsigned NOT NULL auto_increment,
500 page_namespace int NOT NULL,
501 page_title varchar(255) binary NOT NULL,
502 page_restrictions tinyblob NOT NULL,
503 page_counter bigint(20) unsigned NOT NULL default '0',
504 page_is_redirect tinyint(1) unsigned NOT NULL default '0',
505 page_is_new tinyint(1) unsigned NOT NULL default '0',
506 page_random real unsigned NOT NULL,
507 page_touched char(14) binary NOT NULL default '',
508 page_latest int(8) unsigned NOT NULL,
509 page_len int(8) unsigned NOT NULL,
511 PRIMARY KEY page_id (page_id),
512 UNIQUE INDEX name_title (page_namespace,page_title),
515 ) ENGINE=InnoDB", __METHOD__ );
516 $this->db->query(
"CREATE TABLE $revision (
517 rev_id int(8) unsigned NOT NULL auto_increment,
518 rev_page int(8) unsigned NOT NULL,
519 rev_comment tinyblob NOT NULL,
520 rev_user int(5) unsigned NOT NULL default '0',
521 rev_user_text varchar(255) binary NOT NULL default '',
522 rev_timestamp char(14) binary NOT NULL default '',
523 rev_minor_edit tinyint(1) unsigned NOT NULL default '0',
524 rev_deleted tinyint(1) unsigned NOT NULL default '0',
525 rev_len int(8) unsigned,
526 rev_parent_id int(8) unsigned default NULL,
527 PRIMARY KEY rev_page_id (rev_page, rev_id),
528 UNIQUE INDEX rev_id (rev_id),
529 INDEX rev_timestamp (rev_timestamp),
530 INDEX page_timestamp (rev_page,rev_timestamp),
531 INDEX user_timestamp (rev_user,rev_timestamp),
532 INDEX usertext_timestamp (rev_user_text,rev_timestamp)
533 ) ENGINE=InnoDB", __METHOD__ );
536 $this->
output(
"......Locking tables.\n" );
538 "LOCK TABLES $page WRITE, $revision WRITE, $old WRITE, $cur WRITE",
542 $maxold = intval( $this->db->selectField(
'old',
'max(old_id)',
'', __METHOD__ ) );
544 $this->
output(
"......maxold is {$maxold}\n" );
547 global $wgLegacySchemaConversion;
548 if ( $wgLegacySchemaConversion ) {
551 $this->
output(
"......Moving metadata from cur; using blob references to text in cur table.\n" );
552 $cur_text =
"concat('O:18:\"historyblobcurstub\":1:{s:6:\"mCurId\";i:',cur_id,';}')";
553 $cur_flags =
"'object'";
557 $this->
output(
"......Moving text from cur.\n" );
558 $cur_text =
'cur_text';
562 "INSERT INTO $old (old_namespace, old_title, old_text, old_comment, old_user,
563 old_user_text, old_timestamp, old_minor_edit, old_flags)
564 SELECT cur_namespace, cur_title, $cur_text, cur_comment, cur_user, cur_user_text,
565 cur_timestamp, cur_minor_edit, $cur_flags
571 $this->
output(
"......Setting up revision table.\n" );
573 "INSERT INTO $revision (rev_id, rev_page, rev_comment, rev_user,
574 rev_user_text, rev_timestamp, rev_minor_edit)
575 SELECT old_id, cur_id, old_comment, old_user, old_user_text,
576 old_timestamp, old_minor_edit
577 FROM $old,$cur WHERE old_namespace=cur_namespace AND old_title=cur_title",
582 $this->
output(
"......Setting up page table.\n" );
584 "INSERT INTO $page (page_id, page_namespace, page_title,
585 page_restrictions, page_counter, page_is_redirect, page_is_new, page_random,
586 page_touched, page_latest, page_len)
587 SELECT cur_id, cur_namespace, cur_title, cur_restrictions, cur_counter,
588 cur_is_redirect, cur_is_new, cur_random, cur_touched, rev_id, LENGTH(cur_text)
590 WHERE cur_id=rev_page AND rev_timestamp=cur_timestamp AND rev_id > {$maxold}",
595 $this->
output(
"......Unlocking tables.\n" );
596 $this->db->query(
"UNLOCK TABLES", __METHOD__ );
599 $this->
output(
"......Renaming old.\n" );
600 $this->db->query(
"ALTER TABLE $old RENAME TO $text", __METHOD__ );
603 $this->
output(
"...done.\n" );
610 'recentchanges' =>
'rc',
612 'querycache' =>
'qc',
615 foreach (
$tables as $table => $prefix ) {
616 $field = $prefix .
'_namespace';
618 $tablename = $this->db->tableName( $table );
619 $result = $this->db->query(
"SHOW COLUMNS FROM $tablename LIKE '$field'", __METHOD__ );
620 $info = $this->db->fetchObject(
$result );
622 if ( substr( $info->Type, 0, 3 ) ==
'int' ) {
623 $this->
output(
"...$field is already a full int ($info->Type).\n" );
625 $this->
output(
"Promoting $field from $info->Type to int... " );
626 $this->db->query(
"ALTER TABLE $tablename MODIFY $field int NOT NULL", __METHOD__ );
627 $this->
output(
"done.\n" );
633 if ( $this->db->tableExists(
'pagelinks', __METHOD__ ) ) {
634 $this->
output(
"...already have pagelinks table.\n" );
640 'patch-pagelinks.sql',
642 'Converting links and brokenlinks tables to pagelinks'
651 $this->
output(
"Cleaning up broken links for namespace $ns... " );
653 $pagelinks = $this->db->tableName(
'pagelinks' );
655 $prefix = $this->db->strencode(
$name );
656 $likeprefix = str_replace(
'_',
'\\_', $prefix );
658 $sql =
"UPDATE $pagelinks
659 SET pl_namespace=$ns,
660 pl_title=TRIM(LEADING '$prefix:' FROM pl_title)
662 AND pl_title LIKE '$likeprefix:%'";
664 $this->db->query( $sql, __METHOD__ );
665 $this->
output(
"done.\n" );
670 if ( !$this->
doTable(
'user' ) ) {
675 if ( $duper->hasUniqueIndex() ) {
676 $this->
output(
"...already have unique user_name index.\n" );
681 if ( !$duper->clearDupes() ) {
682 $this->
output(
"WARNING: This next step will probably fail due to unfixed duplicates...\n" );
684 $this->
applyPatch(
'patch-user_nameindex.sql',
false,
"Adding unique index on user_name" );
688 if ( !$this->
doTable(
'user_groups' ) ) {
692 if ( $this->db->tableExists(
'user_groups', __METHOD__ ) ) {
693 $info = $this->db->fieldInfo(
'user_groups',
'ug_group' );
694 if ( $info->type() ==
'int' ) {
695 $oldug = $this->db->tableName(
'user_groups' );
696 $newug = $this->db->tableName(
'user_groups_bogus' );
697 $this->
output(
"user_groups table exists but is in bogus intermediate " .
698 "format. Renaming to $newug... " );
699 $this->db->query(
"ALTER TABLE $oldug RENAME TO $newug", __METHOD__ );
700 $this->
output(
"done.\n" );
702 $this->
applyPatch(
'patch-user_groups.sql',
false,
"Re-adding fresh user_groups table" );
705 $this->
output(
"*** WARNING: You will need to manually fix up user " .
706 "permissions in the user_groups\n" );
707 $this->
output(
"*** table. Old 1.5 alpha versions did some pretty funky stuff...\n" );
710 $this->
output(
"...user_groups table exists and is in current format.\n" );
716 $this->
applyPatch(
'patch-user_groups.sql',
false,
"Adding user_groups table" );
718 if ( !$this->db->tableExists(
'user_rights', __METHOD__ ) ) {
719 if ( $this->db->fieldExists(
'user',
'user_rights', __METHOD__ ) ) {
721 'patch-user_rights.sql',
723 'Upgrading from a 1.3 or older database? Breaking out user_rights for conversion'
726 $this->
output(
"*** WARNING: couldn't locate user_rights table or field for upgrade.\n" );
727 $this->
output(
"*** You may need to manually configure some sysops by manipulating\n" );
728 $this->
output(
"*** the user_groups table.\n" );
734 $this->
output(
"Converting user_rights table to user_groups... " );
735 $result = $this->db->select(
'user_rights',
736 array(
'ur_user',
'ur_rights' ),
737 array(
"ur_rights != ''" ),
741 $groups = array_unique(
743 explode(
',', $row->ur_rights ) ) );
745 foreach ( $groups
as $group ) {
746 $this->db->insert(
'user_groups',
748 'ug_user' => $row->ur_user,
749 'ug_group' => $group ),
753 $this->
output(
"done.\n" );
761 $info = $this->db->fieldInfo(
'watchlist',
'wl_notificationtimestamp' );
765 if ( $info->isNullable() ) {
766 $this->
output(
"...wl_notificationtimestamp is already nullable.\n" );
772 'patch-watchlist-null.sql',
774 'Making wl_notificationtimestamp nullable'
784 $page = $this->db->tableName(
'page' );
785 $this->db->query(
"UPDATE $page SET page_random = RAND() WHERE page_random = 0", __METHOD__ );
786 $rows = $this->db->affectedRows();
789 $this->
output(
"Set page_random to a random value on $rows rows where it was set to 0\n" );
791 $this->
output(
"...no page_random rows needed to be set\n" );
796 if ( $this->db->tableExists(
'templatelinks', __METHOD__ ) ) {
797 $this->
output(
"...templatelinks table already exists\n" );
802 $this->
applyPatch(
'patch-templatelinks.sql',
false,
"Creating templatelinks table" );
804 $this->
output(
"Populating...\n" );
805 if (
wfGetLB()->getServerCount() > 1 ) {
807 $res = $this->db->select(
'pagelinks',
array(
'pl_from',
'pl_namespace',
'pl_title' ),
810 foreach (
$res as $row ) {
815 $this->db->insert(
'templatelinks',
817 'tl_from' => $row->pl_from,
818 'tl_namespace' => $row->pl_namespace,
819 'tl_title' => $row->pl_title,
825 $this->db->insertSelect(
'templatelinks',
'pagelinks',
827 'tl_from' =>
'pl_from',
828 'tl_namespace' =>
'pl_namespace',
829 'tl_title' =>
'pl_title'
835 $this->
output(
"Done. Please run maintenance/refreshLinks.php for a more " .
836 "thorough templatelinks update.\n" );
840 if ( !$this->
indexHasField(
'pagelinks',
'pl_namespace',
'pl_from' ) ||
841 !$this->
indexHasField(
'templatelinks',
'tl_namespace',
'tl_from' ) ||
844 $this->
applyPatch(
'patch-backlinkindexes.sql',
false,
"Updating backlinking indices" );
854 if ( $this->db->tableExists(
'page_restrictions', __METHOD__ ) ) {
855 $this->
output(
"...page_restrictions table already exists.\n" );
861 'patch-page_restrictions.sql',
863 'Creating page_restrictions table (1/2)'
866 'patch-page_restrictions_sortkey.sql',
868 'Creating page_restrictions table (2/2)'
870 $this->
output(
"done.\n" );
872 $this->
output(
"Migrating old restrictions to new table...\n" );
873 $task = $this->maintenance->runChild(
'UpdateRestrictions' );
878 if ( !$this->
indexHasField(
'categorylinks',
'cl_sortkey',
'cl_from' ) ) {
879 $this->
applyPatch(
'patch-categorylinksindex.sql',
false,
"Updating categorylinks Indices" );
885 $this->
output(
"...category table already populated.\n" );
891 "Populating category table, printing progress markers. " .
892 "For large databases, you\n" .
893 "may want to hit Ctrl-C and do this manually with maintenance/\n" .
894 "populateCategory.php.\n"
896 $task = $this->maintenance->runChild(
'PopulateCategory' );
898 $this->
output(
"Done populating category table.\n" );
904 "Populating rev_parent_id fields, printing progress markers. For large\n" .
905 "databases, you may want to hit Ctrl-C and do this manually with\n" .
906 "maintenance/populateParentId.php.\n" );
908 $task = $this->maintenance->runChild(
'PopulateParentId' );
914 global $wgProfileToDatabase;
916 if ( !$this->
doTable(
'profiling' ) ) {
920 if ( $wgProfileToDatabase ===
true && !$this->db->tableExists(
'profiling', __METHOD__ ) ) {
921 $this->
applyPatch(
'patch-profiling.sql',
false,
'Add profiling table' );
926 if ( !$this->
doTable(
'profiling' ) ) {
930 if ( !$this->db->tableExists(
'profiling', __METHOD__ ) ) {
932 } elseif ( $this->db->fieldExists(
'profiling',
'pf_memory', __METHOD__ ) ) {
933 $this->
output(
"...profiling table has pf_memory field.\n" );
939 'patch-profiling-memory.sql',
941 'Adding pf_memory field to table profiling'
946 $info = $this->db->indexInfo(
'filearchive',
'fa_user_timestamp', __METHOD__ );
948 $this->
applyPatch(
'patch-filearchive-user-index.sql',
false,
"Updating filearchive indices" );
955 $info = $this->db->indexInfo(
'pagelinks',
'pl_namespace' );
956 if ( is_array( $info ) && !$info[0]->Non_unique ) {
957 $this->
output(
"...pl_namespace, tl_namespace, il_to indices are already UNIQUE.\n" );
961 if ( $this->skipSchema ) {
962 $this->
output(
"...skipping schema change (making pl_namespace, tl_namespace " .
963 "and il_to indices UNIQUE).\n" );
969 'patch-pl-tl-il-unique.sql',
971 'Making pl_namespace, tl_namespace and il_to indices UNIQUE'
977 $this->
output(
"...*_mime_minor fields are already long enough.\n" );
983 'patch-mime_minor_length.sql',
985 'Altering all *_mime_minor fields to 100 bytes in size'
991 $this->
output(
"...categorylinks up-to-date.\n" );
997 'patch-categorylinks-better-collation2.sql',
999 'Updating categorylinks (again)'
1004 $langlinks = $this->db->tableName(
'langlinks' );
1005 $res = $this->db->query(
"SHOW COLUMNS FROM $langlinks LIKE 'll_lang'" );
1006 $row = $this->db->fetchObject(
$res );
1008 if ( $row && $row->Type ==
"varbinary(10)" ) {
1010 'patch-langlinks-ll_lang-20.sql',
1012 'Updating length of ll_lang in langlinks'
1015 $this->
output(
"...ll_lang is up-to-date.\n" );
1020 if ( !$this->
doTable(
'user_newtalk' ) ) {
1024 $info = $this->db->fieldInfo(
'user_newtalk',
'user_last_timestamp' );
1025 if ( $info ===
false ) {
1028 if ( $info->isNullable() ) {
1029 $this->
output(
"...user_last_timestamp is already nullable.\n" );
1035 'patch-user-newtalk-timestamp-null.sql',
1037 'Making user_last_timestamp nullable'
1042 $info = $this->db->indexInfo(
'iwlinks',
'iwl_prefix_title_from' );
1043 if ( is_array( $info ) && $info[0]->Non_unique ) {
1044 $this->
output(
"...iwl_prefix_title_from index is already non-UNIQUE.\n" );
1048 if ( $this->skipSchema ) {
1049 $this->
output(
"...skipping schema change (making iwl_prefix_title_from index non-UNIQUE).\n" );
1055 'patch-iwl_prefix_title_from-non-unique.sql',
1057 'Making iwl_prefix_title_from index non-UNIQUE'