Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
| Total | |
0.00% |
0 / 46 |
|
0.00% |
0 / 3 |
CRAP | |
0.00% |
0 / 1 |
| FixPagePropsSortkey | |
0.00% |
0 / 45 |
|
0.00% |
0 / 3 |
30 | |
0.00% |
0 / 1 |
| __construct | |
0.00% |
0 / 7 |
|
0.00% |
0 / 1 |
2 | |||
| doDBUpdates | |
0.00% |
0 / 37 |
|
0.00% |
0 / 1 |
12 | |||
| getUpdateKey | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
| 1 | <?php |
| 2 | |
| 3 | declare( strict_types = 1 ); |
| 4 | |
| 5 | namespace Wikibase\Lexeme\Maintenance; |
| 6 | |
| 7 | use MediaWiki\Maintenance\LoggedUpdateMaintenance; |
| 8 | |
| 9 | /** |
| 10 | * Maintenance script to fix the pp_sortkey column of the page_props table |
| 11 | * for pp_propname wb-claims, wbl-forms and wbl-senses. |
| 12 | * |
| 13 | * Due to a bug (T350224), some lexemes had their pp_sortkey set to NULL, |
| 14 | * rather than the number of statements, forms or senses. |
| 15 | * To fix this, set the pp_sortkey based on the (assumed correct) pp_value. |
| 16 | * Note that we do not limit this to the Lexeme namespace (no JOIN with the page table): |
| 17 | * the pp_sortkey is not expected to be NULL anywhere else, |
| 18 | * but even if it is, setting it to the numerical value of the pp_value should be correct. |
| 19 | * (But we only do this for the three pp_propname strings known to be affected, |
| 20 | * not any random other page prop.) |
| 21 | * |
| 22 | * Usually, this script is run via update.php and there is no need to run it manually. |
| 23 | * |
| 24 | * This maintenance script can be removed again after a while |
| 25 | * (once we assume all installations have run this script to fix their old data). |
| 26 | * The bug was first introduced in the REL1_39 branch (MediaWiki 1.39). |
| 27 | * |
| 28 | * @license GPL-2.0-or-later |
| 29 | */ |
| 30 | class FixPagePropsSortkey extends LoggedUpdateMaintenance { |
| 31 | |
| 32 | public function __construct() { |
| 33 | parent::__construct(); |
| 34 | |
| 35 | $this->addDescription( |
| 36 | 'Fix the pp_sortkey of wb-claims, wbl-forms and wbl-senses page props ' . |
| 37 | 'where it is NULL (see T350224).' |
| 38 | ); |
| 39 | $this->requireExtension( 'WikibaseLexeme' ); |
| 40 | $this->requireExtension( 'WikibaseRepository' ); |
| 41 | } |
| 42 | |
| 43 | public function doDBUpdates(): bool { |
| 44 | $dbr = $this->getDB( DB_REPLICA ); |
| 45 | $dbw = $this->getDB( DB_PRIMARY ); |
| 46 | |
| 47 | $pageIdsQueryBuilder = $dbr->newSelectQueryBuilder() |
| 48 | ->select( 'pp_page' ) |
| 49 | ->from( 'page_props' ) |
| 50 | ->where( [ |
| 51 | 'pp_propname' => [ 'wb-claims', 'wbl-forms', 'wbl-senses' ], |
| 52 | 'pp_sortkey' => null, |
| 53 | ] ) |
| 54 | ->orderBy( [ 'pp_propname', 'pp_page' ] ) // uses pp_propname_sortkey_page index |
| 55 | ->limit( $this->getBatchSize() ) |
| 56 | ->caller( __METHOD__ ); |
| 57 | $updateQueryBuilder = $dbw->newUpdateQueryBuilder() |
| 58 | ->update( 'page_props' ) |
| 59 | ->set( 'pp_sortkey = CAST(pp_value AS FLOAT)' ) |
| 60 | ->where( [ |
| 61 | 'pp_propname' => [ 'wb-claims', 'wbl-forms', 'wbl-senses' ], |
| 62 | 'pp_sortkey' => null, |
| 63 | // pp_page condition added in loop, per iteration |
| 64 | ] ) |
| 65 | ->caller( __METHOD__ ); |
| 66 | |
| 67 | $this->output( __CLASS__ . ' running...' . PHP_EOL ); |
| 68 | |
| 69 | while ( true ) { |
| 70 | $pageIds = ( clone $pageIdsQueryBuilder )->fetchFieldValues(); |
| 71 | if ( !$pageIds ) { |
| 72 | break; |
| 73 | } |
| 74 | $pageIds = array_values( array_unique( $pageIds ) ); |
| 75 | |
| 76 | $this->beginTransaction( $dbw, __METHOD__ ); |
| 77 | ( clone $updateQueryBuilder ) |
| 78 | ->andWhere( [ 'pp_page' => $pageIds ] ) |
| 79 | ->execute(); |
| 80 | $this->commitTransaction( $dbw, __METHOD__ ); // this also waits for replication |
| 81 | $minPageId = reset( $pageIds ); |
| 82 | $maxPageId = end( $pageIds ); |
| 83 | // note: because we order by pp_propname first, it’s theoretically possible that |
| 84 | // $minPageId > $maxPageId; however, the UPDATE affects all page props at once, |
| 85 | // so in practice the script will most likely only make one pass through the table |
| 86 | $this->output( "Update page IDs from $minPageId to $maxPageId..." . PHP_EOL ); |
| 87 | } |
| 88 | |
| 89 | $this->output( 'Done.' . PHP_EOL ); |
| 90 | |
| 91 | return true; |
| 92 | } |
| 93 | |
| 94 | protected function getUpdateKey(): string { |
| 95 | return __CLASS__; |
| 96 | } |
| 97 | |
| 98 | } |
| 99 | |
| 100 | return FixPagePropsSortkey::class; |