X-Git-Url: https://git.cyclocoop.org/?a=blobdiff_plain;f=maintenance%2FMaintenance.php;h=cec12709625a482ff973a32cafbd103b52023573;hb=56dbeaa4482ff031f8d270f65c66462375e4a1df;hp=adccee197a290dfd243f3155a576b90d49a4a553;hpb=321de8502c2535467729b9da8aa579a21a14c92e;p=lhc%2Fweb%2Fwiklou.git diff --git a/maintenance/Maintenance.php b/maintenance/Maintenance.php index adccee197a..cec1270962 100644 --- a/maintenance/Maintenance.php +++ b/maintenance/Maintenance.php @@ -20,6 +20,11 @@ * @defgroup Maintenance Maintenance */ +/** + * @defgroup MaintenanceArchive Maintenance archives + * @ingroup Maintenance + */ + // Define this so scripts can easily find doMaintenance.php define( 'RUN_MAINTENANCE_IF_MAIN', dirname( __FILE__ ) . '/doMaintenance.php' ); define( 'DO_MAINTENANCE', RUN_MAINTENANCE_IF_MAIN ); // original name, harmless @@ -27,7 +32,7 @@ define( 'DO_MAINTENANCE', RUN_MAINTENANCE_IF_MAIN ); // original name, harmless $maintClass = false; // Make sure we're on PHP5 or better -if ( !function_exists( 'version_compare' ) || version_compare( PHP_VERSION, '5.2.3' ) < 0 ) { +if ( !function_exists( 'version_compare' ) || version_compare( PHP_VERSION, '5.3.2' ) < 0 ) { require_once( dirname( __FILE__ ) . '/../includes/PHPVersionError.php' ); wfPHPVersionError( 'cli' ); } @@ -96,7 +101,10 @@ abstract class Maintenance { // Generic options which might or not be supported by the script private $mDependantParameters = array(); - // Used by getDD() / setDB() + /** + * Used by getDD() / setDB() + * @var DatabaseBase + */ private $mDb = null; /** @@ -292,6 +300,9 @@ abstract class Maintenance { return rtrim( $input ); } + /** + * @return bool + */ public function isQuiet() { return $this->mQuiet; } @@ -309,12 +320,8 @@ abstract class Maintenance { } if ( $channel === null ) { $this->cleanupChanneled(); - - $f = fopen( 'php://stdout', 'w' ); - fwrite( $f, $out ); - fclose( $f ); - } - else { + print( $out ); + } else { $out = preg_replace( '/\n\z/', '', $out ); $this->outputChanneled( $out, $channel ); } @@ -331,9 +338,7 @@ abstract class Maintenance { if ( php_sapi_name() == 'cli' ) { fwrite( STDERR, $err . "\n" ); } else { - $f = fopen( 'php://stderr', 'w' ); - fwrite( $f, $err . "\n" ); - fclose( $f ); + print $err; } $die = intval( $die ); if ( $die > 0 ) { @@ -349,9 +354,7 @@ abstract class Maintenance { */ public function cleanupChanneled() { if ( !$this->atLineStart ) { - $handle = fopen( 'php://stdout', 'w' ); - fwrite( $handle, "\n" ); - fclose( $handle ); + print "\n"; $this->atLineStart = true; } } @@ -361,7 +364,7 @@ abstract class Maintenance { * same channel are concatenated, but any intervening messages in another * channel start a new line. * @param $msg String: the message without trailing newline - * @param $channel Channel identifier or null for no + * @param $channel string Channel identifier or null for no * channel. Channel comparison uses ===. */ public function outputChanneled( $msg, $channel = null ) { @@ -370,25 +373,20 @@ abstract class Maintenance { return; } - $handle = fopen( 'php://stdout', 'w' ); - // End the current line if necessary if ( !$this->atLineStart && $channel !== $this->lastChannel ) { - fwrite( $handle, "\n" ); + print "\n"; } - fwrite( $handle, $msg ); + print $msg; $this->atLineStart = false; if ( $channel === null ) { // For unchanneled messages, output trailing newline immediately - fwrite( $handle, "\n" ); + print "\n"; $this->atLineStart = true; } $this->lastChannel = $channel; - - // Cleanup handle - fclose( $handle ); } /** @@ -456,6 +454,9 @@ abstract class Maintenance { } } + /** + * @var $child Maintenance + */ $child = new $maintClass(); $child->loadParamsAndArgs( $this->mSelf, $this->mOptions, $this->mArgs ); if ( !is_null( $this->mDb ) ) { @@ -526,6 +527,7 @@ abstract class Maintenance { * to allow sysadmins to explicitly set one if they'd prefer to override * defaults (or for people using Suhosin which yells at you for trying * to disable the limits) + * @return string */ public function memoryLimit() { $limit = $this->getOption( 'memory-limit', 'max' ); @@ -852,6 +854,9 @@ abstract class Maintenance { $wgDBpassword = $wgDBadminpassword; if ( $wgDBservers ) { + /** + * @var $wgDBservers array + */ foreach ( $wgDBservers as $i => $server ) { $wgDBservers[$i]['user'] = $wgDBuser; $wgDBservers[$i]['password'] = $wgDBpassword; @@ -930,7 +935,7 @@ abstract class Maintenance { public function purgeRedundantText( $delete = true ) { # Data should come off the master, wrapped in a transaction $dbw = $this->getDB( DB_MASTER ); - $dbw->begin(); + $dbw->begin( __METHOD__ ); $tbl_arc = $dbw->tableName( 'archive' ); $tbl_rev = $dbw->tableName( 'revision' ); @@ -975,11 +980,12 @@ abstract class Maintenance { } # Done - $dbw->commit(); + $dbw->commit( __METHOD__ ); } /** * Get the maintenance directory. + * @return string */ protected function getDir() { return dirname( __FILE__ ); @@ -1004,7 +1010,6 @@ abstract class Maintenance { if ( !self::$mCoreScripts ) { $paths = array( dirname( __FILE__ ), - dirname( __FILE__ ) . '/gearman', dirname( __FILE__ ) . '/language', dirname( __FILE__ ) . '/storage', ); @@ -1058,7 +1063,7 @@ abstract class Maintenance { /** * Lock the search index - * @param &$db Database object + * @param &$db DatabaseBase object */ private function lockSearchindex( &$db ) { $write = array( 'searchindex' ); @@ -1068,7 +1073,7 @@ abstract class Maintenance { /** * Unlock the tables - * @param &$db Database object + * @param &$db DatabaseBase object */ private function unlockSearchindex( &$db ) { $db->unlockTables( __CLASS__ . '::' . __METHOD__ ); @@ -1077,7 +1082,7 @@ abstract class Maintenance { /** * Unlock and lock again * Since the lock is low-priority, queued reads will be able to complete - * @param &$db Database object + * @param &$db DatabaseBase object */ private function relockSearchindex( &$db ) { $this->unlockSearchindex( $db ); @@ -1125,8 +1130,9 @@ abstract class Maintenance { /** * Update the searchindex table for a given pageid - * @param $dbw Database: a database write handle + * @param $dbw DatabaseBase a database write handle * @param $pageId Integer: the page ID to update. + * @return null|string */ public function updateSearchIndexForPage( $dbw, $pageId ) { // Get current revision @@ -1224,6 +1230,9 @@ abstract class Maintenance { } } +/** + * Fake maintenance wrapper, mostly used for the web installer/updater + */ class FakeMaintenance extends Maintenance { protected $mSelf = "FakeMaintenanceScript"; public function execute() { @@ -1231,10 +1240,15 @@ class FakeMaintenance extends Maintenance { } } +/** + * Class for scripts that perform database maintenance and want to log the + * update in `updatelog` so we can later skip it + */ abstract class LoggedUpdateMaintenance extends Maintenance { public function __construct() { parent::__construct(); $this->addOption( 'force', 'Run the update even if it was completed already' ); + $this->setBatchSize( 200 ); } public function execute() { @@ -1244,7 +1258,7 @@ abstract class LoggedUpdateMaintenance extends Maintenance { if ( !$this->hasOption( 'force' ) && $db->selectRow( 'updatelog', '1', array( 'ul_key' => $key ), __METHOD__ ) ) { - $this->output( $this->updateSkippedMessage() . "\n" ); + $this->output( "..." . $this->updateSkippedMessage() . "\n" ); return true; } @@ -1263,27 +1277,33 @@ abstract class LoggedUpdateMaintenance extends Maintenance { } /** - * Do the actual work. All child classes will need to implement this. - * Return true to log the update as done or false (usually on failure). - * @return Bool + * Message to show that the update was done already and was just skipped + * @return String */ - abstract protected function doDBUpdates(); + protected function updateSkippedMessage() { + $key = $this->getUpdateKey(); + return "Update '{$key}' already logged as completed."; + } /** - * Get the update key name to go in the update log table + * Message to show the the update log was unable to log the completion of this update * @return String */ - abstract protected function getUpdateKey(); + protected function updatelogFailedMessage() { + $key = $this->getUpdateKey(); + return "Unable to log update '{$key}' as completed."; + } /** - * Message to show that the update was done already and was just skipped - * @return String + * Do the actual work. All child classes will need to implement this. + * Return true to log the update as done or false (usually on failure). + * @return Bool */ - abstract protected function updateSkippedMessage(); + abstract protected function doDBUpdates(); /** - * Message to show the the update log was unable to log the completion of this update + * Get the update key name to go in the update log table * @return String */ - abstract protected function updatelogFailedMessage(); + abstract protected function getUpdateKey(); }