Page Menu
Home
WickedGov Phorge
Search
Configure Global Search
Log In
Files
F4148635
SchemaChangesHandler.php
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
13 KB
Referenced Files
None
Subscribers
None
SchemaChangesHandler.php
View Options
<?php
namespace
MediaWiki\CheckUser\HookHandler
;
use
MediaWiki\CheckUser\CheckUserQueryInterface
;
use
MediaWiki\CheckUser\Maintenance\DeleteReadOldRowsInCuChanges
;
use
MediaWiki\CheckUser\Maintenance\FixTrailingSpacesInLogs
;
use
MediaWiki\CheckUser\Maintenance\MoveLogEntriesFromCuChanges
;
use
MediaWiki\CheckUser\Maintenance\PopulateCentralCheckUserIndexTables
;
use
MediaWiki\CheckUser\Maintenance\PopulateCheckUserTable
;
use
MediaWiki\CheckUser\Maintenance\PopulateCucActor
;
use
MediaWiki\CheckUser\Maintenance\PopulateCucComment
;
use
MediaWiki\CheckUser\Maintenance\PopulateCulActor
;
use
MediaWiki\CheckUser\Maintenance\PopulateCulComment
;
use
MediaWiki\Installer\Hook\LoadExtensionSchemaUpdatesHook
;
class
SchemaChangesHandler
implements
LoadExtensionSchemaUpdatesHook
,
CheckUserQueryInterface
{
/**
* @codeCoverageIgnore This is tested by installing or updating MediaWiki
* @inheritDoc
*/
public
function
onLoadExtensionSchemaUpdates
(
$updater
)
{
$base
=
__DIR__
.
'/../../schema'
;
$maintenanceDb
=
$updater
->
getDB
();
$dbType
=
$maintenanceDb
->
getType
();
$isCUInstalled
=
$updater
->
tableExists
(
'cu_changes'
);
$updater
->
addExtensionTable
(
'cu_changes'
,
"$base/$dbType/tables-generated.sql"
);
// Added 1.43, but will need to remain here forever as it creates tables which are not in tables-generated.sql
$updater
->
addExtensionUpdateOnVirtualDomain
(
[
self
::
VIRTUAL_GLOBAL_DB_DOMAIN
,
'addTable'
,
'cuci_wiki_map'
,
"$base/$dbType/cuci_wiki_map.sql"
,
true
,
]
);
$updater
->
addExtensionUpdateOnVirtualDomain
(
[
self
::
VIRTUAL_GLOBAL_DB_DOMAIN
,
'addTable'
,
'cuci_temp_edit'
,
"$base/$dbType/cuci_temp_edit.sql"
,
true
,
]
);
$updater
->
addExtensionUpdateOnVirtualDomain
(
[
self
::
VIRTUAL_GLOBAL_DB_DOMAIN
,
'addTable'
,
'cuci_user'
,
"$base/$dbType/cuci_user.sql"
,
true
,
]
);
if
(
$dbType
===
'mysql'
)
{
// 1.35
$updater
->
modifyExtensionField
(
'cu_changes'
,
'cuc_id'
,
"$base/$dbType/patch-cu_changes-cuc_id-unsigned.sql"
);
// 1.38
$updater
->
addExtensionIndex
(
'cu_changes'
,
'cuc_actor_ip_time'
,
"$base/$dbType/patch-cu_changes-actor-comment.sql"
);
// 1.39
$updater
->
modifyExtensionField
(
'cu_changes'
,
'cuc_timestamp'
,
"$base/$dbType/patch-cu_changes-cuc_timestamp.sql"
);
$updater
->
addExtensionField
(
'cu_log'
,
'cul_reason_id'
,
"$base/$dbType/patch-cu_log-comment_table_for_reason.sql"
);
$updater
->
addExtensionField
(
'cu_log'
,
'cul_actor'
,
"$base/$dbType/patch-cu_log-actor.sql"
);
}
elseif
(
$dbType
===
'sqlite'
)
{
// 1.39
$updater
->
addExtensionIndex
(
'cu_changes'
,
'cuc_actor_ip_time'
,
"$base/$dbType/patch-cu_changes-actor-comment.sql"
);
$updater
->
addExtensionField
(
'cu_log'
,
'cul_reason_id'
,
"$base/$dbType/patch-cu_log-comment_table_for_reason.sql"
);
$updater
->
addExtensionField
(
'cu_log'
,
'cul_actor'
,
"$base/$dbType/patch-cu_log-actor.sql"
);
}
elseif
(
$dbType
===
'postgres'
)
{
// 1.37
$updater
->
addExtensionUpdate
(
[
'dropFkey'
,
'cu_log'
,
'cul_user'
]
);
$updater
->
addExtensionUpdate
(
[
'dropFkey'
,
'cu_log'
,
'cul_target_id'
]
);
$updater
->
addExtensionUpdate
(
[
'dropFkey'
,
'cu_changes'
,
'cuc_user'
]
);
$updater
->
addExtensionUpdate
(
[
'dropFkey'
,
'cu_changes'
,
'cuc_page_id'
]
);
// 1.38
$updater
->
addExtensionUpdate
(
[
'addPgField'
,
'cu_changes'
,
'cuc_actor'
,
'INTEGER NOT NULL DEFAULT 0'
]
);
$updater
->
addExtensionUpdate
(
[
'addPgField'
,
'cu_changes'
,
'cuc_comment_id'
,
'INTEGER NOT NULL DEFAULT 0'
]
);
$updater
->
addExtensionUpdate
(
[
'setDefault'
,
'cu_changes'
,
'cuc_user_text'
,
''
]
);
$updater
->
addExtensionUpdate
(
[
'addPgIndex'
,
'cu_changes'
,
'cuc_actor_ip_time'
,
'( cuc_actor, cuc_ip, cuc_timestamp )'
]
);
// 1.39
$updater
->
addExtensionIndex
(
'cu_changes'
,
'cu_changes_pkey'
,
"$base/$dbType/patch-cu_changes-pk.sql"
);
$updater
->
addExtensionUpdate
(
[
'changeField'
,
'cu_changes'
,
'cuc_namespace'
,
'INT'
,
'cuc_namespace::INT DEFAULT 0'
]
);
if
(
$maintenanceDb
->
fieldExists
(
'cu_log'
,
'cuc_user'
,
__METHOD__
)
)
{
$updater
->
addExtensionUpdate
(
[
'changeNullableField'
,
'cu_changes'
,
'cuc_user'
,
'NOT NULL'
,
true
]
);
}
if
(
$maintenanceDb
->
fieldExists
(
'cu_log'
,
'cuc_user_text'
,
__METHOD__
)
)
{
$updater
->
addExtensionUpdate
(
[
'changeField'
,
'cu_changes'
,
'cuc_user_text'
,
'VARCHAR(255)'
,
''
]
);
$updater
->
addExtensionUpdate
(
[
'setDefault'
,
'cu_changes'
,
'cuc_user_text'
,
''
]
);
}
$updater
->
addExtensionUpdate
(
[
'changeField'
,
'cu_changes'
,
'cuc_actor'
,
'BIGINT'
,
'cuc_actor::BIGINT DEFAULT 0'
]
);
$updater
->
addExtensionUpdate
(
[
'changeField'
,
'cu_changes'
,
'cuc_comment_id'
,
'BIGINT'
,
'cuc_comment_id::BIGINT DEFAULT 0'
]
);
$updater
->
addExtensionUpdate
(
[
'changeField'
,
'cu_changes'
,
'cuc_minor'
,
'SMALLINT'
,
'cuc_minor::SMALLINT DEFAULT 0'
]
);
$updater
->
addExtensionUpdate
(
[
'changeNullableField'
,
'cu_changes'
,
'cuc_page_id'
,
'NOT NULL'
,
true
]
);
$updater
->
addExtensionUpdate
(
[
'setDefault'
,
'cu_changes'
,
'cuc_page_id'
,
0
]
);
$updater
->
addExtensionUpdate
(
[
'changeNullableField'
,
'cu_changes'
,
'cuc_timestamp'
,
'NOT NULL'
,
true
]
);
$updater
->
addExtensionUpdate
(
[
'changeField'
,
'cu_changes'
,
'cuc_ip'
,
'VARCHAR(255)'
,
''
]
);
$updater
->
addExtensionUpdate
(
[
'setDefault'
,
'cu_changes'
,
'cuc_ip'
,
''
]
);
$updater
->
addExtensionUpdate
(
[
'changeField'
,
'cu_changes'
,
'cuc_ip_hex'
,
'VARCHAR(255)'
,
''
]
);
$updater
->
addExtensionUpdate
(
[
'setDefault'
,
'cu_changes'
,
'cuc_xff'
,
''
]
);
$updater
->
addExtensionUpdate
(
[
'changeField'
,
'cu_changes'
,
'cuc_xff_hex'
,
'VARCHAR(255)'
,
''
]
);
if
(
$maintenanceDb
->
fieldExists
(
'cu_changes'
,
'cuc_private'
,
__METHOD__
)
)
{
$updater
->
addExtensionUpdate
(
[
'changeField'
,
'cu_changes'
,
'cuc_private'
,
'TEXT'
,
''
]
);
}
$updater
->
addExtensionIndex
(
'cu_log'
,
'cu_log_pkey'
,
"$base/$dbType/patch-cu_log-pk.sql"
);
$updater
->
addExtensionUpdate
(
[
'changeNullableField'
,
'cu_log'
,
'cul_timestamp'
,
'NOT NULL'
,
true
]
);
if
(
$maintenanceDb
->
fieldExists
(
'cu_log'
,
'cul_user'
,
__METHOD__
)
)
{
$updater
->
addExtensionUpdate
(
[
'changeNullableField'
,
'cu_log'
,
'cul_user'
,
'NOT NULL'
,
true
]
);
}
$updater
->
addExtensionUpdate
(
[
'dropDefault'
,
'cu_log'
,
'cul_type'
]
);
$updater
->
addExtensionUpdate
(
[
'changeNullableField'
,
'cu_log'
,
'cul_target_id'
,
'NOT NULL'
,
true
]
);
$updater
->
addExtensionUpdate
(
[
'setDefault'
,
'cu_log'
,
'cul_target_id'
,
0
]
);
$updater
->
addExtensionUpdate
(
[
'dropDefault'
,
'cu_log'
,
'cul_target_text'
]
);
$updater
->
addExtensionUpdate
(
[
'addPgField'
,
'cu_log'
,
'cul_reason_id'
,
'INTEGER NOT NULL DEFAULT 0'
]
);
$updater
->
addExtensionUpdate
(
[
'addPgField'
,
'cu_log'
,
'cul_reason_plaintext_id'
,
'INTEGER NOT NULL DEFAULT 0'
]
);
$updater
->
addExtensionUpdate
(
[
'addPgField'
,
'cu_log'
,
'cul_actor'
,
'INTEGER NOT NULL DEFAULT 0'
]
);
$updater
->
addExtensionUpdate
(
[
'addPgIndex'
,
'cu_log'
,
'cul_actor_time'
,
'( cul_actor, cul_timestamp )'
]
);
}
$updater
->
addExtensionUpdate
(
[
'runMaintenance'
,
PopulateCulActor
::
class
,
]
);
$updater
->
addExtensionUpdate
(
[
'runMaintenance'
,
PopulateCulComment
::
class
,
]
);
if
(
$dbType
===
'postgres'
)
{
# For wikis which ran update.php after pulling the master branch of CheckUser between
# 4 June 2022 and 6 June 2022, the cul_reason_id and cul_reason_plaintext_id columns
# were added but were by default NULL.
# This is needed for postgres installations that did the above. All other DB types
# make the columns "NOT NULL" when removing the default.
$updater
->
addExtensionUpdate
(
[
'changeNullableField'
,
'cu_log'
,
'cul_reason_id'
,
'NOT NULL'
,
true
]
);
$updater
->
addExtensionUpdate
(
[
'changeNullableField'
,
'cu_log'
,
'cul_reason_plaintext_id'
,
'NOT NULL'
,
true
]
);
}
$updater
->
addExtensionUpdate
(
[
'runMaintenance'
,
PopulateCucActor
::
class
,
]
);
$updater
->
addExtensionUpdate
(
[
'runMaintenance'
,
PopulateCucComment
::
class
,
]
);
// 1.40
$updater
->
addExtensionTable
(
'cu_log_event'
,
"$base/$dbType/patch-cu_log_event-def.sql"
);
$updater
->
addExtensionTable
(
'cu_private_event'
,
"$base/$dbType/patch-cu_private_event-def.sql"
);
$updater
->
dropExtensionField
(
'cu_log'
,
'cul_user'
,
"$base/$dbType/patch-cu_log-drop-cul_user.sql"
);
if
(
$dbType
!==
'sqlite'
||
$maintenanceDb
->
fieldExists
(
'cu_log'
,
'cul_reason'
,
__METHOD__
)
)
{
// Only run this for SQLite if cul_reason exists,
// as modifyExtensionField does not take into account
// SQLite patches that use temporary tables. If the cul_reason
// field does not exist this SQL would fail, however, cul_reason
// not existing also means this change has been previously applied.
$updater
->
modifyExtensionField
(
'cu_log'
,
'cul_actor'
,
"$base/$dbType/patch-cu_log-drop-actor_default.sql"
);
}
$updater
->
dropExtensionField
(
'cu_log'
,
'cul_reason'
,
"$base/$dbType/patch-cu_log-drop-cul_reason.sql"
);
$updater
->
modifyExtensionField
(
'cu_log'
,
'cul_reason_id'
,
"$base/$dbType/patch-cu_log-drop-cul_reason_id_default.sql"
);
$updater
->
dropExtensionField
(
'cu_changes'
,
'cuc_user'
,
"$base/$dbType/patch-cu_changes-drop-cuc_user.sql"
);
// Skip adding the cuc_only_for_read_old column if:
// * This is an install of CheckUser MW 1.43 or later (and therefore no migration is necesary)
// * The column has been in the table before (checked by seeing if the cuc_agent_id column exists
// in the cu_changes, and if it does then this update has been run before therefore it should be
// skipped).
if
(
$isCUInstalled
&&
!
$maintenanceDb
->
fieldExists
(
'cu_changes'
,
'cuc_agent_id'
,
__METHOD__
)
)
{
$updater
->
addExtensionField
(
'cu_changes'
,
'cuc_only_for_read_old'
,
"$base/$dbType/patch-cu_changes-add-cuc_only_for_read_old.sql"
);
}
$updater
->
dropExtensionField
(
'cu_changes'
,
'cuc_comment'
,
"$base/$dbType/patch-cu_changes-drop-cuc_comment.sql"
);
// Only run this for SQLite if cuc_only_for_read_old exists, as modifyExtensionField does not take into
// account that SQLite patches that use temporary tables. If the cuc_only_for_read_old field does not exist
// this SQL would fail, however, cuc_only_for_read_old not existing also means this change has
// been previously applied.
if
(
$dbType
!==
'sqlite'
||
$maintenanceDb
->
fieldExists
(
'cu_changes'
,
'cuc_only_for_read_old'
,
__METHOD__
)
)
{
$updater
->
modifyExtensionField
(
'cu_changes'
,
'cuc_actor'
,
"$base/$dbType/patch-cu_changes-drop-defaults.sql"
);
}
// 1.41
$updater
->
addExtensionTable
(
'cu_useragent_clienthints'
,
"$base/$dbType/cu_useragent_clienthints.sql"
);
$updater
->
addExtensionTable
(
'cu_useragent_clienthints_map'
,
"$base/$dbType/cu_useragent_clienthints_map.sql"
);
// Must be run before deleteReadOldEntriesInCuChanges.php is run or the cuc_only_for_read_old column is
// removed, as the script needs the column to be present and needs to be allowed to set the value of the
// column to 1.
$updater
->
addExtensionUpdate
(
[
'runMaintenance'
,
MoveLogEntriesFromCuChanges
::
class
,
]
);
// 1.42
$updater
->
addExtensionField
(
'cu_log'
,
'cul_result_id'
,
"$base/$dbType/patch-cu_log-add-cul_result_id.sql"
);
if
(
$dbType
!==
'sqlite'
)
{
$updater
->
modifyExtensionField
(
'cu_changes'
,
'cuc_id'
,
"$base/$dbType/patch-cu_changes-modify-cuc_id-bigint.sql"
);
}
$updater
->
addPostDatabaseUpdateMaintenance
(
FixTrailingSpacesInLogs
::
class
);
// If any columns are modified or removed from cu_private_event in the future, then make sure to only apply this
// patch if the later schema change has not yet been applied. Otherwise wikis using SQLite will have a DB error.
$updater
->
modifyExtensionField
(
'cu_private_event'
,
'cupe_actor'
,
"$base/$dbType/patch-cu_private_event-modify-cupe_actor-nullable.sql"
);
$updater
->
addExtensionTable
(
'cu_useragent'
,
"$base/$dbType/cu_useragent.sql"
);
$updater
->
addExtensionField
(
'cu_changes'
,
'cuc_agent_id'
,
"$base/$dbType/patch-cu_changes-add-cuc_agent_id.sql"
);
$updater
->
addExtensionField
(
'cu_log_event'
,
'cule_agent_id'
,
"$base/$dbType/patch-cu_log_event-add-cule_agent_id.sql"
);
$updater
->
addExtensionField
(
'cu_private_event'
,
'cupe_agent_id'
,
"$base/$dbType/patch-cu_private_event-add-cupe_agent_id.sql"
);
// 1.43
// Must be run before the removal of the cuc_only_for_read_old column, as the script needs the column to be
// present to delete the rows where the column value is 1.
$updater
->
addExtensionUpdate
(
[
'runMaintenance'
,
DeleteReadOldRowsInCuChanges
::
class
,
]
);
$updater
->
dropExtensionField
(
'cu_changes'
,
'cuc_only_for_read_old'
,
"$base/$dbType/patch-cu_changes-drop-cuc_only_for_read_old.sql"
);
$updater
->
dropExtensionField
(
'cu_changes'
,
'cuc_actiontext'
,
"$base/$dbType/patch-cu_changes-drop-cuc_actiontext.sql"
);
$updater
->
dropExtensionField
(
'cu_changes'
,
'cuc_private'
,
"$base/$dbType/patch-cu_changes-drop-cuc_private.sql"
);
if
(
$isCUInstalled
)
{
// We only need to run this maintenance script if CU is already installed, because otherwise the script
// will be run for us by the populateCheckUserTable.php script (after it's populated the tables).
$updater
->
addPostDatabaseUpdateMaintenance
(
PopulateCentralCheckUserIndexTables
::
class
);
}
if
(
!
$isCUInstalled
)
{
// First time so populate the CheckUser result tables with recentchanges data.
// Note: We cannot completely rely on updatelog here for old entries
// as populateCheckUserTable.php doesn't check for duplicates
$updater
->
addPostDatabaseUpdateMaintenance
(
PopulateCheckUserTable
::
class
);
}
}
}
File Metadata
Details
Attached
Mime Type
text/x-php
Expires
Aug 19 2026, 18:52 (6 w, 2 d ago)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
33/96/30b2ce8a2b6fc9a914ad411c3615
Default Alt Text
SchemaChangesHandler.php (13 KB)
Attached To
Mode
rMWPROD MediaWiki Production
Attached
Detach File
Event Timeline
Log In to Comment