MediaWiki  1.23.2
MysqlUpdater.php
Go to the documentation of this file.
1 <?php
31  protected function getCoreUpdateList() {
32  return array(
33  array( 'disableContentHandlerUseDB' ),
34 
35  // 1.2
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' ),
43 
44  // 1.3
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' ),
52 
53  // 1.4
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' ),
63 
64  // 1.5
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' ),
87 
88  // 1.6
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' ),
104 
105  // 1.9
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' ),
113 
114  // 1.10
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' ),
126 
127  // 1.11
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' ),
136 
137  // 1.12
138  array( 'addTable', 'protected_titles', 'patch-protected_titles.sql' ),
139 
140  // 1.13
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' ),
152 
153  // 1.14
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' ),
157 
158  // 1.15
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' ),
163 
164  // 1.16
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' ),
177 
178  // 1.17
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' ),
192 
193  // 1.18
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' ),
199 
200  // 1.19
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' ),
210 
211  // 1.20
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' ),
216 
217  // 1.21
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' ),
238 
239  // 1.22
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' ),
245 
246  // 1.23
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' ),
253  );
254  }
255 
265  protected function checkBin( $table, $field, $patchFile ) {
266  if ( !$this->doTable( $table ) ) {
267  return true;
268  }
269 
271  $fieldInfo = $this->db->fieldInfo( $table, $field );
272  if ( $fieldInfo->isBinary() ) {
273  $this->output( "...$table table has correct $field encoding.\n" );
274  } else {
275  $this->applyPatch( $patchFile, false, "Fixing $field encoding on $table table" );
276  }
277  }
278 
287  protected function indexHasField( $table, $index, $field ) {
288  if ( !$this->doTable( $table ) ) {
289  return true;
290  }
291 
292  $info = $this->db->indexInfo( $table, $index, __METHOD__ );
293  if ( $info ) {
294  foreach ( $info as $row ) {
295  if ( $row->Column_name == $field ) {
296  $this->output( "...index $index on table $table includes field $field.\n" );
297 
298  return true;
299  }
300  }
301  }
302  $this->output( "...index $index on table $table has no field $field; added.\n" );
303 
304  return false;
305  }
306 
310  protected function doInterwikiUpdate() {
311  global $IP;
312 
313  if ( !$this->doTable( 'interwiki' ) ) {
314  return true;
315  }
316 
317  if ( $this->db->tableExists( "interwiki", __METHOD__ ) ) {
318  $this->output( "...already have interwiki table\n" );
319 
320  return;
321  }
322 
323  $this->applyPatch( 'patch-interwiki.sql', false, 'Creating interwiki table' );
324  $this->applyPatch(
325  "$IP/maintenance/interwiki.sql",
326  true,
327  'Adding default interwiki definitions'
328  );
329  }
330 
334  protected function doIndexUpdate() {
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.' );
338  }
339  if ( $meta->isMultipleKey() ) {
340  $this->output( "...indexes seem up to 20031107 standards.\n" );
341 
342  return;
343  }
344 
345  $this->applyPatch( 'patch-indexes.sql', true, "Updating indexes to 20031107" );
346  }
347 
348  protected function doOldLinksUpdate() {
349  $cl = $this->maintenance->runChild( 'ConvertLinks' );
350  $cl->execute();
351  }
352 
353  protected function doFixAncientImagelinks() {
354  $info = $this->db->fieldInfo( 'imagelinks', 'il_from' );
355  if ( !$info || $info->type() !== 'string' ) {
356  $this->output( "...il_from OK\n" );
357 
358  return;
359  }
360 
361  $applied = $this->applyPatch(
362  'patch-fix-il_from.sql',
363  false,
364  'Fixing ancient broken imagelinks table.'
365  );
366 
367  if ( $applied ) {
368  $this->output( "NOTE: you will have to run maintenance/refreshLinks.php after this." );
369  }
370  }
371 
375  function doWatchlistUpdate() {
376  $talk = $this->db->selectField( 'watchlist', 'count(*)', 'wl_namespace & 1', __METHOD__ );
377  $nontalk = $this->db->selectField(
378  'watchlist',
379  'count(*)',
380  'NOT (wl_namespace & 1)',
381  __METHOD__
382  );
383  if ( $talk == $nontalk ) {
384  $this->output( "...watchlist talk page rows already present.\n" );
385 
386  return;
387  }
388 
389  $this->output( "Adding missing watchlist talk page rows... " );
390  $this->db->insertSelect( 'watchlist', 'watchlist',
391  array(
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" );
398 
399  $this->output( "Adding missing watchlist subject page rows... " );
400  $this->db->insertSelect( 'watchlist', 'watchlist',
401  array(
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" );
408  }
409 
411  if ( $this->db->tableExists( 'page', __METHOD__ ) ) {
412  $this->output( "...page table already exists.\n" );
413 
414  return;
415  }
416 
417  $this->output( "...converting from cur/old to page/revision/text DB structure.\n" );
418  $this->output( wfTimestamp( TS_DB ) );
419  $this->output( "......checking for duplicate entries.\n" );
420 
421  list( $cur, $old, $page, $revision, $text ) = $this->db->tableNamesN(
422  'cur',
423  'old',
424  'page',
425  'revision',
426  'text'
427  );
428 
429  $rows = $this->db->query( "
430  SELECT cur_title, cur_namespace, COUNT(cur_namespace) AS c
431  FROM $cur
432  GROUP BY cur_title, cur_namespace
433  HAVING c>1",
434  __METHOD__
435  );
436 
437  if ( $rows->numRows() > 0 ) {
438  $this->output( wfTimestamp( TS_DB ) );
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();
445  }
446 
447  $duplicate[$row->cur_namespace][] = $row->cur_title;
448  $this->output( sprintf(
449  " %-60s %3s %5s\n",
450  $row->cur_title, $row->cur_namespace,
451  $row->c
452  ) );
453  }
454  $sql = "SELECT cur_title, cur_namespace, cur_id, cur_timestamp FROM $cur WHERE ";
455  $firstCond = true;
456  foreach ( $duplicate as $ns => $titles ) {
457  if ( $firstCond ) {
458  $firstCond = false;
459  } else {
460  $sql .= ' OR ';
461  }
462  $sql .= "( cur_namespace = {$ns} AND cur_title in (";
463  $first = true;
464  foreach ( $titles as $t ) {
465  if ( $first ) {
466  $sql .= $this->db->addQuotes( $t );
467  $first = false;
468  } else {
469  $sql .= ', ' . $this->db->addQuotes( $t );
470  }
471  }
472  $sql .= ") ) \n";
473  }
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';
477 
478  $rows = $this->db->query( $sql, __METHOD__ );
479 
480  $prev_title = $prev_namespace = false;
481  $deleteId = array();
482 
483  foreach ( $rows as $row ) {
484  if ( $prev_title == $row->cur_title && $prev_namespace == $row->cur_namespace ) {
485  $deleteId[] = $row->cur_id;
486  }
487  $prev_title = $row->cur_title;
488  $prev_namespace = $row->cur_namespace;
489  }
490  $sql = "DELETE FROM $cur WHERE cur_id IN ( " . join( ',', $deleteId ) . ')';
491  $this->db->query( $sql, __METHOD__ );
492  $this->output( wfTimestamp( TS_DB ) );
493  $this->output( "......<b>Deleted</b> " . $this->db->affectedRows() . " records.\n" );
494  }
495 
496  $this->output( wfTimestamp( TS_DB ) );
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,
510 
511  PRIMARY KEY page_id (page_id),
512  UNIQUE INDEX name_title (page_namespace,page_title),
513  INDEX (page_random),
514  INDEX (page_len)
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__ );
534 
535  $this->output( wfTimestamp( TS_DB ) );
536  $this->output( "......Locking tables.\n" );
537  $this->db->query(
538  "LOCK TABLES $page WRITE, $revision WRITE, $old WRITE, $cur WRITE",
539  __METHOD__
540  );
541 
542  $maxold = intval( $this->db->selectField( 'old', 'max(old_id)', '', __METHOD__ ) );
543  $this->output( wfTimestamp( TS_DB ) );
544  $this->output( "......maxold is {$maxold}\n" );
545 
546  $this->output( wfTimestamp( TS_DB ) );
547  global $wgLegacySchemaConversion;
548  if ( $wgLegacySchemaConversion ) {
549  // Create HistoryBlobCurStub entries.
550  // Text will be pulled from the leftover 'cur' table at runtime.
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'";
554  } else {
555  // Copy all cur text in immediately: this may take longer but avoids
556  // having to keep an extra table around.
557  $this->output( "......Moving text from cur.\n" );
558  $cur_text = 'cur_text';
559  $cur_flags = "''";
560  }
561  $this->db->query(
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
566  FROM $cur",
567  __METHOD__
568  );
569 
570  $this->output( wfTimestamp( TS_DB ) );
571  $this->output( "......Setting up revision table.\n" );
572  $this->db->query(
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",
578  __METHOD__
579  );
580 
581  $this->output( wfTimestamp( TS_DB ) );
582  $this->output( "......Setting up page table.\n" );
583  $this->db->query(
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)
589  FROM $cur,$revision
590  WHERE cur_id=rev_page AND rev_timestamp=cur_timestamp AND rev_id > {$maxold}",
591  __METHOD__
592  );
593 
594  $this->output( wfTimestamp( TS_DB ) );
595  $this->output( "......Unlocking tables.\n" );
596  $this->db->query( "UNLOCK TABLES", __METHOD__ );
597 
598  $this->output( wfTimestamp( TS_DB ) );
599  $this->output( "......Renaming old.\n" );
600  $this->db->query( "ALTER TABLE $old RENAME TO $text", __METHOD__ );
601 
602  $this->output( wfTimestamp( TS_DB ) );
603  $this->output( "...done.\n" );
604  }
605 
606  protected function doNamespaceSize() {
607  $tables = array(
608  'page' => 'page',
609  'archive' => 'ar',
610  'recentchanges' => 'rc',
611  'watchlist' => 'wl',
612  'querycache' => 'qc',
613  'logging' => 'log',
614  );
615  foreach ( $tables as $table => $prefix ) {
616  $field = $prefix . '_namespace';
617 
618  $tablename = $this->db->tableName( $table );
619  $result = $this->db->query( "SHOW COLUMNS FROM $tablename LIKE '$field'", __METHOD__ );
620  $info = $this->db->fetchObject( $result );
621 
622  if ( substr( $info->Type, 0, 3 ) == 'int' ) {
623  $this->output( "...$field is already a full int ($info->Type).\n" );
624  } else {
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" );
628  }
629  }
630  }
631 
632  protected function doPagelinksUpdate() {
633  if ( $this->db->tableExists( 'pagelinks', __METHOD__ ) ) {
634  $this->output( "...already have pagelinks table.\n" );
635 
636  return;
637  }
638 
639  $this->applyPatch(
640  'patch-pagelinks.sql',
641  false,
642  'Converting links and brokenlinks tables to pagelinks'
643  );
644 
646  foreach ( MWNamespace::getCanonicalNamespaces() as $ns => $name ) {
647  if ( $ns == 0 ) {
648  continue;
649  }
650 
651  $this->output( "Cleaning up broken links for namespace $ns... " );
652 
653  $pagelinks = $this->db->tableName( 'pagelinks' );
654  $name = $wgContLang->getNsText( $ns );
655  $prefix = $this->db->strencode( $name );
656  $likeprefix = str_replace( '_', '\\_', $prefix );
657 
658  $sql = "UPDATE $pagelinks
659  SET pl_namespace=$ns,
660  pl_title=TRIM(LEADING '$prefix:' FROM pl_title)
661  WHERE pl_namespace=0
662  AND pl_title LIKE '$likeprefix:%'";
663 
664  $this->db->query( $sql, __METHOD__ );
665  $this->output( "done.\n" );
666  }
667  }
668 
669  protected function doUserUniqueUpdate() {
670  if ( !$this->doTable( 'user' ) ) {
671  return true;
672  }
673 
674  $duper = new UserDupes( $this->db, array( $this, 'output' ) );
675  if ( $duper->hasUniqueIndex() ) {
676  $this->output( "...already have unique user_name index.\n" );
677 
678  return;
679  }
680 
681  if ( !$duper->clearDupes() ) {
682  $this->output( "WARNING: This next step will probably fail due to unfixed duplicates...\n" );
683  }
684  $this->applyPatch( 'patch-user_nameindex.sql', false, "Adding unique index on user_name" );
685  }
686 
687  protected function doUserGroupsUpdate() {
688  if ( !$this->doTable( 'user_groups' ) ) {
689  return true;
690  }
691 
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" );
701 
702  $this->applyPatch( 'patch-user_groups.sql', false, "Re-adding fresh user_groups table" );
703 
704  $this->output( "***\n" );
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" );
708  $this->output( "***\n" );
709  } else {
710  $this->output( "...user_groups table exists and is in current format.\n" );
711  }
712 
713  return;
714  }
715 
716  $this->applyPatch( 'patch-user_groups.sql', false, "Adding user_groups table" );
717 
718  if ( !$this->db->tableExists( 'user_rights', __METHOD__ ) ) {
719  if ( $this->db->fieldExists( 'user', 'user_rights', __METHOD__ ) ) {
720  $this->applyPatch(
721  'patch-user_rights.sql',
722  false,
723  'Upgrading from a 1.3 or older database? Breaking out user_rights for conversion'
724  );
725  } else {
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" );
729 
730  return;
731  }
732  }
733 
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 != ''" ),
738  __METHOD__ );
739 
740  foreach ( $result as $row ) {
741  $groups = array_unique(
742  array_map( 'trim',
743  explode( ',', $row->ur_rights ) ) );
744 
745  foreach ( $groups as $group ) {
746  $this->db->insert( 'user_groups',
747  array(
748  'ug_user' => $row->ur_user,
749  'ug_group' => $group ),
750  __METHOD__ );
751  }
752  }
753  $this->output( "done.\n" );
754  }
755 
760  protected function doWatchlistNull() {
761  $info = $this->db->fieldInfo( 'watchlist', 'wl_notificationtimestamp' );
762  if ( !$info ) {
763  return;
764  }
765  if ( $info->isNullable() ) {
766  $this->output( "...wl_notificationtimestamp is already nullable.\n" );
767 
768  return;
769  }
770 
771  $this->applyPatch(
772  'patch-watchlist-null.sql',
773  false,
774  'Making wl_notificationtimestamp nullable'
775  );
776  }
777 
783  protected function doPageRandomUpdate() {
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();
787 
788  if ( $rows ) {
789  $this->output( "Set page_random to a random value on $rows rows where it was set to 0\n" );
790  } else {
791  $this->output( "...no page_random rows needed to be set\n" );
792  }
793  }
794 
795  protected function doTemplatelinksUpdate() {
796  if ( $this->db->tableExists( 'templatelinks', __METHOD__ ) ) {
797  $this->output( "...templatelinks table already exists\n" );
798 
799  return;
800  }
801 
802  $this->applyPatch( 'patch-templatelinks.sql', false, "Creating templatelinks table" );
803 
804  $this->output( "Populating...\n" );
805  if ( wfGetLB()->getServerCount() > 1 ) {
806  // Slow, replication-friendly update
807  $res = $this->db->select( 'pagelinks', array( 'pl_from', 'pl_namespace', 'pl_title' ),
808  array( 'pl_namespace' => NS_TEMPLATE ), __METHOD__ );
809  $count = 0;
810  foreach ( $res as $row ) {
811  $count = ( $count + 1 ) % 100;
812  if ( $count == 0 ) {
813  wfWaitForSlaves();
814  }
815  $this->db->insert( 'templatelinks',
816  array(
817  'tl_from' => $row->pl_from,
818  'tl_namespace' => $row->pl_namespace,
819  'tl_title' => $row->pl_title,
820  ), __METHOD__
821  );
822  }
823  } else {
824  // Fast update
825  $this->db->insertSelect( 'templatelinks', 'pagelinks',
826  array(
827  'tl_from' => 'pl_from',
828  'tl_namespace' => 'pl_namespace',
829  'tl_title' => 'pl_title'
830  ), array(
831  'pl_namespace' => 10
832  ), __METHOD__
833  );
834  }
835  $this->output( "Done. Please run maintenance/refreshLinks.php for a more " .
836  "thorough templatelinks update.\n" );
837  }
838 
839  protected function doBacklinkingIndicesUpdate() {
840  if ( !$this->indexHasField( 'pagelinks', 'pl_namespace', 'pl_from' ) ||
841  !$this->indexHasField( 'templatelinks', 'tl_namespace', 'tl_from' ) ||
842  !$this->indexHasField( 'imagelinks', 'il_to', 'il_from' )
843  ) {
844  $this->applyPatch( 'patch-backlinkindexes.sql', false, "Updating backlinking indices" );
845  }
846  }
847 
853  protected function doRestrictionsUpdate() {
854  if ( $this->db->tableExists( 'page_restrictions', __METHOD__ ) ) {
855  $this->output( "...page_restrictions table already exists.\n" );
856 
857  return;
858  }
859 
860  $this->applyPatch(
861  'patch-page_restrictions.sql',
862  false,
863  'Creating page_restrictions table (1/2)'
864  );
865  $this->applyPatch(
866  'patch-page_restrictions_sortkey.sql',
867  false,
868  'Creating page_restrictions table (2/2)'
869  );
870  $this->output( "done.\n" );
871 
872  $this->output( "Migrating old restrictions to new table...\n" );
873  $task = $this->maintenance->runChild( 'UpdateRestrictions' );
874  $task->execute();
875  }
876 
877  protected function doCategorylinksIndicesUpdate() {
878  if ( !$this->indexHasField( 'categorylinks', 'cl_sortkey', 'cl_from' ) ) {
879  $this->applyPatch( 'patch-categorylinksindex.sql', false, "Updating categorylinks Indices" );
880  }
881  }
882 
883  protected function doCategoryPopulation() {
884  if ( $this->updateRowExists( 'populate category' ) ) {
885  $this->output( "...category table already populated.\n" );
886 
887  return;
888  }
889 
890  $this->output(
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"
895  );
896  $task = $this->maintenance->runChild( 'PopulateCategory' );
897  $task->execute();
898  $this->output( "Done populating category table.\n" );
899  }
900 
901  protected function doPopulateParentId() {
902  if ( !$this->updateRowExists( 'populate rev_parent_id' ) ) {
903  $this->output(
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" );
907 
908  $task = $this->maintenance->runChild( 'PopulateParentId' );
909  $task->execute();
910  }
911  }
912 
913  protected function doEnableProfiling() {
914  global $wgProfileToDatabase;
915 
916  if ( !$this->doTable( 'profiling' ) ) {
917  return true;
918  }
919 
920  if ( $wgProfileToDatabase === true && !$this->db->tableExists( 'profiling', __METHOD__ ) ) {
921  $this->applyPatch( 'patch-profiling.sql', false, 'Add profiling table' );
922  }
923  }
924 
925  protected function doMaybeProfilingMemoryUpdate() {
926  if ( !$this->doTable( 'profiling' ) ) {
927  return true;
928  }
929 
930  if ( !$this->db->tableExists( 'profiling', __METHOD__ ) ) {
931  return true;
932  } elseif ( $this->db->fieldExists( 'profiling', 'pf_memory', __METHOD__ ) ) {
933  $this->output( "...profiling table has pf_memory field.\n" );
934 
935  return true;
936  }
937 
938  return $this->applyPatch(
939  'patch-profiling-memory.sql',
940  false,
941  'Adding pf_memory field to table profiling'
942  );
943  }
944 
945  protected function doFilearchiveIndicesUpdate() {
946  $info = $this->db->indexInfo( 'filearchive', 'fa_user_timestamp', __METHOD__ );
947  if ( !$info ) {
948  $this->applyPatch( 'patch-filearchive-user-index.sql', false, "Updating filearchive indices" );
949  }
950 
951  return true;
952  }
953 
954  protected function doUniquePlTlIl() {
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" );
958 
959  return true;
960  }
961  if ( $this->skipSchema ) {
962  $this->output( "...skipping schema change (making pl_namespace, tl_namespace " .
963  "and il_to indices UNIQUE).\n" );
964 
965  return false;
966  }
967 
968  return $this->applyPatch(
969  'patch-pl-tl-il-unique.sql',
970  false,
971  'Making pl_namespace, tl_namespace and il_to indices UNIQUE'
972  );
973  }
974 
975  protected function doUpdateMimeMinorField() {
976  if ( $this->updateRowExists( 'mime_minor_length' ) ) {
977  $this->output( "...*_mime_minor fields are already long enough.\n" );
978 
979  return;
980  }
981 
982  $this->applyPatch(
983  'patch-mime_minor_length.sql',
984  false,
985  'Altering all *_mime_minor fields to 100 bytes in size'
986  );
987  }
988 
989  protected function doClFieldsUpdate() {
990  if ( $this->updateRowExists( 'cl_fields_update' ) ) {
991  $this->output( "...categorylinks up-to-date.\n" );
992 
993  return;
994  }
995 
996  $this->applyPatch(
997  'patch-categorylinks-better-collation2.sql',
998  false,
999  'Updating categorylinks (again)'
1000  );
1001  }
1002 
1003  protected function doLangLinksLengthUpdate() {
1004  $langlinks = $this->db->tableName( 'langlinks' );
1005  $res = $this->db->query( "SHOW COLUMNS FROM $langlinks LIKE 'll_lang'" );
1006  $row = $this->db->fetchObject( $res );
1007 
1008  if ( $row && $row->Type == "varbinary(10)" ) {
1009  $this->applyPatch(
1010  'patch-langlinks-ll_lang-20.sql',
1011  false,
1012  'Updating length of ll_lang in langlinks'
1013  );
1014  } else {
1015  $this->output( "...ll_lang is up-to-date.\n" );
1016  }
1017  }
1018 
1019  protected function doUserNewTalkTimestampNotNull() {
1020  if ( !$this->doTable( 'user_newtalk' ) ) {
1021  return true;
1022  }
1023 
1024  $info = $this->db->fieldInfo( 'user_newtalk', 'user_last_timestamp' );
1025  if ( $info === false ) {
1026  return;
1027  }
1028  if ( $info->isNullable() ) {
1029  $this->output( "...user_last_timestamp is already nullable.\n" );
1030 
1031  return;
1032  }
1033 
1034  $this->applyPatch(
1035  'patch-user-newtalk-timestamp-null.sql',
1036  false,
1037  'Making user_last_timestamp nullable'
1038  );
1039  }
1040 
1041  protected function doIwlinksIndexNonUnique() {
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" );
1045 
1046  return true;
1047  }
1048  if ( $this->skipSchema ) {
1049  $this->output( "...skipping schema change (making iwl_prefix_title_from index non-UNIQUE).\n" );
1050 
1051  return false;
1052  }
1053 
1054  return $this->applyPatch(
1055  'patch-iwl_prefix_title_from-non-unique.sql',
1056  false,
1057  'Making iwl_prefix_title_from index non-UNIQUE'
1058  );
1059  }
1060 }
DatabaseUpdater\output
output( $str)
Output some text.
Definition: DatabaseUpdater.php:184
MysqlUpdater\checkBin
checkBin( $table, $field, $patchFile)
1.4 betas were missing the 'binary' marker from logging.log_title, which causes a collation mismatch ...
Definition: MysqlUpdater.php:265
$result
The index of the header message $result[1]=The index of the body text message $result[2 through n]=Parameters passed to body text message. Please note the header message cannot receive/use parameters. 'ImportHandleLogItemXMLTag':When parsing a XML tag in a log item. $reader:XMLReader object $logInfo:Array of information Return false to stop further processing of the tag 'ImportHandlePageXMLTag':When parsing a XML tag in a page. $reader:XMLReader object $pageInfo:Array of information Return false to stop further processing of the tag 'ImportHandleRevisionXMLTag':When parsing a XML tag in a page revision. $reader:XMLReader object $pageInfo:Array of page information $revisionInfo:Array of revision information Return false to stop further processing of the tag 'ImportHandleToplevelXMLTag':When parsing a top level XML tag. $reader:XMLReader object Return false to stop further processing of the tag 'ImportHandleUploadXMLTag':When parsing a XML tag in a file upload. $reader:XMLReader object $revisionInfo:Array of information Return false to stop further processing of the tag 'InfoAction':When building information to display on the action=info page. $context:IContextSource object & $pageInfo:Array of information 'InitializeArticleMaybeRedirect':MediaWiki check to see if title is a redirect. $title:Title object for the current page $request:WebRequest $ignoreRedirect:boolean to skip redirect check $target:Title/string of redirect target $article:Article object 'InterwikiLoadPrefix':When resolving if a given prefix is an interwiki or not. Return true without providing an interwiki to continue interwiki search. $prefix:interwiki prefix we are looking for. & $iwData:output array describing the interwiki with keys iw_url, iw_local, iw_trans and optionally iw_api and iw_wikiid. 'InternalParseBeforeSanitize':during Parser 's internalParse method just before the parser removes unwanted/dangerous HTML tags and after nowiki/noinclude/includeonly/onlyinclude and other processings. Ideal for syntax-extensions after template/parser function execution which respect nowiki and HTML-comments. & $parser:Parser object & $text:string containing partially parsed text & $stripState:Parser 's internal StripState object 'InternalParseBeforeLinks':during Parser 's internalParse method before links but after nowiki/noinclude/includeonly/onlyinclude and other processings. & $parser:Parser object & $text:string containing partially parsed text & $stripState:Parser 's internal StripState object 'InvalidateEmailComplete':Called after a user 's email has been invalidated successfully. $user:user(object) whose email is being invalidated 'IRCLineURL':When constructing the URL to use in an IRC notification. Callee may modify $url and $query, URL will be constructed as $url . $query & $url:URL to index.php & $query:Query string $rc:RecentChange object that triggered url generation 'IsFileCacheable':Override the result of Article::isFileCacheable()(if true) $article:article(object) being checked 'IsTrustedProxy':Override the result of wfIsTrustedProxy() $ip:IP being check $result:Change this value to override the result of wfIsTrustedProxy() 'IsUploadAllowedFromUrl':Override the result of UploadFromUrl::isAllowedUrl() $url:URL used to upload from & $allowed:Boolean indicating if uploading is allowed for given URL 'isValidEmailAddr':Override the result of User::isValidEmailAddr(), for instance to return false if the domain name doesn 't match your organization. $addr:The e-mail address entered by the user & $result:Set this and return false to override the internal checks 'isValidPassword':Override the result of User::isValidPassword() $password:The password entered by the user & $result:Set this and return false to override the internal checks $user:User the password is being validated for 'Language::getMessagesFileName':$code:The language code or the language we 're looking for a messages file for & $file:The messages file path, you can override this to change the location. 'LanguageGetNamespaces':Provide custom ordering for namespaces or remove namespaces. Do not use this hook to add namespaces. Use CanonicalNamespaces for that. & $namespaces:Array of namespaces indexed by their numbers 'LanguageGetMagic':DEPRECATED, use $magicWords in a file listed in $wgExtensionMessagesFiles instead. Use this to define synonyms of magic words depending of the language $magicExtensions:associative array of magic words synonyms $lang:language code(string) 'LanguageGetSpecialPageAliases':DEPRECATED, use $specialPageAliases in a file listed in $wgExtensionMessagesFiles instead. Use to define aliases of special pages names depending of the language $specialPageAliases:associative array of magic words synonyms $lang:language code(string) 'LanguageGetTranslatedLanguageNames':Provide translated language names. & $names:array of language code=> language name $code language of the preferred translations 'LanguageLinks':Manipulate a page 's language links. This is called in various places to allow extensions to define the effective language links for a page. $title:The page 's Title. & $links:Associative array mapping language codes to prefixed links of the form "language:title". & $linkFlags:Associative array mapping prefixed links to arrays of flags. Currently unused, but planned to provide support for marking individual language links in the UI, e.g. for featured articles. 'LinkBegin':Used when generating internal and interwiki links in Linker::link(), before processing starts. Return false to skip default processing and return $ret. See documentation for Linker::link() for details on the expected meanings of parameters. $skin:the Skin object $target:the Title that the link is pointing to & $html:the contents that the< a > tag should have(raw HTML) $result
Definition: hooks.txt:1528
DatabaseUpdater\applyPatch
applyPatch( $path, $isFullPath=false, $msg=null)
Applies a SQL patch.
Definition: DatabaseUpdater.php:623
php
skin txt MediaWiki includes four core it has been set as the default in MediaWiki since the replacing Monobook it had been been the default skin since before being replaced by Vector largely rewritten in while keeping its appearance Several legacy skins were removed in the as the burden of supporting them became too heavy to bear Those in etc for skin dependent CSS etc for skin dependent JavaScript These can also be customised on a per user by etc This feature has led to a wide variety of user styles becoming that gallery is a good place to ending in php
Definition: skin.txt:62
MysqlUpdater\doPagelinksUpdate
doPagelinksUpdate()
Definition: MysqlUpdater.php:632
MysqlUpdater\doFixAncientImagelinks
doFixAncientImagelinks()
Definition: MysqlUpdater.php:353
$tables
namespace and then decline to actually register it RecentChangesLinked and Watchlist RecentChangesLinked and Watchlist e g Watchlist & $tables
Definition: hooks.txt:815
DatabaseUpdater
Class for handling database updates.
Definition: DatabaseUpdater.php:33
MysqlUpdater\doUpdateMimeMinorField
doUpdateMimeMinorField()
Definition: MysqlUpdater.php:975
wfGetLB
wfGetLB( $wiki=false)
Get a load balancer object.
Definition: GlobalFunctions.php:3660
wfTimestamp
wfTimestamp( $outputtype=TS_UNIX, $ts=0)
Get a timestamp string in one of various formats.
Definition: GlobalFunctions.php:2483
MysqlUpdater\doUniquePlTlIl
doUniquePlTlIl()
Definition: MysqlUpdater.php:954
DatabaseUpdater\doTable
doTable( $name)
Returns whether updates should be executed on the database table $name.
Definition: DatabaseUpdater.php:519
MysqlUpdater\doWatchlistUpdate
doWatchlistUpdate()
Check if we need to add talk page rows to the watchlist.
Definition: MysqlUpdater.php:375
NS_TEMPLATE
const NS_TEMPLATE
Definition: Defines.php:89
TS_DB
const TS_DB
MySQL DATETIME (YYYY-MM-DD HH:MM:SS)
Definition: GlobalFunctions.php:2436
MysqlUpdater\doMaybeProfilingMemoryUpdate
doMaybeProfilingMemoryUpdate()
Definition: MysqlUpdater.php:925
$wgContLang
this class mediates it Skin Encapsulates a look and feel for the wiki All of the functions that render HTML and make choices about how to render it are here and are called from various other places when and is meant to be subclassed with other skins that may override some of its functions The User object contains a reference to a and so rather than having a global skin object we just rely on the global User and get the skin with $wgUser and also has some character encoding functions and other locale stuff The current user interface language is instantiated as and the content language as $wgContLang
Definition: design.txt:56
MysqlUpdater\doEnableProfiling
doEnableProfiling()
Definition: MysqlUpdater.php:913
MysqlUpdater\doUserGroupsUpdate
doUserGroupsUpdate()
Definition: MysqlUpdater.php:687
MysqlUpdater\doClFieldsUpdate
doClFieldsUpdate()
Definition: MysqlUpdater.php:989
MysqlUpdater\doIndexUpdate
doIndexUpdate()
Check that proper indexes are in place.
Definition: MysqlUpdater.php:334
MysqlUpdater\doRestrictionsUpdate
doRestrictionsUpdate()
Adding page_restrictions table, obsoleting page.page_restrictions.
Definition: MysqlUpdater.php:853
MysqlUpdater\doPageRandomUpdate
doPageRandomUpdate()
Set page_random field to a random value where it is equals to 0.
Definition: MysqlUpdater.php:783
MWException
MediaWiki exception.
Definition: MWException.php:26
MysqlUpdater\doInterwikiUpdate
doInterwikiUpdate()
Check that interwiki table exists; if it doesn't source it.
Definition: MysqlUpdater.php:310
$titles
linkcache txt The LinkCache class maintains a list of article titles and the information about whether or not the article exists in the database This is used to mark up links when displaying a page If the same link appears more than once on any page then it only has to be looked up once In most cases link lookups are done in batches with the LinkBatch class or the equivalent in so the link cache is mostly useful for short snippets of parsed and for links in the navigation areas of the skin The link cache was formerly used to track links used in a document for the purposes of updating the link tables This application is now deprecated To create a you can use the following $titles
Definition: linkcache.txt:17
MysqlUpdater\doWatchlistNull
doWatchlistNull()
Make sure wl_notificationtimestamp can be NULL, and update old broken items.
Definition: MysqlUpdater.php:760
MysqlUpdater\doSchemaRestructuring
doSchemaRestructuring()
Definition: MysqlUpdater.php:410
MysqlUpdater\getCoreUpdateList
getCoreUpdateList()
Get an array of updates to perform on the database.
Definition: MysqlUpdater.php:31
MysqlUpdater\doLangLinksLengthUpdate
doLangLinksLengthUpdate()
Definition: MysqlUpdater.php:1003
MysqlUpdater\doUserNewTalkTimestampNotNull
doUserNewTalkTimestampNotNull()
Definition: MysqlUpdater.php:1019
array
the array() calling protocol came about after MediaWiki 1.4rc1.
List of Api Query prop modules.
global
when a variable name is used in a it is silently declared as a new masking the global
Definition: design.txt:93
wfWaitForSlaves
wfWaitForSlaves( $maxLag=false, $wiki=false, $cluster=false)
Modern version of wfWaitForSlaves().
Definition: GlobalFunctions.php:3795
list
deferred txt A few of the database updates required by various functions here can be deferred until after the result page is displayed to the user For updating the view updating the linked to tables after a etc PHP does not yet have any way to tell the server to actually return and disconnect while still running these but it might have such a feature in the future We handle these by creating a deferred update object and putting those objects on a global list
Definition: deferred.txt:11
DatabaseUpdater\updateRowExists
updateRowExists( $key)
Helper function: check if the given key is present in the updatelog table.
Definition: DatabaseUpdater.php:470
$name
Allows to change the fields on the form that will be generated $name
Definition: hooks.txt:336
MysqlUpdater\doOldLinksUpdate
doOldLinksUpdate()
Definition: MysqlUpdater.php:348
UserDupes
Look for duplicate user table entries and optionally prune them.
Definition: userDupes.inc:35
$count
$count
Definition: UtfNormalTest2.php:96
MysqlUpdater\doUserUniqueUpdate
doUserUniqueUpdate()
Definition: MysqlUpdater.php:669
as
This document is intended to provide useful advice for parties seeking to redistribute MediaWiki to end users It s targeted particularly at maintainers for Linux since it s been observed that distribution packages of MediaWiki often break We ve consistently had to recommend that users seeking support use official tarballs instead of their distribution s and this often solves whatever problem the user is having It would be nice if this could such as
Definition: distributors.txt:9
MWNamespace\getCanonicalNamespaces
static getCanonicalNamespaces( $rebuild=false)
Returns array of all defined namespaces with their canonical (English) names.
Definition: Namespace.php:218
MysqlUpdater\doFilearchiveIndicesUpdate
doFilearchiveIndicesUpdate()
Definition: MysqlUpdater.php:945
MysqlUpdater\indexHasField
indexHasField( $table, $index, $field)
Check whether an index contain a field.
Definition: MysqlUpdater.php:287
from
Please log in again after you receive it</td >< td > s a saved copy from
Definition: All_system_messages.txt:3297
MysqlUpdater\doCategoryPopulation
doCategoryPopulation()
Definition: MysqlUpdater.php:883
$t
$t
Definition: testCompression.php:65
MysqlUpdater\doNamespaceSize
doNamespaceSize()
Definition: MysqlUpdater.php:606
MysqlUpdater\doCategorylinksIndicesUpdate
doCategorylinksIndicesUpdate()
Definition: MysqlUpdater.php:877
$IP
$IP
Definition: WebStart.php:88
MysqlUpdater\doBacklinkingIndicesUpdate
doBacklinkingIndicesUpdate()
Definition: MysqlUpdater.php:839
$res
$res
Definition: database.txt:21
MysqlUpdater\doTemplatelinksUpdate
doTemplatelinksUpdate()
Definition: MysqlUpdater.php:795
MysqlUpdater\doIwlinksIndexNonUnique
doIwlinksIndexNonUnique()
Definition: MysqlUpdater.php:1041
MysqlUpdater
Mysql update list and mysql-specific update functions.
Definition: MysqlUpdater.php:30
MysqlUpdater\doPopulateParentId
doPopulateParentId()
Definition: MysqlUpdater.php:901