Add a maintenance script for populating pp_sortkey
authormdew192837 <justin.d128@gmail.com>
Wed, 24 May 2017 21:00:08 +0000 (16:00 -0500)
committerMtDu <justin.d128@gmail.com>
Thu, 13 Jul 2017 22:55:26 +0000 (22:55 +0000)
The addition of a pp_sortkey field in T60032 necessitates an update
to old entries in the page_props table that don't have a pp_sortkey.
The script uses the pp_value as the sort key if it's numeric.
The script extends LoggedUpdateMaintenance so it only runs once.
Added the script to MysqlUpdater so that it automatically runs.

Bug: T66949
Change-Id: Id482dc73ec1963010324e51fe9273a72dd31a7f7

autoload.php
includes/installer/DatabaseUpdater.php
maintenance/populatePPSortKey.php [new file with mode: 0644]

index 2560bdb..003ebd9 100644 (file)
@@ -1117,6 +1117,7 @@ $wgAutoloadLocalClasses = [
        'PopulateInterwiki' => __DIR__ . '/maintenance/populateInterwiki.php',
        'PopulateLogSearch' => __DIR__ . '/maintenance/populateLogSearch.php',
        'PopulateLogUsertext' => __DIR__ . '/maintenance/populateLogUsertext.php',
+       'PopulatePPSortKey' => __DIR__ . '/maintenance/populatePPSortKey.php',
        'PopulateParentId' => __DIR__ . '/maintenance/populateParentId.php',
        'PopulateRecentChangesSource' => __DIR__ . '/maintenance/populateRecentChangesSource.php',
        'PopulateRevisionLength' => __DIR__ . '/maintenance/populateRevisionLength.php',
index e5cbb7c..53acc98 100644 (file)
@@ -83,6 +83,7 @@ abstract class DatabaseUpdater {
                FixDefaultJsonContentPages::class,
                CleanupEmptyCategories::class,
                AddRFCAndPMIDInterwiki::class,
+               PopulatePPSortKey::class
        ];
 
        /**
diff --git a/maintenance/populatePPSortKey.php b/maintenance/populatePPSortKey.php
new file mode 100644 (file)
index 0000000..519c665
--- /dev/null
@@ -0,0 +1,105 @@
+<?php
+/**
+ * Populate the pp_sortkey fields in the page_props table
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @ingroup Maintenance
+ */
+
+require_once __DIR__ . '/Maintenance.php';
+
+use Wikimedia\Rdbms\IDatabase;
+
+/**
+ * Usage:
+ *  populatePPSortKey.php
+ */
+class PopulatePPSortKey extends LoggedUpdateMaintenance {
+       public function __construct() {
+               parent::__construct();
+               $this->addDescription( 'Populate the pp_sortkey field' );
+               $this->setBatchSize( 100 );
+       }
+
+       protected function doDBUpdates() {
+               $dbw = $this->getDB( DB_MASTER );
+
+               $lastProp = null;
+               $lastPageValue = 0;
+               $editedRowCount = 0;
+
+               while ( true ) {
+                       $conditions = [ 'pp_sortkey IS NULL' ];
+                       if ( $lastPageValue !== 0 ) {
+                               $conditions[] = 'pp_page > ' . $dbw->addQuotes( $lastPageValue ) . ' OR ' .
+                                       '( pp_page = ' . $dbw->addQuotes( $lastPageValue ) .
+                                       ' AND pp_propname > ' . $dbw->addQuotes( $lastProp ) . ' )';
+                       }
+
+                       $res = $dbw->select(
+                               'page_props',
+                               [ 'pp_propname', 'pp_page', 'pp_sortkey', 'pp_value' ],
+                               $conditions,
+                               __METHOD__,
+                               [
+                                       'ORDER BY' => 'pp_page, pp_propname',
+                                       'LIMIT' => $this->mBatchSize
+                               ]
+                       );
+
+                       if ( $res->numRows() === 0 ) {
+                               break;
+                       }
+
+                       $this->beginTransaction( $dbw, __METHOD__ );
+
+                       foreach ( $res as $row ) {
+                               if ( !is_numeric( $row->pp_value ) ) {
+                                       continue;
+                               }
+                               $dbw->update(
+                                       'page_props',
+                                       [ 'pp_sortkey' => $row->pp_value ],
+                                       [
+                                               'pp_page' => $row->pp_page,
+                                               'pp_propname' => $row->pp_propname
+                                       ],
+                                       __METHOD__
+                               );
+                               $editedRowCount++;
+                       }
+
+                       $this->output( "Updated " . $editedRowCount . " rows\n" );
+                       $this->commitTransaction( $dbw, __METHOD__ );
+
+                       // We need to get the last element's page ID
+                       $lastPageValue = $row->pp_value;
+                       // And the propname...
+                       $lastProp = $row->pp_propname;
+               }
+
+               $this->output( "Done!\n" );
+       }
+
+       protected function getUpdateKey() {
+               return 'populate pp_sortkey';
+       }
+}
+
+$maintClass = 'PopulatePPSortKey';
+require_once RUN_MAINTENANCE_IF_MAIN;