Page Menu
Home
WickedGov Phorge
Search
Configure Global Search
Log In
Files
F4136614
UpdateAutoBlockParentIdColumn.php
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
4 KB
Referenced Files
None
Subscribers
None
UpdateAutoBlockParentIdColumn.php
View Options
<?php
namespace
MediaWiki\Extension\GlobalBlocking\Maintenance
;
use
MediaWiki\Maintenance\LoggedUpdateMaintenance
;
use
Wikimedia\Rdbms\IMaintainableDatabase
;
use
Wikimedia\Rdbms\SelectQueryBuilder
;
// @codeCoverageIgnoreStart
$IP
=
getenv
(
'MW_INSTALL_PATH'
);
if
(
$IP
===
false
)
{
$IP
=
__DIR__
.
'/../../..'
;
}
require_once
"$IP/maintenance/Maintenance.php"
;
// @codeCoverageIgnoreEnd
/**
* Maintenance script for updating gb_autoblock_parent_id to replace NULL values with 0.
*/
class
UpdateAutoBlockParentIdColumn
extends
LoggedUpdateMaintenance
{
public
function
__construct
()
{
parent
::
__construct
();
$this
->
addDescription
(
"Used to update the values of NULL for gb_autoblock_parent_id to 0 (T376340). Necessary because "
.
"the gb_autoblock_parent_id is used in a unique index which does not work as intended with NULL values. "
.
"If you use a central globalblocks table, you only need to run this script once for the wikis which "
.
"use the central table."
);
$this
->
requireExtension
(
'GlobalBlocking'
);
}
/** @inheritDoc */
public
function
getUpdateKey
()
{
return
__CLASS__
;
}
/** @inheritDoc */
public
function
doDbUpdates
()
{
$connectionProvider
=
$this
->
getServiceContainer
()->
getConnectionProvider
();
$dbr
=
$connectionProvider
->
getReplicaDatabase
(
'virtual-globalblocking'
);
if
(
!(
$dbr
instanceof
IMaintainableDatabase
)
)
{
throw
new
\RuntimeException
(
'Wrong database class'
);
}
$autoBlockParentIdFieldInfo
=
$dbr
->
fieldInfo
(
'globalblocks'
,
'gb_autoblock_parent_id'
);
if
(
!
$autoBlockParentIdFieldInfo
||
!
$autoBlockParentIdFieldInfo
->
isNullable
()
)
{
$this
->
output
(
"The field globalblocks.gb_autoblock_parent_id is not nullable, nothing to do.
\n
"
);
return
true
;
}
$hasRowsToUpdate
=
$dbr
->
newSelectQueryBuilder
()
->
select
(
'1'
)
->
from
(
'globalblocks'
)
->
where
(
[
'gb_autoblock_parent_id'
=>
null
]
)
->
caller
(
__METHOD__
)
->
fetchField
();
if
(
!
$hasRowsToUpdate
)
{
$this
->
output
(
"The globalblocks table has no rows to update.
\n
"
);
return
true
;
}
$success
=
0
;
$failed
=
0
;
$lastProcessedRowId
=
0
;
$dbw
=
$connectionProvider
->
getPrimaryDatabase
(
'virtual-globalblocking'
);
do
{
// Fetch a batch of rows with gb_autoblock_parent_id as NULL
$batchToProcess
=
$dbr
->
newSelectQueryBuilder
()
->
select
(
'gb_id'
)
->
from
(
'globalblocks'
)
->
where
(
[
'gb_autoblock_parent_id'
=>
null
,
$dbr
->
expr
(
'gb_id'
,
'>'
,
$lastProcessedRowId
),
]
)
->
orderBy
(
'gb_id'
,
SelectQueryBuilder
::
SORT_ASC
)
->
limit
(
$this
->
getBatchSize
()
)
->
caller
(
__METHOD__
)
->
fetchFieldValues
();
if
(
count
(
$batchToProcess
)
)
{
$lastId
=
end
(
$batchToProcess
);
$firstId
=
reset
(
$batchToProcess
);
$this
->
output
(
"Now processing global blocks with id between $firstId and $lastId...
\n
"
);
foreach
(
$batchToProcess
as
$id
)
{
// Check if the gb_address used by this globalblocks row is used for any other globalblocks
// row where the gb_autoblock_parent_id is 0. If it is, then we cannot update the row with ID
// $id because it would cause a unique index constrant violation.
// We cannot use an UPDATE IGNORE for this as postgres will still throw an error.
$targetForRow
=
$dbr
->
newSelectQueryBuilder
()
->
select
(
'gb_address'
)
->
from
(
'globalblocks'
)
->
where
(
[
'gb_id'
=>
$id
]
)
->
caller
(
__METHOD__
)
->
fetchField
();
$collidingRowExists
=
$dbw
->
newSelectQueryBuilder
()
->
select
(
'1'
)
->
from
(
'globalblocks'
)
->
where
(
[
'gb_address'
=>
$targetForRow
,
'gb_autoblock_parent_id'
=>
0
]
)
->
fetchField
();
if
(
!
$collidingRowExists
)
{
$dbw
->
newUpdateQueryBuilder
()
->
update
(
'globalblocks'
)
->
set
(
[
'gb_autoblock_parent_id'
=>
0
]
)
->
where
(
[
'gb_id'
=>
$id
]
)
->
caller
(
__METHOD__
)
->
execute
();
}
$newValue
=
$dbw
->
newSelectQueryBuilder
()
->
select
(
'gb_autoblock_parent_id'
)
->
from
(
'globalblocks'
)
->
where
(
[
'gb_id'
=>
$id
]
)
->
fetchField
();
if
(
$newValue
!==
null
)
{
$success
+=
1
;
}
else
{
$this
->
output
(
"...Failed to update row with ID $id.
\n
"
);
$failed
+=
1
;
}
}
$lastProcessedRowId
=
end
(
$batchToProcess
);
$this
->
waitForReplication
();
}
}
while
(
count
(
$batchToProcess
)
===
$this
->
getBatchSize
()
);
$this
->
output
(
"Completed migration, updated $success row(s), failed to update $failed row(s).
\n
"
);
return
true
;
}
}
// @codeCoverageIgnoreStart
$maintClass
=
UpdateAutoBlockParentIdColumn
::
class
;
require_once
RUN_MAINTENANCE_IF_MAIN
;
// @codeCoverageIgnoreEnd
File Metadata
Details
Attached
Mime Type
text/x-php
Expires
Wed, Aug 19, 13:47 (3 w, 3 d ago)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
ee/85/4a026f2c0b501e1104bdbc6624c0
Default Alt Text
UpdateAutoBlockParentIdColumn.php (4 KB)
Attached To
Mode
rMWPROD MediaWiki Production
Attached
Detach File
Event Timeline
Log In to Comment