MediaWiki  REL1_23
populateCategory.php
Go to the documentation of this file.
00001 <?php
00025 require_once __DIR__ . '/Maintenance.php';
00026 
00032 class PopulateCategory extends Maintenance {
00033 
00034     const REPORTING_INTERVAL = 1000;
00035 
00036     public function __construct() {
00037         parent::__construct();
00038         $this->mDescription = <<<TEXT
00039 This script will populate the category table, added in MediaWiki 1.13.  It will
00040 print out progress indicators every 1000 categories it adds to the table.  The
00041 script is perfectly safe to run on large, live wikis, and running it multiple
00042 times is harmless.  You may want to use the throttling options if it's causing
00043 too much load; they will not affect correctness.
00044 
00045 If the script is stopped and later resumed, you can use the --begin option with
00046 the last printed progress indicator to pick up where you left off.  This is
00047 safe, because any newly-added categories before this cutoff will have been
00048 added after the software update and so will be populated anyway.
00049 
00050 When the script has finished, it will make a note of this in the database, and
00051 will not run again without the --force option.
00052 TEXT;
00053 # '
00054         $this->addOption( 'begin', 'Only do categories whose names are alphabetically after the provided name', false, true );
00055         $this->addOption( 'max-slave-lag', 'If slave lag exceeds this many seconds, wait until it drops before continuing.  Default: 10', false, true );
00056         $this->addOption( 'throttle', 'Wait this many milliseconds after each category.  Default: 0', false, true );
00057         $this->addOption( 'force', 'Run regardless of whether the database says it\'s been run already' );
00058     }
00059 
00060     public function execute() {
00061         $begin = $this->getOption( 'begin', '' );
00062         $maxSlaveLag = $this->getOption( 'max-slave-lag', 10 );
00063         $throttle = $this->getOption( 'throttle', 0 );
00064         $force = $this->getOption( 'force', false );
00065         $this->doPopulateCategory( $begin, $maxSlaveLag, $throttle, $force );
00066     }
00067 
00068     private function doPopulateCategory( $begin, $maxlag, $throttle, $force ) {
00069         $dbw = wfGetDB( DB_MASTER );
00070 
00071         if ( !$force ) {
00072             $row = $dbw->selectRow(
00073                 'updatelog',
00074                 '1',
00075                 array( 'ul_key' => 'populate category' ),
00076                 __METHOD__
00077             );
00078             if ( $row ) {
00079                 $this->output( "Category table already populated.  Use php " .
00080                 "maintenance/populateCategory.php\n--force from the command line " .
00081                 "to override.\n" );
00082                 return true;
00083             }
00084         }
00085 
00086         $throttle = intval( $throttle );
00087         if ( $begin !== '' ) {
00088             $where = 'cl_to > ' . $dbw->addQuotes( $begin );
00089         } else {
00090             $where = null;
00091         }
00092         $i = 0;
00093 
00094         while ( true ) {
00095             # Find which category to update
00096             $row = $dbw->selectRow(
00097                 'categorylinks',
00098                 'cl_to',
00099                 $where,
00100                 __METHOD__,
00101                 array(
00102                     'ORDER BY' => 'cl_to'
00103                 )
00104             );
00105             if ( !$row ) {
00106                 # Done, hopefully.
00107                 break;
00108             }
00109             $name = $row->cl_to;
00110             $where = 'cl_to > ' . $dbw->addQuotes( $name );
00111 
00112             # Use the row to update the category count
00113             $cat = Category::newFromName( $name );
00114             if ( !is_object( $cat ) ) {
00115                 $this->output( "The category named $name is not valid?!\n" );
00116             } else {
00117                 $cat->refreshCounts();
00118             }
00119 
00120             ++$i;
00121             if ( !( $i % self::REPORTING_INTERVAL ) ) {
00122                 $this->output( "$name\n" );
00123                 wfWaitForSlaves();
00124             }
00125             usleep( $throttle * 1000 );
00126         }
00127 
00128         if ( $dbw->insert(
00129                 'updatelog',
00130                 array( 'ul_key' => 'populate category' ),
00131                 __METHOD__,
00132                 'IGNORE'
00133             )
00134         ) {
00135             $this->output( "Category population complete.\n" );
00136             return true;
00137         } else {
00138             $this->output( "Could not insert category population row.\n" );
00139             return false;
00140         }
00141     }
00142 }
00143 
00144 $maintClass = "PopulateCategory";
00145 require_once RUN_MAINTENANCE_IF_MAIN;