MediaWiki REL1_31
MysqlUpdater.php
Go to the documentation of this file.
1<?php
26
34 protected function getCoreUpdateList() {
35 return [
36 [ 'disableContentHandlerUseDB' ],
37
38 // 1.2
39 [ 'addField', 'ipblocks', 'ipb_id', 'patch-ipblocks.sql' ],
40 [ 'addField', 'ipblocks', 'ipb_expiry', 'patch-ipb_expiry.sql' ],
41 [ 'doInterwikiUpdate' ],
42 [ 'doIndexUpdate' ],
43 [ 'addField', 'recentchanges', 'rc_type', 'patch-rc_type.sql' ],
44 [ 'addIndex', 'recentchanges', 'new_name_timestamp', 'patch-rc-newindex.sql' ],
45
46 // 1.3
47 [ 'addField', 'user', 'user_real_name', 'patch-user-realname.sql' ],
48 [ 'addTable', 'querycache', 'patch-querycache.sql' ],
49 [ 'addTable', 'objectcache', 'patch-objectcache.sql' ],
50 [ 'addTable', 'categorylinks', 'patch-categorylinks.sql' ],
51 [ 'doOldLinksUpdate' ],
52 [ 'doFixAncientImagelinks' ],
53 [ 'addField', 'recentchanges', 'rc_ip', 'patch-rc_ip.sql' ],
54
55 // 1.4
56 [ 'addIndex', 'image', 'PRIMARY', 'patch-image_name_primary.sql' ],
57 [ 'addField', 'recentchanges', 'rc_id', 'patch-rc_id.sql' ],
58 [ 'addField', 'recentchanges', 'rc_patrolled', 'patch-rc-patrol.sql' ],
59 [ 'addTable', 'logging', 'patch-logging.sql' ],
60 [ 'addField', 'user', 'user_token', 'patch-user_token.sql' ],
61 [ 'addField', 'watchlist', 'wl_notificationtimestamp', 'patch-email-notification.sql' ],
62 [ 'doWatchlistUpdate' ],
63 [ 'dropField', 'user', 'user_emailauthenticationtimestamp',
64 'patch-email-authentication.sql' ],
65
66 // 1.5
67 [ 'doSchemaRestructuring' ],
68 [ 'addField', 'logging', 'log_params', 'patch-log_params.sql' ],
69 [ 'checkBin', 'logging', 'log_title', 'patch-logging-title.sql', ],
70 [ 'addField', 'archive', 'ar_rev_id', 'patch-archive-rev_id.sql' ],
71 [ 'addField', 'page', 'page_len', 'patch-page_len.sql' ],
72 [ 'dropField', 'revision', 'inverse_timestamp', 'patch-inverse_timestamp.sql' ],
73 [ 'addField', 'revision', 'rev_text_id', 'patch-rev_text_id.sql' ],
74 [ 'addField', 'revision', 'rev_deleted', 'patch-rev_deleted.sql' ],
75 [ 'addField', 'image', 'img_width', 'patch-img_width.sql' ],
76 [ 'addField', 'image', 'img_metadata', 'patch-img_metadata.sql' ],
77 [ 'addField', 'user', 'user_email_token', 'patch-user_email_token.sql' ],
78 [ 'addField', 'archive', 'ar_text_id', 'patch-archive-text_id.sql' ],
79 [ 'doNamespaceSize' ],
80 [ 'addField', 'image', 'img_media_type', 'patch-img_media_type.sql' ],
81 [ 'doPagelinksUpdate' ],
82 [ 'dropField', 'image', 'img_type', 'patch-drop_img_type.sql' ],
83 [ 'doUserUniqueUpdate' ],
84 [ 'doUserGroupsUpdate' ],
85 [ 'addField', 'site_stats', 'ss_total_pages', 'patch-ss_total_articles.sql' ],
86 [ 'addTable', 'user_newtalk', 'patch-usernewtalk.sql' ],
87 [ 'addTable', 'transcache', 'patch-transcache.sql' ],
88 [ 'addField', 'interwiki', 'iw_trans', 'patch-interwiki-trans.sql' ],
89
90 // 1.6
91 [ 'doWatchlistNull' ],
92 [ 'addIndex', 'logging', 'times', 'patch-logging-times-index.sql' ],
93 [ 'addField', 'ipblocks', 'ipb_range_start', 'patch-ipb_range_start.sql' ],
94 [ 'doPageRandomUpdate' ],
95 [ 'addField', 'user', 'user_registration', 'patch-user_registration.sql' ],
96 [ 'doTemplatelinksUpdate' ],
97 [ 'addTable', 'externallinks', 'patch-externallinks.sql' ],
98 [ 'addTable', 'job', 'patch-job.sql' ],
99 [ 'addField', 'site_stats', 'ss_images', 'patch-ss_images.sql' ],
100 [ 'addTable', 'langlinks', 'patch-langlinks.sql' ],
101 [ 'addTable', 'querycache_info', 'patch-querycacheinfo.sql' ],
102 [ 'addTable', 'filearchive', 'patch-filearchive.sql' ],
103 [ 'addField', 'ipblocks', 'ipb_anon_only', 'patch-ipb_anon_only.sql' ],
104 [ 'addIndex', 'recentchanges', 'rc_ns_usertext', 'patch-recentchanges-utindex.sql' ],
105 [ 'addIndex', 'recentchanges', 'rc_user_text', 'patch-rc_user_text-index.sql' ],
106
107 // 1.9
108 [ 'addField', 'user', 'user_newpass_time', 'patch-user_newpass_time.sql' ],
109 [ 'addTable', 'redirect', 'patch-redirect.sql' ],
110 [ 'addTable', 'querycachetwo', 'patch-querycachetwo.sql' ],
111 [ 'addField', 'ipblocks', 'ipb_enable_autoblock', 'patch-ipb_optional_autoblock.sql' ],
112 [ 'doBacklinkingIndicesUpdate' ],
113 [ 'addField', 'recentchanges', 'rc_old_len', 'patch-rc_len.sql' ],
114 [ 'addField', 'user', 'user_editcount', 'patch-user_editcount.sql' ],
115
116 // 1.10
117 [ 'doRestrictionsUpdate' ],
118 [ 'addField', 'logging', 'log_id', 'patch-log_id.sql' ],
119 [ 'addField', 'revision', 'rev_parent_id', 'patch-rev_parent_id.sql' ],
120 [ 'addField', 'page_restrictions', 'pr_id', 'patch-page_restrictions_sortkey.sql' ],
121 [ 'addField', 'revision', 'rev_len', 'patch-rev_len.sql' ],
122 [ 'addField', 'recentchanges', 'rc_deleted', 'patch-rc_deleted.sql' ],
123 [ 'addField', 'logging', 'log_deleted', 'patch-log_deleted.sql' ],
124 [ 'addField', 'archive', 'ar_deleted', 'patch-ar_deleted.sql' ],
125 [ 'addField', 'ipblocks', 'ipb_deleted', 'patch-ipb_deleted.sql' ],
126 [ 'addField', 'filearchive', 'fa_deleted', 'patch-fa_deleted.sql' ],
127 [ 'addField', 'archive', 'ar_len', 'patch-ar_len.sql' ],
128
129 // 1.11
130 [ 'addField', 'ipblocks', 'ipb_block_email', 'patch-ipb_emailban.sql' ],
131 [ 'doCategorylinksIndicesUpdate' ],
132 [ 'addField', 'oldimage', 'oi_metadata', 'patch-oi_metadata.sql' ],
133 [ 'addIndex', 'archive', 'usertext_timestamp', 'patch-archive-user-index.sql' ],
134 [ 'addIndex', 'image', 'img_usertext_timestamp', 'patch-image-user-index.sql' ],
135 [ 'addIndex', 'oldimage', 'oi_usertext_timestamp', 'patch-oldimage-user-index.sql' ],
136 [ 'addField', 'archive', 'ar_page_id', 'patch-archive-page_id.sql' ],
137 [ 'addField', 'image', 'img_sha1', 'patch-img_sha1.sql' ],
138
139 // 1.12
140 [ 'addTable', 'protected_titles', 'patch-protected_titles.sql' ],
141
142 // 1.13
143 [ 'addField', 'ipblocks', 'ipb_by_text', 'patch-ipb_by_text.sql' ],
144 [ 'addTable', 'page_props', 'patch-page_props.sql' ],
145 [ 'addTable', 'updatelog', 'patch-updatelog.sql' ],
146 [ 'addTable', 'category', 'patch-category.sql' ],
147 [ 'doCategoryPopulation' ],
148 [ 'addField', 'archive', 'ar_parent_id', 'patch-ar_parent_id.sql' ],
149 [ 'addField', 'user_newtalk', 'user_last_timestamp', 'patch-user_last_timestamp.sql' ],
150 [ 'doPopulateParentId' ],
151 [ 'checkBin', 'protected_titles', 'pt_title', 'patch-pt_title-encoding.sql', ],
152 [ 'doMaybeProfilingMemoryUpdate' ],
153 [ 'doFilearchiveIndicesUpdate' ],
154
155 // 1.14
156 [ 'addField', 'site_stats', 'ss_active_users', 'patch-ss_active_users.sql' ],
157 [ 'doActiveUsersInit' ],
158 [ 'addField', 'ipblocks', 'ipb_allow_usertalk', 'patch-ipb_allow_usertalk.sql' ],
159
160 // 1.15
161 [ 'addTable', 'change_tag', 'patch-change_tag.sql' ],
162 [ 'addTable', 'tag_summary', 'patch-tag_summary.sql' ],
163 [ 'addTable', 'valid_tag', 'patch-valid_tag.sql' ],
164
165 // 1.16
166 [ 'addTable', 'user_properties', 'patch-user_properties.sql' ],
167 [ 'addTable', 'log_search', 'patch-log_search.sql' ],
168 [ 'addField', 'logging', 'log_user_text', 'patch-log_user_text.sql' ],
169 # listed separately from the previous update because 1.16 was released without this update
170 [ 'doLogUsertextPopulation' ],
171 [ 'doLogSearchPopulation' ],
172 [ 'addTable', 'l10n_cache', 'patch-l10n_cache.sql' ],
173 [ 'addIndex', 'change_tag', 'change_tag_rc_tag', 'patch-change_tag-indexes.sql' ],
174 [ 'addField', 'redirect', 'rd_interwiki', 'patch-rd_interwiki.sql' ],
175 [ 'doUpdateTranscacheField' ],
176 [ 'doUpdateMimeMinorField' ],
177
178 // 1.17
179 [ 'addTable', 'iwlinks', 'patch-iwlinks.sql' ],
180 [ 'addIndex', 'iwlinks', 'iwl_prefix_title_from', 'patch-rename-iwl_prefix.sql' ],
181 [ 'addField', 'updatelog', 'ul_value', 'patch-ul_value.sql' ],
182 [ 'addField', 'interwiki', 'iw_api', 'patch-iw_api_and_wikiid.sql' ],
183 [ 'dropIndex', 'iwlinks', 'iwl_prefix', 'patch-kill-iwl_prefix.sql' ],
184 [ 'addField', 'categorylinks', 'cl_collation', 'patch-categorylinks-better-collation.sql' ],
185 [ 'doClFieldsUpdate' ],
186 [ 'addTable', 'module_deps', 'patch-module_deps.sql' ],
187 [ 'dropIndex', 'archive', 'ar_page_revid', 'patch-archive_kill_ar_page_revid.sql' ],
188 [ 'addIndex', 'archive', 'ar_revid', 'patch-archive_ar_revid.sql' ],
189 [ 'doLangLinksLengthUpdate' ],
190
191 // 1.18
192 [ 'doUserNewTalkTimestampNotNull' ],
193 [ 'addIndex', 'user', 'user_email', 'patch-user_email_index.sql' ],
194 [ 'modifyField', 'user_properties', 'up_property', 'patch-up_property.sql' ],
195 [ 'addTable', 'uploadstash', 'patch-uploadstash.sql' ],
196 [ 'addTable', 'user_former_groups', 'patch-user_former_groups.sql' ],
197
198 // 1.19
199 [ 'addIndex', 'logging', 'type_action', 'patch-logging-type-action-index.sql' ],
200 [ 'addField', 'revision', 'rev_sha1', 'patch-rev_sha1.sql' ],
201 [ 'doMigrateUserOptions' ],
202 [ 'dropField', 'user', 'user_options', 'patch-drop-user_options.sql' ],
203 [ 'addField', 'archive', 'ar_sha1', 'patch-ar_sha1.sql' ],
204 [ 'addIndex', 'page', 'page_redirect_namespace_len',
205 'patch-page_redirect_namespace_len.sql' ],
206 [ 'addField', 'uploadstash', 'us_chunk_inx', 'patch-uploadstash_chunk.sql' ],
207 [ 'addfield', 'job', 'job_timestamp', 'patch-jobs-add-timestamp.sql' ],
208
209 // 1.20
210 [ 'addIndex', 'revision', 'page_user_timestamp', 'patch-revision-user-page-index.sql' ],
211 [ 'addField', 'ipblocks', 'ipb_parent_block_id', 'patch-ipb-parent-block-id.sql' ],
212 [ 'addIndex', 'ipblocks', 'ipb_parent_block_id', 'patch-ipb-parent-block-id-index.sql' ],
213 [ 'dropField', 'category', 'cat_hidden', 'patch-cat_hidden.sql' ],
214
215 // 1.21
216 [ 'addField', 'revision', 'rev_content_format', 'patch-revision-rev_content_format.sql' ],
217 [ 'addField', 'revision', 'rev_content_model', 'patch-revision-rev_content_model.sql' ],
218 [ 'addField', 'archive', 'ar_content_format', 'patch-archive-ar_content_format.sql' ],
219 [ 'addField', 'archive', 'ar_content_model', 'patch-archive-ar_content_model.sql' ],
220 [ 'addField', 'page', 'page_content_model', 'patch-page-page_content_model.sql' ],
221 [ 'enableContentHandlerUseDB' ],
222 [ 'dropField', 'site_stats', 'ss_admins', 'patch-drop-ss_admins.sql' ],
223 [ 'dropField', 'recentchanges', 'rc_moved_to_title', 'patch-rc_moved.sql' ],
224 [ 'addTable', 'sites', 'patch-sites.sql' ],
225 [ 'addField', 'filearchive', 'fa_sha1', 'patch-fa_sha1.sql' ],
226 [ 'addField', 'job', 'job_token', 'patch-job_token.sql' ],
227 [ 'addField', 'job', 'job_attempts', 'patch-job_attempts.sql' ],
228 [ 'doEnableProfiling' ],
229 [ 'addField', 'uploadstash', 'us_props', 'patch-uploadstash-us_props.sql' ],
230 [ 'modifyField', 'user_groups', 'ug_group', 'patch-ug_group-length-increase-255.sql' ],
231 [ 'modifyField', 'user_former_groups', 'ufg_group',
232 'patch-ufg_group-length-increase-255.sql' ],
233 [ 'addIndex', 'page_props', 'pp_propname_page',
234 'patch-page_props-propname-page-index.sql' ],
235 [ 'addIndex', 'image', 'img_media_mime', 'patch-img_media_mime-index.sql' ],
236
237 // 1.22
238 [ 'doIwlinksIndexNonUnique' ],
239 [ 'addIndex', 'iwlinks', 'iwl_prefix_from_title',
240 'patch-iwlinks-from-title-index.sql' ],
241 [ 'addField', 'archive', 'ar_id', 'patch-archive-ar_id.sql' ],
242 [ 'addField', 'externallinks', 'el_id', 'patch-externallinks-el_id.sql' ],
243
244 // 1.23
245 [ 'addField', 'recentchanges', 'rc_source', 'patch-rc_source.sql' ],
246 [ 'addIndex', 'logging', 'log_user_text_type_time',
247 'patch-logging_user_text_type_time_index.sql' ],
248 [ 'addIndex', 'logging', 'log_user_text_time', 'patch-logging_user_text_time_index.sql' ],
249 [ 'addField', 'page', 'page_links_updated', 'patch-page_links_updated.sql' ],
250 [ 'addField', 'user', 'user_password_expires', 'patch-user_password_expire.sql' ],
251
252 // 1.24
253 [ 'addField', 'page_props', 'pp_sortkey', 'patch-pp_sortkey.sql' ],
254 [ 'dropField', 'recentchanges', 'rc_cur_time', 'patch-drop-rc_cur_time.sql' ],
255 [ 'addIndex', 'watchlist', 'wl_user_notificationtimestamp',
256 'patch-watchlist-user-notificationtimestamp-index.sql' ],
257 [ 'addField', 'page', 'page_lang', 'patch-page_lang.sql' ],
258 [ 'addField', 'pagelinks', 'pl_from_namespace', 'patch-pl_from_namespace.sql' ],
259 [ 'addField', 'templatelinks', 'tl_from_namespace', 'patch-tl_from_namespace.sql' ],
260 [ 'addField', 'imagelinks', 'il_from_namespace', 'patch-il_from_namespace.sql' ],
261 [ 'modifyField', 'image', 'img_major_mime',
262 'patch-img_major_mime-chemical.sql' ],
263 [ 'modifyField', 'oldimage', 'oi_major_mime',
264 'patch-oi_major_mime-chemical.sql' ],
265 [ 'modifyField', 'filearchive', 'fa_major_mime',
266 'patch-fa_major_mime-chemical.sql' ],
267
268 // 1.25
269 // note this patch covers other _comment and _description fields too
270 [ 'doExtendCommentLengths' ],
271
272 // 1.26
273 [ 'dropTable', 'hitcounter' ],
274 [ 'dropField', 'site_stats', 'ss_total_views', 'patch-drop-ss_total_views.sql' ],
275 [ 'dropField', 'page', 'page_counter', 'patch-drop-page_counter.sql' ],
276
277 // 1.27
278 [ 'dropTable', 'msg_resource_links' ],
279 [ 'dropTable', 'msg_resource' ],
280 [ 'addTable', 'bot_passwords', 'patch-bot_passwords.sql' ],
281 [ 'addField', 'watchlist', 'wl_id', 'patch-watchlist-wl_id.sql' ],
282 [ 'dropIndex', 'categorylinks', 'cl_collation', 'patch-kill-cl_collation_index.sql' ],
283 [ 'addIndex', 'categorylinks', 'cl_collation_ext',
284 'patch-add-cl_collation_ext_index.sql' ],
285 [ 'doCollationUpdate' ],
286
287 // 1.28
288 [ 'addIndex', 'recentchanges', 'rc_name_type_patrolled_timestamp',
289 'patch-add-rc_name_type_patrolled_timestamp_index.sql' ],
290 [ 'doRevisionPageRevIndexNonUnique' ],
291 [ 'doNonUniquePlTlIl' ],
292 [ 'addField', 'change_tag', 'ct_id', 'patch-change_tag-ct_id.sql' ],
293 [ 'addField', 'tag_summary', 'ts_id', 'patch-tag_summary-ts_id.sql' ],
294 [ 'modifyField', 'recentchanges', 'rc_ip', 'patch-rc_ip_modify.sql' ],
295 [ 'addIndex', 'archive', 'usertext_timestamp', 'patch-rename-ar_usertext_timestamp.sql' ],
296
297 // 1.29
298 [ 'addField', 'externallinks', 'el_index_60', 'patch-externallinks-el_index_60.sql' ],
299 [ 'dropIndex', 'user_groups', 'ug_user_group', 'patch-user_groups-primary-key.sql' ],
300 [ 'addField', 'user_groups', 'ug_expiry', 'patch-user_groups-ug_expiry.sql' ],
301 [ 'addIndex', 'image', 'img_user_timestamp', 'patch-image-user-index-2.sql' ],
302
303 // 1.30
304 [ 'modifyField', 'image', 'img_media_type', 'patch-add-3d.sql' ],
305 [ 'addTable', 'ip_changes', 'patch-ip_changes.sql' ],
306 [ 'renameIndex', 'categorylinks', 'cl_from', 'PRIMARY', false,
307 'patch-categorylinks-fix-pk.sql' ],
308 [ 'renameIndex', 'templatelinks', 'tl_from', 'PRIMARY', false,
309 'patch-templatelinks-fix-pk.sql' ],
310 [ 'renameIndex', 'pagelinks', 'pl_from', 'PRIMARY', false, 'patch-pagelinks-fix-pk.sql' ],
311 [ 'renameIndex', 'text', 'old_id', 'PRIMARY', false, 'patch-text-fix-pk.sql' ],
312 [ 'renameIndex', 'imagelinks', 'il_from', 'PRIMARY', false, 'patch-imagelinks-fix-pk.sql' ],
313 [ 'renameIndex', 'iwlinks', 'iwl_from', 'PRIMARY', false, 'patch-iwlinks-fix-pk.sql' ],
314 [ 'renameIndex', 'langlinks', 'll_from', 'PRIMARY', false, 'patch-langlinks-fix-pk.sql' ],
315 [ 'renameIndex', 'log_search', 'ls_field_val', 'PRIMARY', false, 'patch-log_search-fix-pk.sql' ],
316 [ 'renameIndex', 'module_deps', 'md_module_skin', 'PRIMARY', false,
317 'patch-module_deps-fix-pk.sql' ],
318 [ 'renameIndex', 'objectcache', 'keyname', 'PRIMARY', false, 'patch-objectcache-fix-pk.sql' ],
319 [ 'renameIndex', 'querycache_info', 'qci_type', 'PRIMARY', false,
320 'patch-querycache_info-fix-pk.sql' ],
321 [ 'renameIndex', 'site_stats', 'ss_row_id', 'PRIMARY', false, 'patch-site_stats-fix-pk.sql' ],
322 [ 'renameIndex', 'transcache', 'tc_url_idx', 'PRIMARY', false, 'patch-transcache-fix-pk.sql' ],
323 [ 'renameIndex', 'user_former_groups', 'ufg_user_group', 'PRIMARY', false,
324 'patch-user_former_groups-fix-pk.sql' ],
325 [ 'renameIndex', 'user_properties', 'user_properties_user_property', 'PRIMARY', false,
326 'patch-user_properties-fix-pk.sql' ],
327 [ 'addTable', 'comment', 'patch-comment-table.sql' ],
328 [ 'addTable', 'revision_comment_temp', 'patch-revision_comment_temp-table.sql' ],
329 [ 'addTable', 'image_comment_temp', 'patch-image_comment_temp-table.sql' ],
330 [ 'addField', 'archive', 'ar_comment_id', 'patch-archive-ar_comment_id.sql' ],
331 [ 'addField', 'filearchive', 'fa_description_id', 'patch-filearchive-fa_description_id.sql' ],
332 [ 'modifyField', 'image', 'img_description', 'patch-image-img_description-default.sql' ],
333 [ 'addField', 'ipblocks', 'ipb_reason_id', 'patch-ipblocks-ipb_reason_id.sql' ],
334 [ 'addField', 'logging', 'log_comment_id', 'patch-logging-log_comment_id.sql' ],
335 [ 'addField', 'oldimage', 'oi_description_id', 'patch-oldimage-oi_description_id.sql' ],
336 [ 'addField', 'protected_titles', 'pt_reason_id', 'patch-protected_titles-pt_reason_id.sql' ],
337 [ 'addField', 'recentchanges', 'rc_comment_id', 'patch-recentchanges-rc_comment_id.sql' ],
338 [ 'modifyField', 'revision', 'rev_comment', 'patch-revision-rev_comment-default.sql' ],
339
340 // This field was added in 1.31, but is put here so it can be used by 'migrateComments'
341 [ 'addField', 'image', 'img_description_id', 'patch-image-img_description_id.sql' ],
342
343 [ 'migrateComments' ],
344 [ 'renameIndex', 'l10n_cache', 'lc_lang_key', 'PRIMARY', false,
345 'patch-l10n_cache-primary-key.sql' ],
346 [ 'doUnsignedSyncronisation' ],
347
348 // 1.31
349 [ 'addTable', 'slots', 'patch-slots.sql' ],
350 [ 'addField', 'slots', 'slot_origin', 'patch-slot-origin.sql' ],
351 [ 'addTable', 'content', 'patch-content.sql' ],
352 [ 'addTable', 'slot_roles', 'patch-slot_roles.sql' ],
353 [ 'addTable', 'content_models', 'patch-content_models.sql' ],
354 [ 'migrateArchiveText' ],
355 [ 'addTable', 'actor', 'patch-actor-table.sql' ],
356 [ 'addTable', 'revision_actor_temp', 'patch-revision_actor_temp-table.sql' ],
357 [ 'addField', 'archive', 'ar_actor', 'patch-archive-ar_actor.sql' ],
358 [ 'addField', 'ipblocks', 'ipb_by_actor', 'patch-ipblocks-ipb_by_actor.sql' ],
359 [ 'addField', 'image', 'img_actor', 'patch-image-img_actor.sql' ],
360 [ 'addField', 'oldimage', 'oi_actor', 'patch-oldimage-oi_actor.sql' ],
361 [ 'addField', 'filearchive', 'fa_actor', 'patch-filearchive-fa_actor.sql' ],
362 [ 'addField', 'recentchanges', 'rc_actor', 'patch-recentchanges-rc_actor.sql' ],
363 [ 'addField', 'logging', 'log_actor', 'patch-logging-log_actor.sql' ],
364 [ 'migrateActors' ],
365 [ 'modifyField', 'revision', 'rev_text_id', 'patch-rev_text_id-default.sql' ],
366 [ 'modifyTable', 'site_stats', 'patch-site_stats-modify.sql' ],
367 [ 'populateArchiveRevId' ],
368 [ 'addIndex', 'recentchanges', 'rc_namespace_title_timestamp',
369 'patch-recentchanges-nttindex.sql' ],
370 ];
371 }
372
382 protected function checkBin( $table, $field, $patchFile ) {
383 if ( !$this->doTable( $table ) ) {
384 return true;
385 }
386
388 $fieldInfo = $this->db->fieldInfo( $table, $field );
389 if ( $fieldInfo->isBinary() ) {
390 $this->output( "...$table table has correct $field encoding.\n" );
391 } else {
392 $this->applyPatch( $patchFile, false, "Fixing $field encoding on $table table" );
393 }
394 }
395
404 protected function indexHasField( $table, $index, $field ) {
405 if ( !$this->doTable( $table ) ) {
406 return true;
407 }
408
409 $info = $this->db->indexInfo( $table, $index, __METHOD__ );
410 if ( $info ) {
411 foreach ( $info as $row ) {
412 if ( $row->Column_name == $field ) {
413 $this->output( "...index $index on table $table includes field $field.\n" );
414
415 return true;
416 }
417 }
418 }
419 $this->output( "...index $index on table $table has no field $field; added.\n" );
420
421 return false;
422 }
423
427 protected function doInterwikiUpdate() {
428 global $IP;
429
430 if ( !$this->doTable( 'interwiki' ) ) {
431 return;
432 }
433
434 if ( $this->db->tableExists( "interwiki", __METHOD__ ) ) {
435 $this->output( "...already have interwiki table\n" );
436
437 return;
438 }
439
440 $this->applyPatch( 'patch-interwiki.sql', false, 'Creating interwiki table' );
441 $this->applyPatch(
442 "$IP/maintenance/interwiki.sql",
443 true,
444 'Adding default interwiki definitions'
445 );
446 }
447
451 protected function doIndexUpdate() {
452 $meta = $this->db->fieldInfo( 'recentchanges', 'rc_timestamp' );
453 if ( $meta === false ) {
454 throw new MWException( 'Missing rc_timestamp field of recentchanges table. Should not happen.' );
455 }
456 if ( $meta->isMultipleKey() ) {
457 $this->output( "...indexes seem up to 20031107 standards.\n" );
458
459 return;
460 }
461
462 $this->applyPatch( 'patch-indexes.sql', true, "Updating indexes to 20031107" );
463 }
464
465 protected function doOldLinksUpdate() {
466 $cl = $this->maintenance->runChild( ConvertLinks::class );
467 $cl->execute();
468 }
469
470 protected function doFixAncientImagelinks() {
471 $info = $this->db->fieldInfo( 'imagelinks', 'il_from' );
472 if ( !$info || $info->type() !== 'string' ) {
473 $this->output( "...il_from OK\n" );
474
475 return;
476 }
477
478 $applied = $this->applyPatch(
479 'patch-fix-il_from.sql',
480 false,
481 'Fixing ancient broken imagelinks table.'
482 );
483
484 if ( $applied ) {
485 $this->output( "NOTE: you will have to run maintenance/refreshLinks.php after this." );
486 }
487 }
488
492 function doWatchlistUpdate() {
493 $talk = $this->db->selectField( 'watchlist', 'count(*)', 'wl_namespace & 1', __METHOD__ );
494 $nontalk = $this->db->selectField(
495 'watchlist',
496 'count(*)',
497 'NOT (wl_namespace & 1)',
498 __METHOD__
499 );
500 if ( $talk == $nontalk ) {
501 $this->output( "...watchlist talk page rows already present.\n" );
502
503 return;
504 }
505
506 $insertOpts = [ 'IGNORE' ];
507 $selectOpts = [];
508
509 // If wl_id exists, make insertSelect() more replication-safe by
510 // ordering on that column. If not, hint that it should be safe anyway.
511 if ( $this->db->fieldExists( 'watchlist', 'wl_id', __METHOD__ ) ) {
512 $selectOpts['ORDER BY'] = 'wl_id';
513 } else {
514 $insertOpts[] = 'NO_AUTO_COLUMNS';
515 }
516
517 $this->output( "Adding missing watchlist talk page rows... " );
518 $this->db->insertSelect( 'watchlist', 'watchlist',
519 [
520 'wl_user' => 'wl_user',
521 'wl_namespace' => 'wl_namespace | 1',
522 'wl_title' => 'wl_title',
523 'wl_notificationtimestamp' => 'wl_notificationtimestamp'
524 ], [ 'NOT (wl_namespace & 1)' ], __METHOD__, $insertOpts, $selectOpts );
525 $this->output( "done.\n" );
526
527 $this->output( "Adding missing watchlist subject page rows... " );
528 $this->db->insertSelect( 'watchlist', 'watchlist',
529 [
530 'wl_user' => 'wl_user',
531 'wl_namespace' => 'wl_namespace & ~1',
532 'wl_title' => 'wl_title',
533 'wl_notificationtimestamp' => 'wl_notificationtimestamp'
534 ], [ 'wl_namespace & 1' ], __METHOD__, $insertOpts, $selectOpts );
535 $this->output( "done.\n" );
536 }
537
539 if ( $this->db->tableExists( 'page', __METHOD__ ) ) {
540 $this->output( "...page table already exists.\n" );
541
542 return;
543 }
544
545 $this->output( "...converting from cur/old to page/revision/text DB structure.\n" );
546 $this->output( wfTimestamp( TS_DB ) );
547 $this->output( "......checking for duplicate entries.\n" );
548
549 list( $cur, $old, $page, $revision, $text ) = $this->db->tableNamesN(
550 'cur',
551 'old',
552 'page',
553 'revision',
554 'text'
555 );
556
557 $rows = $this->db->query( "
558 SELECT cur_title, cur_namespace, COUNT(cur_namespace) AS c
559 FROM $cur
560 GROUP BY cur_title, cur_namespace
561 HAVING c>1",
562 __METHOD__
563 );
564
565 if ( $rows->numRows() > 0 ) {
566 $this->output( wfTimestamp( TS_DB ) );
567 $this->output( "......<b>Found duplicate entries</b>\n" );
568 $this->output( sprintf( "<b> %-60s %3s %5s</b>\n", 'Title', 'NS', 'Count' ) );
569 $duplicate = [];
570 foreach ( $rows as $row ) {
571 if ( !isset( $duplicate[$row->cur_namespace] ) ) {
572 $duplicate[$row->cur_namespace] = [];
573 }
574
575 $duplicate[$row->cur_namespace][] = $row->cur_title;
576 $this->output( sprintf(
577 " %-60s %3s %5s\n",
578 $row->cur_title, $row->cur_namespace,
579 $row->c
580 ) );
581 }
582 $sql = "SELECT cur_title, cur_namespace, cur_id, cur_timestamp FROM $cur WHERE ";
583 $dupeTitles = [];
584 foreach ( $duplicate as $ns => $titles ) {
585 $dupeTitles[] = "( cur_namespace = {$ns} AND cur_title in ("
586 . $this->db->makeList( $titles ) . ") ) \n";
587 }
588 $sql .= $this->db->makeList( $dupeTitles, IDatabase::LIST_OR );
589 # By sorting descending, the most recent entry will be the first in the list.
590 # All following entries will be deleted by the next while-loop.
591 $sql .= 'ORDER BY cur_namespace, cur_title, cur_timestamp DESC';
592
593 $rows = $this->db->query( $sql, __METHOD__ );
594
595 $prev_title = $prev_namespace = false;
596 $deleteId = [];
597
598 foreach ( $rows as $row ) {
599 if ( $prev_title == $row->cur_title && $prev_namespace == $row->cur_namespace ) {
600 $deleteId[] = $row->cur_id;
601 }
602 $prev_title = $row->cur_title;
603 $prev_namespace = $row->cur_namespace;
604 }
605 $sql = "DELETE FROM $cur WHERE cur_id IN ( " . implode( ',', $deleteId ) . ')';
606 $this->db->query( $sql, __METHOD__ );
607 $this->output( wfTimestamp( TS_DB ) );
608 $this->output( "......<b>Deleted</b> " . $this->db->affectedRows() . " records.\n" );
609 }
610
611 $this->output( wfTimestamp( TS_DB ) );
612 $this->output( "......Creating tables.\n" );
613 $this->db->query( "CREATE TABLE $page (
614 page_id int(8) unsigned NOT NULL auto_increment,
615 page_namespace int NOT NULL,
616 page_title varchar(255) binary NOT NULL,
617 page_restrictions tinyblob NOT NULL,
618 page_is_redirect tinyint(1) unsigned NOT NULL default '0',
619 page_is_new tinyint(1) unsigned NOT NULL default '0',
620 page_random real unsigned NOT NULL,
621 page_touched char(14) binary NOT NULL default '',
622 page_latest int(8) unsigned NOT NULL,
623 page_len int(8) unsigned NOT NULL,
624
625 PRIMARY KEY page_id (page_id),
626 UNIQUE INDEX name_title (page_namespace,page_title),
627 INDEX (page_random),
628 INDEX (page_len)
629 ) ENGINE=InnoDB", __METHOD__ );
630 $this->db->query( "CREATE TABLE $revision (
631 rev_id int(8) unsigned NOT NULL auto_increment,
632 rev_page int(8) unsigned NOT NULL,
633 rev_comment tinyblob NOT NULL,
634 rev_user int(5) unsigned NOT NULL default '0',
635 rev_user_text varchar(255) binary NOT NULL default '',
636 rev_timestamp char(14) binary NOT NULL default '',
637 rev_minor_edit tinyint(1) unsigned NOT NULL default '0',
638 rev_deleted tinyint(1) unsigned NOT NULL default '0',
639 rev_len int(8) unsigned,
640 rev_parent_id int(8) unsigned default NULL,
641 PRIMARY KEY rev_page_id (rev_page, rev_id),
642 UNIQUE INDEX rev_id (rev_id),
643 INDEX rev_timestamp (rev_timestamp),
644 INDEX page_timestamp (rev_page,rev_timestamp),
645 INDEX user_timestamp (rev_user,rev_timestamp),
646 INDEX usertext_timestamp (rev_user_text,rev_timestamp)
647 ) ENGINE=InnoDB", __METHOD__ );
648
649 $this->output( wfTimestamp( TS_DB ) );
650 $this->output( "......Locking tables.\n" );
651 $this->db->query(
652 "LOCK TABLES $page WRITE, $revision WRITE, $old WRITE, $cur WRITE",
653 __METHOD__
654 );
655
656 $maxold = intval( $this->db->selectField( 'old', 'max(old_id)', '', __METHOD__ ) );
657 $this->output( wfTimestamp( TS_DB ) );
658 $this->output( "......maxold is {$maxold}\n" );
659
660 $this->output( wfTimestamp( TS_DB ) );
663 // Create HistoryBlobCurStub entries.
664 // Text will be pulled from the leftover 'cur' table at runtime.
665 $this->output( "......Moving metadata from cur; using blob references to text in cur table.\n" );
666 $cur_text = "concat('O:18:\"historyblobcurstub\":1:{s:6:\"mCurId\";i:',cur_id,';}')";
667 $cur_flags = "'object'";
668 } else {
669 // Copy all cur text in immediately: this may take longer but avoids
670 // having to keep an extra table around.
671 $this->output( "......Moving text from cur.\n" );
672 $cur_text = 'cur_text';
673 $cur_flags = "''";
674 }
675 $this->db->query(
676 "INSERT INTO $old (old_namespace, old_title, old_text, old_comment, old_user,
677 old_user_text, old_timestamp, old_minor_edit, old_flags)
678 SELECT cur_namespace, cur_title, $cur_text, cur_comment, cur_user, cur_user_text,
679 cur_timestamp, cur_minor_edit, $cur_flags
680 FROM $cur",
681 __METHOD__
682 );
683
684 $this->output( wfTimestamp( TS_DB ) );
685 $this->output( "......Setting up revision table.\n" );
686 $this->db->query(
687 "INSERT INTO $revision (rev_id, rev_page, rev_comment, rev_user,
688 rev_user_text, rev_timestamp, rev_minor_edit)
689 SELECT old_id, cur_id, old_comment, old_user, old_user_text,
690 old_timestamp, old_minor_edit
691 FROM $old,$cur WHERE old_namespace=cur_namespace AND old_title=cur_title",
692 __METHOD__
693 );
694
695 $this->output( wfTimestamp( TS_DB ) );
696 $this->output( "......Setting up page table.\n" );
697 $this->db->query(
698 "INSERT INTO $page (page_id, page_namespace, page_title,
699 page_restrictions, page_is_redirect, page_is_new, page_random,
700 page_touched, page_latest, page_len)
701 SELECT cur_id, cur_namespace, cur_title, cur_restrictions,
702 cur_is_redirect, cur_is_new, cur_random, cur_touched, rev_id, LENGTH(cur_text)
703 FROM $cur,$revision
704 WHERE cur_id=rev_page AND rev_timestamp=cur_timestamp AND rev_id > {$maxold}",
705 __METHOD__
706 );
707
708 $this->output( wfTimestamp( TS_DB ) );
709 $this->output( "......Unlocking tables.\n" );
710 $this->db->query( "UNLOCK TABLES", __METHOD__ );
711
712 $this->output( wfTimestamp( TS_DB ) );
713 $this->output( "......Renaming old.\n" );
714 $this->db->query( "ALTER TABLE $old RENAME TO $text", __METHOD__ );
715
716 $this->output( wfTimestamp( TS_DB ) );
717 $this->output( "...done.\n" );
718 }
719
720 protected function doNamespaceSize() {
721 $tables = [
722 'page' => 'page',
723 'archive' => 'ar',
724 'recentchanges' => 'rc',
725 'watchlist' => 'wl',
726 'querycache' => 'qc',
727 'logging' => 'log',
728 ];
729 foreach ( $tables as $table => $prefix ) {
730 $field = $prefix . '_namespace';
731
732 $tablename = $this->db->tableName( $table );
733 $result = $this->db->query( "SHOW COLUMNS FROM $tablename LIKE '$field'", __METHOD__ );
734 $info = $this->db->fetchObject( $result );
735
736 if ( substr( $info->Type, 0, 3 ) == 'int' ) {
737 $this->output( "...$field is already a full int ($info->Type).\n" );
738 } else {
739 $this->output( "Promoting $field from $info->Type to int... " );
740 $this->db->query( "ALTER TABLE $tablename MODIFY $field int NOT NULL", __METHOD__ );
741 $this->output( "done.\n" );
742 }
743 }
744 }
745
746 protected function doPagelinksUpdate() {
747 if ( $this->db->tableExists( 'pagelinks', __METHOD__ ) ) {
748 $this->output( "...already have pagelinks table.\n" );
749
750 return;
751 }
752
753 $this->applyPatch(
754 'patch-pagelinks.sql',
755 false,
756 'Converting links and brokenlinks tables to pagelinks'
757 );
758
759 global $wgContLang;
760 foreach ( $wgContLang->getNamespaces() as $ns => $name ) {
761 if ( $ns == 0 ) {
762 continue;
763 }
764
765 $this->output( "Cleaning up broken links for namespace $ns... " );
766 $this->db->update( 'pagelinks',
767 [
768 'pl_namespace' => $ns,
769 "pl_title = TRIM(LEADING {$this->db->addQuotes( "$name:" )} FROM pl_title)",
770 ],
771 [
772 'pl_namespace' => 0,
773 'pl_title' . $this->db->buildLike( "$name:", $this->db->anyString() ),
774 ],
775 __METHOD__
776 );
777 $this->output( "done.\n" );
778 }
779 }
780
781 protected function doUserUniqueUpdate() {
782 if ( !$this->doTable( 'user' ) ) {
783 return true;
784 }
785
786 $duper = new UserDupes( $this->db, [ $this, 'output' ] );
787 if ( $duper->hasUniqueIndex() ) {
788 $this->output( "...already have unique user_name index.\n" );
789
790 return;
791 }
792
793 if ( !$duper->clearDupes() ) {
794 $this->output( "WARNING: This next step will probably fail due to unfixed duplicates...\n" );
795 }
796 $this->applyPatch( 'patch-user_nameindex.sql', false, "Adding unique index on user_name" );
797 }
798
799 protected function doUserGroupsUpdate() {
800 if ( !$this->doTable( 'user_groups' ) ) {
801 return true;
802 }
803
804 if ( $this->db->tableExists( 'user_groups', __METHOD__ ) ) {
805 $info = $this->db->fieldInfo( 'user_groups', 'ug_group' );
806 if ( $info->type() == 'int' ) {
807 $oldug = $this->db->tableName( 'user_groups' );
808 $newug = $this->db->tableName( 'user_groups_bogus' );
809 $this->output( "user_groups table exists but is in bogus intermediate " .
810 "format. Renaming to $newug... " );
811 $this->db->query( "ALTER TABLE $oldug RENAME TO $newug", __METHOD__ );
812 $this->output( "done.\n" );
813
814 $this->applyPatch( 'patch-user_groups.sql', false, "Re-adding fresh user_groups table" );
815
816 $this->output( "***\n" );
817 $this->output( "*** WARNING: You will need to manually fix up user " .
818 "permissions in the user_groups\n" );
819 $this->output( "*** table. Old 1.5 alpha versions did some pretty funky stuff...\n" );
820 $this->output( "***\n" );
821 } else {
822 $this->output( "...user_groups table exists and is in current format.\n" );
823 }
824
825 return;
826 }
827
828 $this->applyPatch( 'patch-user_groups.sql', false, "Adding user_groups table" );
829
830 if ( !$this->db->tableExists( 'user_rights', __METHOD__ ) ) {
831 if ( $this->db->fieldExists( 'user', 'user_rights', __METHOD__ ) ) {
832 $this->applyPatch(
833 'patch-user_rights.sql',
834 false,
835 'Upgrading from a 1.3 or older database? Breaking out user_rights for conversion'
836 );
837 } else {
838 $this->output( "*** WARNING: couldn't locate user_rights table or field for upgrade.\n" );
839 $this->output( "*** You may need to manually configure some sysops by manipulating\n" );
840 $this->output( "*** the user_groups table.\n" );
841
842 return;
843 }
844 }
845
846 $this->output( "Converting user_rights table to user_groups... " );
847 $result = $this->db->select( 'user_rights',
848 [ 'ur_user', 'ur_rights' ],
849 [ "ur_rights != ''" ],
850 __METHOD__ );
851
852 foreach ( $result as $row ) {
853 $groups = array_unique(
854 array_map( 'trim',
855 explode( ',', $row->ur_rights ) ) );
856
857 foreach ( $groups as $group ) {
858 $this->db->insert( 'user_groups',
859 [
860 'ug_user' => $row->ur_user,
861 'ug_group' => $group ],
862 __METHOD__ );
863 }
864 }
865 $this->output( "done.\n" );
866 }
867
872 protected function doWatchlistNull() {
873 $info = $this->db->fieldInfo( 'watchlist', 'wl_notificationtimestamp' );
874 if ( !$info ) {
875 return;
876 }
877 if ( $info->isNullable() ) {
878 $this->output( "...wl_notificationtimestamp is already nullable.\n" );
879
880 return;
881 }
882
883 $this->applyPatch(
884 'patch-watchlist-null.sql',
885 false,
886 'Making wl_notificationtimestamp nullable'
887 );
888 }
889
895 protected function doPageRandomUpdate() {
896 $page = $this->db->tableName( 'page' );
897 $this->db->query( "UPDATE $page SET page_random = RAND() WHERE page_random = 0", __METHOD__ );
898 $rows = $this->db->affectedRows();
899
900 if ( $rows ) {
901 $this->output( "Set page_random to a random value on $rows rows where it was set to 0\n" );
902 } else {
903 $this->output( "...no page_random rows needed to be set\n" );
904 }
905 }
906
907 protected function doTemplatelinksUpdate() {
908 if ( $this->db->tableExists( 'templatelinks', __METHOD__ ) ) {
909 $this->output( "...templatelinks table already exists\n" );
910
911 return;
912 }
913
914 $this->applyPatch( 'patch-templatelinks.sql', false, "Creating templatelinks table" );
915
916 $this->output( "Populating...\n" );
917 $services = MediaWikiServices::getInstance();
918 if ( $services->getDBLoadBalancer()->getServerCount() > 1 ) {
919 // Slow, replication-friendly update
920 $res = $this->db->select( 'pagelinks', [ 'pl_from', 'pl_namespace', 'pl_title' ],
921 [ 'pl_namespace' => NS_TEMPLATE ], __METHOD__ );
922 $count = 0;
923 foreach ( $res as $row ) {
924 $count = ( $count + 1 ) % 100;
925 if ( $count == 0 ) {
926 $lbFactory = $services->getDBLoadBalancerFactory();
927 $lbFactory->waitForReplication( [ 'wiki' => wfWikiID() ] );
928 }
929 $this->db->insert( 'templatelinks',
930 [
931 'tl_from' => $row->pl_from,
932 'tl_namespace' => $row->pl_namespace,
933 'tl_title' => $row->pl_title,
934 ], __METHOD__
935 );
936 }
937 } else {
938 // Fast update
939 $this->db->insertSelect( 'templatelinks', 'pagelinks',
940 [
941 'tl_from' => 'pl_from',
942 'tl_namespace' => 'pl_namespace',
943 'tl_title' => 'pl_title'
944 ], [
945 'pl_namespace' => 10
946 ], __METHOD__,
947 [ 'NO_AUTO_COLUMNS' ] // There's no "tl_id" auto-increment field
948 );
949 }
950 $this->output( "Done. Please run maintenance/refreshLinks.php for a more " .
951 "thorough templatelinks update.\n" );
952 }
953
954 protected function doBacklinkingIndicesUpdate() {
955 if ( !$this->indexHasField( 'pagelinks', 'pl_namespace', 'pl_from' ) ||
956 !$this->indexHasField( 'templatelinks', 'tl_namespace', 'tl_from' ) ||
957 !$this->indexHasField( 'imagelinks', 'il_to', 'il_from' )
958 ) {
959 $this->applyPatch( 'patch-backlinkindexes.sql', false, "Updating backlinking indices" );
960 }
961 }
962
968 protected function doRestrictionsUpdate() {
969 if ( $this->db->tableExists( 'page_restrictions', __METHOD__ ) ) {
970 $this->output( "...page_restrictions table already exists.\n" );
971
972 return;
973 }
974
975 $this->applyPatch(
976 'patch-page_restrictions.sql',
977 false,
978 'Creating page_restrictions table (1/2)'
979 );
980 $this->applyPatch(
981 'patch-page_restrictions_sortkey.sql',
982 false,
983 'Creating page_restrictions table (2/2)'
984 );
985 $this->output( "done.\n" );
986
987 $this->output( "Migrating old restrictions to new table...\n" );
988 $task = $this->maintenance->runChild( UpdateRestrictions::class );
989 $task->execute();
990 }
991
992 protected function doCategorylinksIndicesUpdate() {
993 if ( !$this->indexHasField( 'categorylinks', 'cl_sortkey', 'cl_from' ) ) {
994 $this->applyPatch( 'patch-categorylinksindex.sql', false, "Updating categorylinks Indices" );
995 }
996 }
997
998 protected function doCategoryPopulation() {
999 if ( $this->updateRowExists( 'populate category' ) ) {
1000 $this->output( "...category table already populated.\n" );
1001
1002 return;
1003 }
1004
1005 $this->output(
1006 "Populating category table, printing progress markers. " .
1007 "For large databases, you\n" .
1008 "may want to hit Ctrl-C and do this manually with maintenance/\n" .
1009 "populateCategory.php.\n"
1010 );
1011 $task = $this->maintenance->runChild( PopulateCategory::class );
1012 $task->execute();
1013 $this->output( "Done populating category table.\n" );
1014 }
1015
1016 protected function doPopulateParentId() {
1017 if ( !$this->updateRowExists( 'populate rev_parent_id' ) ) {
1018 $this->output(
1019 "Populating rev_parent_id fields, printing progress markers. For large\n" .
1020 "databases, you may want to hit Ctrl-C and do this manually with\n" .
1021 "maintenance/populateParentId.php.\n" );
1022
1023 $task = $this->maintenance->runChild( PopulateParentId::class );
1024 $task->execute();
1025 }
1026 }
1027
1028 protected function doMaybeProfilingMemoryUpdate() {
1029 if ( !$this->doTable( 'profiling' ) ) {
1030 return true;
1031 }
1032
1033 if ( !$this->db->tableExists( 'profiling', __METHOD__ ) ) {
1034 return true;
1035 } elseif ( $this->db->fieldExists( 'profiling', 'pf_memory', __METHOD__ ) ) {
1036 $this->output( "...profiling table has pf_memory field.\n" );
1037
1038 return true;
1039 }
1040
1041 return $this->applyPatch(
1042 'patch-profiling-memory.sql',
1043 false,
1044 'Adding pf_memory field to table profiling'
1045 );
1046 }
1047
1048 protected function doFilearchiveIndicesUpdate() {
1049 $info = $this->db->indexInfo( 'filearchive', 'fa_user_timestamp', __METHOD__ );
1050 if ( !$info ) {
1051 $this->applyPatch( 'patch-filearchive-user-index.sql', false, "Updating filearchive indices" );
1052 }
1053
1054 return true;
1055 }
1056
1057 protected function doNonUniquePlTlIl() {
1058 $info = $this->db->indexInfo( 'pagelinks', 'pl_namespace' );
1059 if ( is_array( $info ) && $info[0]->Non_unique ) {
1060 $this->output( "...pl_namespace, tl_namespace, il_to indices are already non-UNIQUE.\n" );
1061
1062 return true;
1063 }
1064 if ( $this->skipSchema ) {
1065 $this->output( "...skipping schema change (making pl_namespace, tl_namespace " .
1066 "and il_to indices non-UNIQUE).\n" );
1067
1068 return false;
1069 }
1070
1071 return $this->applyPatch(
1072 'patch-pl-tl-il-nonunique.sql',
1073 false,
1074 'Making pl_namespace, tl_namespace and il_to indices non-UNIQUE'
1075 );
1076 }
1077
1078 protected function doUpdateMimeMinorField() {
1079 if ( $this->updateRowExists( 'mime_minor_length' ) ) {
1080 $this->output( "...*_mime_minor fields are already long enough.\n" );
1081
1082 return;
1083 }
1084
1085 $this->applyPatch(
1086 'patch-mime_minor_length.sql',
1087 false,
1088 'Altering all *_mime_minor fields to 100 bytes in size'
1089 );
1090 }
1091
1092 protected function doClFieldsUpdate() {
1093 if ( $this->updateRowExists( 'cl_fields_update' ) ) {
1094 $this->output( "...categorylinks up-to-date.\n" );
1095
1096 return;
1097 }
1098
1099 $this->applyPatch(
1100 'patch-categorylinks-better-collation2.sql',
1101 false,
1102 'Updating categorylinks (again)'
1103 );
1104 }
1105
1106 protected function doLangLinksLengthUpdate() {
1107 $langlinks = $this->db->tableName( 'langlinks' );
1108 $res = $this->db->query( "SHOW COLUMNS FROM $langlinks LIKE 'll_lang'" );
1109 $row = $this->db->fetchObject( $res );
1110
1111 if ( $row && $row->Type == "varbinary(10)" ) {
1112 $this->applyPatch(
1113 'patch-langlinks-ll_lang-20.sql',
1114 false,
1115 'Updating length of ll_lang in langlinks'
1116 );
1117 } else {
1118 $this->output( "...ll_lang is up-to-date.\n" );
1119 }
1120 }
1121
1122 protected function doUserNewTalkTimestampNotNull() {
1123 if ( !$this->doTable( 'user_newtalk' ) ) {
1124 return true;
1125 }
1126
1127 $info = $this->db->fieldInfo( 'user_newtalk', 'user_last_timestamp' );
1128 if ( $info === false ) {
1129 return;
1130 }
1131 if ( $info->isNullable() ) {
1132 $this->output( "...user_last_timestamp is already nullable.\n" );
1133
1134 return;
1135 }
1136
1137 $this->applyPatch(
1138 'patch-user-newtalk-timestamp-null.sql',
1139 false,
1140 'Making user_last_timestamp nullable'
1141 );
1142 }
1143
1144 protected function doIwlinksIndexNonUnique() {
1145 $info = $this->db->indexInfo( 'iwlinks', 'iwl_prefix_title_from' );
1146 if ( is_array( $info ) && $info[0]->Non_unique ) {
1147 $this->output( "...iwl_prefix_title_from index is already non-UNIQUE.\n" );
1148
1149 return true;
1150 }
1151 if ( $this->skipSchema ) {
1152 $this->output( "...skipping schema change (making iwl_prefix_title_from index non-UNIQUE).\n" );
1153
1154 return false;
1155 }
1156
1157 return $this->applyPatch(
1158 'patch-iwl_prefix_title_from-non-unique.sql',
1159 false,
1160 'Making iwl_prefix_title_from index non-UNIQUE'
1161 );
1162 }
1163
1164 protected function doUnsignedSyncronisation() {
1165 $sync = [
1166 [ 'table' => 'bot_passwords', 'field' => 'bp_user' ],
1167 [ 'table' => 'change_tag', 'field' => 'ct_log_id' ],
1168 [ 'table' => 'change_tag', 'field' => 'ct_rev_id' ],
1169 [ 'table' => 'page_restrictions', 'field' => 'pr_user' ],
1170 [ 'table' => 'tag_summary', 'field' => 'ts_log_id' ],
1171 [ 'table' => 'tag_summary', 'field' => 'ts_rev_id' ],
1172 [ 'table' => 'user_newtalk', 'field' => 'user_id' ],
1173 [ 'table' => 'user_properties', 'field' => 'up_user' ],
1174 ];
1175
1176 foreach ( $sync as $s ) {
1177 if ( !$this->doTable( $s['table'] ) ) {
1178 continue;
1179 }
1180
1181 $info = $this->db->fieldInfo( $s['table'], $s['field'] );
1182 if ( $info === false ) {
1183 continue;
1184 }
1185 $fullName = "{$s['table']}.{$s['field']}";
1186 if ( $info->isUnsigned() ) {
1187 $this->output( "...$fullName is already unsigned int.\n" );
1188
1189 continue;
1190 }
1191
1192 $this->applyPatch(
1193 "patch-{$s['table']}-{$s['field']}-unsigned.sql",
1194 false,
1195 "Making $fullName into an unsigned int"
1196 );
1197 }
1198
1199 return true;
1200 }
1201
1202 protected function doRevisionPageRevIndexNonUnique() {
1203 if ( !$this->doTable( 'revision' ) ) {
1204 return true;
1205 } elseif ( !$this->db->indexExists( 'revision', 'rev_page_id' ) ) {
1206 $this->output( "...rev_page_id index not found on revision.\n" );
1207 return true;
1208 }
1209
1210 if ( !$this->db->indexUnique( 'revision', 'rev_page_id' ) ) {
1211 $this->output( "...rev_page_id index already non-unique.\n" );
1212 return true;
1213 }
1214
1215 return $this->applyPatch(
1216 'patch-revision-page-rev-index-nonunique.sql',
1217 false,
1218 'Making rev_page_id index non-unique'
1219 );
1220 }
1221
1222 protected function doExtendCommentLengths() {
1223 $table = $this->db->tableName( 'revision' );
1224 $res = $this->db->query( "SHOW COLUMNS FROM $table LIKE 'rev_comment'" );
1225 $row = $this->db->fetchObject( $res );
1226
1227 if ( $row && ( $row->Type !== "varbinary(767)" || $row->Default !== "" ) ) {
1228 $this->applyPatch(
1229 'patch-editsummary-length.sql',
1230 false,
1231 'Extending edit summary lengths (and setting defaults)'
1232 );
1233 } else {
1234 $this->output( '...comment fields are up to date' );
1235 }
1236 }
1237
1238 public function getSchemaVars() {
1239 global $wgDBTableOptions;
1240
1241 $vars = [];
1242 $vars['wgDBTableOptions'] = str_replace( 'TYPE', 'ENGINE', $wgDBTableOptions );
1243 $vars['wgDBTableOptions'] = str_replace(
1244 'CHARSET=mysql4',
1245 'CHARSET=binary',
1246 $vars['wgDBTableOptions']
1247 );
1248
1249 return $vars;
1250 }
1251}
$wgLegacySchemaConversion
If set to true, the MediaWiki 1.4 to 1.5 schema conversion will create stub reference rows in the tex...
$wgDBTableOptions
MySQL table options to use during installation or update.
wfTimestamp( $outputtype=TS_UNIX, $ts=0)
Get a timestamp string in one of various formats.
wfWikiID()
Get an ASCII string identifying this wiki This is used as a prefix in memcached keys.
Class for handling database updates.
updateRowExists( $key)
Helper function: check if the given key is present in the updatelog table.
applyPatch( $path, $isFullPath=false, $msg=null)
Applies a SQL patch.
doTable( $name)
Returns whether updates should be executed on the database table $name.
MediaWiki exception.
MediaWikiServices is the service locator for the application scope of MediaWiki.
Mysql update list and mysql-specific update functions.
doWatchlistNull()
Make sure wl_notificationtimestamp can be NULL, and update old broken items.
doInterwikiUpdate()
Check that interwiki table exists; if it doesn't source it.
getSchemaVars()
Get appropriate schema variables in the current database connection.
doRestrictionsUpdate()
Adding page_restrictions table, obsoleting page.page_restrictions.
doCategorylinksIndicesUpdate()
checkBin( $table, $field, $patchFile)
1.4 betas were missing the 'binary' marker from logging.log_title, which causes a collation mismatch ...
doIndexUpdate()
Check that proper indexes are in place.
getCoreUpdateList()
Get an array of updates to perform on the database.
doRevisionPageRevIndexNonUnique()
indexHasField( $table, $index, $field)
Check whether an index contain a field.
doPageRandomUpdate()
Set page_random field to a random value where it is equals to 0.
doWatchlistUpdate()
Check if we need to add talk page rows to the watchlist.
doUserNewTalkTimestampNotNull()
Look for duplicate user table entries and optionally prune them.
Definition userDupes.inc:35
$res
Definition database.txt:21
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
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 local content language as $wgContLang
Definition design.txt:57
design txt This is a brief overview of the new design More thorough and up to date information is available on the documentation wiki at etc Handles the details of getting and saving to the user table of the and dealing with sessions and cookies OutputPage Encapsulates the entire HTML page that will be sent in response to any server request It is used by calling its functions to add in any and then calling output() to send it all. It could be easily changed to send incrementally if that becomes useful
static configuration should be added through ResourceLoaderGetConfigVars instead & $vars
Definition hooks.txt:2228
do that in ParserLimitReportFormat instead use this to modify the parameters of the image all existing parser cache entries will be invalid To avoid you ll need to handle that somehow(e.g. with the RejectParserCacheValue hook) because MediaWiki won 't do it for you. & $defaults also a ContextSource after deleting those rows but within the same transaction $rows
Definition hooks.txt:2783
this hook is for auditing only RecentChangesLinked and Watchlist RecentChangesLinked and Watchlist Do not use this to implement individual filters if they are compatible with the ChangesListFilter and ChangesListFilterGroup structure use sub classes of those in conjunction with the ChangesListSpecialPageStructuredFilters hook This hook can be used to implement filters that do not implement that or custom behavior that is not an individual filter e g Watchlist & $tables
Definition hooks.txt:1015
static configuration should be added through ResourceLoaderGetConfigVars instead can be used to get the real title after the basic globals have been set but before ordinary actions take place or wrap services the preferred way to define a new service is the $wgServiceWiringFiles array $services
Definition hooks.txt:2273
$IP
Definition update.php:3
const NS_TEMPLATE
Definition Defines.php:84
Basic database interface for live and lazy-loaded relation database handles.
Definition IDatabase.php:38
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