Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | n/a |
0 / 0 |
n/a |
0 / 0 |
CRAP | n/a |
0 / 0 |
|||
SchemaChangesHandler | n/a |
0 / 0 |
n/a |
0 / 0 |
12 | n/a |
0 / 0 |
|||
onLoadExtensionSchemaUpdates | n/a |
0 / 0 |
n/a |
0 / 0 |
12 |
1 | <?php |
2 | |
3 | namespace MediaWiki\CheckUser\HookHandler; |
4 | |
5 | use MediaWiki\CheckUser\Maintenance\FixTrailingSpacesInLogs; |
6 | use MediaWiki\CheckUser\Maintenance\MoveLogEntriesFromCuChanges; |
7 | use MediaWiki\CheckUser\Maintenance\PopulateCheckUserTable; |
8 | use MediaWiki\CheckUser\Maintenance\PopulateCucActor; |
9 | use MediaWiki\CheckUser\Maintenance\PopulateCucComment; |
10 | use MediaWiki\CheckUser\Maintenance\PopulateCulActor; |
11 | use MediaWiki\CheckUser\Maintenance\PopulateCulComment; |
12 | use MediaWiki\Installer\Hook\LoadExtensionSchemaUpdatesHook; |
13 | |
14 | class SchemaChangesHandler implements LoadExtensionSchemaUpdatesHook { |
15 | /** |
16 | * @codeCoverageIgnore This is tested by installing or updating MediaWiki |
17 | * @inheritDoc |
18 | */ |
19 | public function onLoadExtensionSchemaUpdates( $updater ) { |
20 | $base = __DIR__ . '/../../schema'; |
21 | $maintenanceDb = $updater->getDB(); |
22 | $dbType = $maintenanceDb->getType(); |
23 | $isCUInstalled = $updater->tableExists( 'cu_changes' ); |
24 | |
25 | $updater->addExtensionTable( 'cu_changes', "$base/$dbType/tables-generated.sql" ); |
26 | |
27 | if ( $dbType === 'mysql' ) { |
28 | // 1.35 |
29 | $updater->modifyExtensionField( |
30 | 'cu_changes', |
31 | 'cuc_id', |
32 | "$base/$dbType/patch-cu_changes-cuc_id-unsigned.sql" |
33 | ); |
34 | |
35 | // 1.38 |
36 | $updater->addExtensionIndex( |
37 | 'cu_changes', |
38 | 'cuc_actor_ip_time', |
39 | "$base/$dbType/patch-cu_changes-actor-comment.sql" |
40 | ); |
41 | |
42 | // 1.39 |
43 | $updater->modifyExtensionField( |
44 | 'cu_changes', |
45 | 'cuc_timestamp', |
46 | "$base/$dbType/patch-cu_changes-cuc_timestamp.sql" |
47 | ); |
48 | $updater->addExtensionField( |
49 | 'cu_log', |
50 | 'cul_reason_id', |
51 | "$base/$dbType/patch-cu_log-comment_table_for_reason.sql" |
52 | ); |
53 | $updater->addExtensionField( |
54 | 'cu_log', |
55 | 'cul_actor', |
56 | "$base/$dbType/patch-cu_log-actor.sql" |
57 | ); |
58 | } elseif ( $dbType === 'sqlite' ) { |
59 | // 1.39 |
60 | $updater->addExtensionIndex( |
61 | 'cu_changes', |
62 | 'cuc_actor_ip_time', |
63 | "$base/$dbType/patch-cu_changes-actor-comment.sql" |
64 | ); |
65 | $updater->addExtensionField( |
66 | 'cu_log', |
67 | 'cul_reason_id', |
68 | "$base/$dbType/patch-cu_log-comment_table_for_reason.sql" |
69 | ); |
70 | $updater->addExtensionField( |
71 | 'cu_log', |
72 | 'cul_actor', |
73 | "$base/$dbType/patch-cu_log-actor.sql" |
74 | ); |
75 | } elseif ( $dbType === 'postgres' ) { |
76 | // 1.37 |
77 | $updater->addExtensionUpdate( [ 'dropFkey', 'cu_log', 'cul_user' ] ); |
78 | $updater->addExtensionUpdate( [ 'dropFkey', 'cu_log', 'cul_target_id' ] ); |
79 | $updater->addExtensionUpdate( [ 'dropFkey', 'cu_changes', 'cuc_user' ] ); |
80 | $updater->addExtensionUpdate( [ 'dropFkey', 'cu_changes', 'cuc_page_id' ] ); |
81 | |
82 | // 1.38 |
83 | $updater->addExtensionUpdate( |
84 | [ 'addPgField', 'cu_changes', 'cuc_actor', 'INTEGER NOT NULL DEFAULT 0' ] |
85 | ); |
86 | $updater->addExtensionUpdate( |
87 | [ 'addPgField', 'cu_changes', 'cuc_comment_id', 'INTEGER NOT NULL DEFAULT 0' ] |
88 | ); |
89 | $updater->addExtensionUpdate( |
90 | [ 'setDefault', 'cu_changes', 'cuc_user_text', '' ] |
91 | ); |
92 | $updater->addExtensionUpdate( |
93 | [ 'addPgIndex', 'cu_changes', 'cuc_actor_ip_time', '( cuc_actor, cuc_ip, cuc_timestamp )' ] |
94 | ); |
95 | |
96 | // 1.39 |
97 | $updater->addExtensionIndex( 'cu_changes', 'cu_changes_pkey', "$base/$dbType/patch-cu_changes-pk.sql" ); |
98 | $updater->addExtensionUpdate( |
99 | [ 'changeField', 'cu_changes', 'cuc_namespace', 'INT', 'cuc_namespace::INT DEFAULT 0' ] |
100 | ); |
101 | if ( $maintenanceDb->fieldExists( 'cu_log', 'cuc_user' ) ) { |
102 | $updater->addExtensionUpdate( |
103 | [ 'changeNullableField', 'cu_changes', 'cuc_user', 'NOT NULL', true ] |
104 | ); |
105 | } |
106 | if ( $maintenanceDb->fieldExists( 'cu_log', 'cuc_user_text' ) ) { |
107 | $updater->addExtensionUpdate( |
108 | [ 'changeField', 'cu_changes', 'cuc_user_text', 'VARCHAR(255)', '' ] |
109 | ); |
110 | $updater->addExtensionUpdate( |
111 | [ 'setDefault', 'cu_changes', 'cuc_user_text', '' ] |
112 | ); |
113 | } |
114 | $updater->addExtensionUpdate( |
115 | [ 'changeField', 'cu_changes', 'cuc_actor', 'BIGINT', 'cuc_actor::BIGINT DEFAULT 0' ] |
116 | ); |
117 | $updater->addExtensionUpdate( |
118 | [ 'changeField', 'cu_changes', 'cuc_comment_id', 'BIGINT', 'cuc_comment_id::BIGINT DEFAULT 0' ] |
119 | ); |
120 | $updater->addExtensionUpdate( |
121 | [ 'changeField', 'cu_changes', 'cuc_minor', 'SMALLINT', 'cuc_minor::SMALLINT DEFAULT 0' ] |
122 | ); |
123 | $updater->addExtensionUpdate( |
124 | [ 'changeNullableField', 'cu_changes', 'cuc_page_id', 'NOT NULL', true ] |
125 | ); |
126 | $updater->addExtensionUpdate( |
127 | [ 'setDefault', 'cu_changes', 'cuc_page_id', 0 ] |
128 | ); |
129 | $updater->addExtensionUpdate( |
130 | [ 'changeNullableField', 'cu_changes', 'cuc_timestamp', 'NOT NULL', true ] |
131 | ); |
132 | $updater->addExtensionUpdate( |
133 | [ 'changeField', 'cu_changes', 'cuc_ip', 'VARCHAR(255)', '' ] |
134 | ); |
135 | $updater->addExtensionUpdate( |
136 | [ 'setDefault', 'cu_changes', 'cuc_ip', '' ] |
137 | ); |
138 | $updater->addExtensionUpdate( |
139 | [ 'changeField', 'cu_changes', 'cuc_ip_hex', 'VARCHAR(255)', '' ] |
140 | ); |
141 | $updater->addExtensionUpdate( |
142 | [ 'setDefault', 'cu_changes', 'cuc_xff', '' ] |
143 | ); |
144 | $updater->addExtensionUpdate( |
145 | [ 'changeField', 'cu_changes', 'cuc_xff_hex', 'VARCHAR(255)', '' ] |
146 | ); |
147 | $updater->addExtensionUpdate( |
148 | [ 'changeField', 'cu_changes', 'cuc_private', 'TEXT', '' ] |
149 | ); |
150 | $updater->addExtensionIndex( 'cu_log', 'cu_log_pkey', "$base/$dbType/patch-cu_log-pk.sql" ); |
151 | $updater->addExtensionUpdate( |
152 | [ 'changeNullableField', 'cu_log', 'cul_timestamp', 'NOT NULL', true ] |
153 | ); |
154 | if ( $maintenanceDb->fieldExists( 'cu_log', 'cul_user' ) ) { |
155 | $updater->addExtensionUpdate( |
156 | [ 'changeNullableField', 'cu_log', 'cul_user', 'NOT NULL', true ] |
157 | ); |
158 | } |
159 | $updater->addExtensionUpdate( |
160 | [ 'dropDefault', 'cu_log', 'cul_type' ] |
161 | ); |
162 | $updater->addExtensionUpdate( |
163 | [ 'changeNullableField', 'cu_log', 'cul_target_id', 'NOT NULL', true ] |
164 | ); |
165 | $updater->addExtensionUpdate( |
166 | [ 'setDefault', 'cu_log', 'cul_target_id', 0 ] |
167 | ); |
168 | $updater->addExtensionUpdate( |
169 | [ 'dropDefault', 'cu_log', 'cul_target_text' ] |
170 | ); |
171 | $updater->addExtensionUpdate( |
172 | [ 'addPgField', 'cu_log', 'cul_reason_id', 'INTEGER NOT NULL DEFAULT 0' ] |
173 | ); |
174 | $updater->addExtensionUpdate( |
175 | [ 'addPgField', 'cu_log', 'cul_reason_plaintext_id', 'INTEGER NOT NULL DEFAULT 0' ] |
176 | ); |
177 | $updater->addExtensionUpdate( |
178 | [ 'addPgField', 'cu_log', 'cul_actor', 'INTEGER NOT NULL DEFAULT 0' ] |
179 | ); |
180 | $updater->addExtensionUpdate( |
181 | [ 'addPgIndex', 'cu_log', 'cul_actor_time', '( cul_actor, cul_timestamp )' ] |
182 | ); |
183 | } |
184 | |
185 | $updater->addExtensionUpdate( [ |
186 | 'runMaintenance', |
187 | PopulateCulActor::class, |
188 | 'extensions/CheckUser/maintenance/populateCulActor.php' |
189 | ] ); |
190 | $updater->addExtensionUpdate( [ |
191 | 'runMaintenance', |
192 | PopulateCulComment::class, |
193 | 'extensions/CheckUser/maintenance/populateCulComment.php' |
194 | ] ); |
195 | if ( $dbType === 'postgres' ) { |
196 | # For wikis which ran update.php after pulling the master branch of CheckUser between |
197 | # 4 June 2022 and 6 June 2022, the cul_reason_id and cul_reason_plaintext_id columns |
198 | # were added but were by default NULL. |
199 | # This is needed for postgres installations that did the above. All other DB types |
200 | # make the columns "NOT NULL" when removing the default. |
201 | $updater->addExtensionUpdate( |
202 | [ 'changeNullableField', 'cu_log', 'cul_reason_id', 'NOT NULL', true ] |
203 | ); |
204 | $updater->addExtensionUpdate( |
205 | [ 'changeNullableField', 'cu_log', 'cul_reason_plaintext_id', 'NOT NULL', true ] |
206 | ); |
207 | } |
208 | |
209 | $updater->addExtensionUpdate( [ |
210 | 'runMaintenance', |
211 | PopulateCucActor::class, |
212 | 'extensions/CheckUser/maintenance/populateCucActor.php' |
213 | ] ); |
214 | $updater->addExtensionUpdate( [ |
215 | 'runMaintenance', |
216 | PopulateCucComment::class, |
217 | 'extensions/CheckUser/maintenance/populateCucComment.php' |
218 | ] ); |
219 | |
220 | // 1.40 |
221 | $updater->addExtensionTable( |
222 | 'cu_log_event', |
223 | "$base/$dbType/patch-cu_log_event-def.sql" |
224 | ); |
225 | $updater->addExtensionTable( |
226 | 'cu_private_event', |
227 | "$base/$dbType/patch-cu_private_event-def.sql" |
228 | ); |
229 | $updater->dropExtensionField( |
230 | 'cu_log', |
231 | 'cul_user', |
232 | "$base/$dbType/patch-cu_log-drop-cul_user.sql" |
233 | ); |
234 | if ( |
235 | $dbType !== 'sqlite' || |
236 | $maintenanceDb->fieldExists( 'cu_log', 'cul_reason' ) |
237 | ) { |
238 | // Only run this for SQLite if cul_reason exists, |
239 | // as modifyExtensionField does not take into account |
240 | // SQLite patches that use temporary tables. If the cul_reason |
241 | // field does not exist this SQL would fail, however, cul_reason |
242 | // not existing also means this change has been previously applied. |
243 | $updater->modifyExtensionField( |
244 | 'cu_log', |
245 | 'cul_actor', |
246 | "$base/$dbType/patch-cu_log-drop-actor_default.sql" |
247 | ); |
248 | } |
249 | $updater->dropExtensionField( |
250 | 'cu_log', |
251 | 'cul_reason', |
252 | "$base/$dbType/patch-cu_log-drop-cul_reason.sql" |
253 | ); |
254 | $updater->modifyExtensionField( |
255 | 'cu_log', |
256 | 'cul_reason_id', |
257 | "$base/$dbType/patch-cu_log-drop-cul_reason_id_default.sql" |
258 | ); |
259 | $updater->dropExtensionField( |
260 | 'cu_changes', |
261 | 'cuc_user', |
262 | "$base/$dbType/patch-cu_changes-drop-cuc_user.sql" |
263 | ); |
264 | $updater->addExtensionField( |
265 | 'cu_changes', |
266 | 'cuc_only_for_read_old', |
267 | "$base/$dbType/patch-cu_changes-add-cuc_only_for_read_old.sql" |
268 | ); |
269 | $updater->dropExtensionField( |
270 | 'cu_changes', |
271 | 'cuc_comment', |
272 | "$base/$dbType/patch-cu_changes-drop-cuc_comment.sql" |
273 | ); |
274 | $updater->modifyExtensionField( |
275 | 'cu_changes', |
276 | 'cuc_actor', |
277 | "$base/$dbType/patch-cu_changes-drop-defaults.sql" |
278 | ); |
279 | |
280 | // 1.41 |
281 | $updater->addExtensionTable( 'cu_useragent_clienthints', "$base/$dbType/cu_useragent_clienthints.sql" ); |
282 | $updater->addExtensionTable( 'cu_useragent_clienthints_map', "$base/$dbType/cu_useragent_clienthints_map.sql" ); |
283 | $updater->addPostDatabaseUpdateMaintenance( MoveLogEntriesFromCuChanges::class ); |
284 | |
285 | // 1.42 |
286 | $updater->addExtensionField( |
287 | 'cu_log', |
288 | 'cul_result_id', |
289 | "$base/$dbType/patch-cu_log-add-cul_result_id.sql" |
290 | ); |
291 | if ( $dbType !== 'sqlite' ) { |
292 | $updater->modifyExtensionField( |
293 | 'cu_changes', |
294 | 'cuc_id', |
295 | "$base/$dbType/patch-cu_changes-modify-cuc_id-bigint.sql" |
296 | ); |
297 | } |
298 | $updater->addPostDatabaseUpdateMaintenance( FixTrailingSpacesInLogs::class ); |
299 | // If any columns are modified or removed from cu_private_event in the future, then make sure to only apply this |
300 | // patch if the later schema change has not yet been applied. Otherwise wikis using SQLite will have a DB error. |
301 | $updater->modifyExtensionField( |
302 | 'cu_private_event', |
303 | 'cupe_actor', |
304 | "$base/$dbType/patch-cu_private_event-modify-cupe_actor-nullable.sql" |
305 | ); |
306 | $updater->addExtensionTable( 'cu_useragent', "$base/$dbType/cu_useragent.sql" ); |
307 | $updater->addExtensionField( |
308 | 'cu_changes', |
309 | 'cuc_agent_id', |
310 | "$base/$dbType/patch-cu_changes-add-cuc_agent_id.sql" |
311 | ); |
312 | $updater->addExtensionField( |
313 | 'cu_log_event', |
314 | 'cule_agent_id', |
315 | "$base/$dbType/patch-cu_log_event-add-cule_agent_id.sql" |
316 | ); |
317 | $updater->addExtensionField( |
318 | 'cu_private_event', |
319 | 'cupe_agent_id', |
320 | "$base/$dbType/patch-cu_private_event-add-cupe_agent_id.sql" |
321 | ); |
322 | |
323 | if ( !$isCUInstalled ) { |
324 | // First time so populate cu_changes with recentchanges data. |
325 | // Note: We cannot completely rely on updatelog here for old entries |
326 | // as populateCheckUserTable.php doesn't check for duplicates |
327 | $updater->addPostDatabaseUpdateMaintenance( PopulateCheckUserTable::class ); |
328 | } |
329 | } |
330 | } |