Use wfWaitForSlaves in upload stash cleanup script
[lhc/web/wiklou.git] / maintenance / populateImageSha1.php
index 54ff247..e9123aa 100644 (file)
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  * http://www.gnu.org/copyleft/gpl.html
  *
+ * @file
  * @ingroup Maintenance
  */
 
-require_once( dirname( __FILE__ ) . '/Maintenance.php' );
+require_once __DIR__ . '/Maintenance.php';
 
+/**
+ * Maintenance script to populate the img_sha1 field.
+ *
+ * @ingroup Maintenance
+ */
 class PopulateImageSha1 extends LoggedUpdateMaintenance {
        public function __construct() {
                parent::__construct();
                $this->mDescription = "Populate the img_sha1 field";
                $this->addOption( 'force', "Recalculate sha1 for rows that already have a value" );
+               $this->addOption( 'multiversiononly', "Calculate only for files with several versions" );
                $this->addOption( 'method', "Use 'pipe' to pipe to mysql command line,\n" .
                        "\t\tdefault uses Database class", false, true );
-               $this->addOption( 'file', 'Fix for a specific file, without File: namespace prefixed', false, true );
+               $this->addOption(
+                       'file',
+                       'Fix for a specific file, without File: namespace prefixed',
+                       false,
+                       true
+               );
        }
 
        protected function getUpdateKey() {
@@ -41,7 +53,7 @@ class PopulateImageSha1 extends LoggedUpdateMaintenance {
        }
 
        public function execute() {
-               if ( $this->getOption( 'file' ) ) {
+               if ( $this->getOption( 'file' ) || $this->hasOption( 'multiversiononly' ) ) {
                        $this->doDBUpdates(); // skip update log checks/saves
                } else {
                        parent::execute();
@@ -50,12 +62,13 @@ class PopulateImageSha1 extends LoggedUpdateMaintenance {
 
        public function doDBUpdates() {
                $method = $this->getOption( 'method', 'normal' );
-               $file = $this->getOption( 'file' );
+               $file = $this->getOption( 'file', '' );
                $force = $this->getOption( 'force' );
+               $isRegen = ( $force || $file != '' ); // forced recalculation?
 
                $t = -microtime( true );
                $dbw = wfGetDB( DB_MASTER );
-               if ( $file ) {
+               if ( $file != '' ) {
                        $res = $dbw->select(
                                'image',
                                array( 'img_name' ),
@@ -64,28 +77,37 @@ class PopulateImageSha1 extends LoggedUpdateMaintenance {
                        );
                        if ( !$res ) {
                                $this->error( "No such file: $file", true );
+
                                return false;
                        }
                        $this->output( "Populating img_sha1 field for specified files\n" );
                } else {
-                       if ( $force ) {
+                       if ( $this->hasOption( 'multiversiononly' ) ) {
+                               $conds = array();
+                               $this->output( "Populating and recalculating img_sha1 field for versioned files\n" );
+                       } elseif ( $force ) {
                                $conds = array();
                                $this->output( "Populating and recalculating img_sha1 field\n" );
                        } else {
                                $conds = array( 'img_sha1' => '' );
                                $this->output( "Populating img_sha1 field\n" );
                        }
-                       $res = $dbw->select( 'image', array( 'img_name' ), $conds, __METHOD__ );
+                       if ( $this->hasOption( 'multiversiononly' ) ) {
+                               $res = $dbw->select( 'oldimage',
+                                       array( 'img_name' => 'DISTINCT(oi_name)' ), $conds, __METHOD__ );
+                       } else {
+                               $res = $dbw->select( 'image', array( 'img_name' ), $conds, __METHOD__ );
+                       }
                }
 
                $imageTable = $dbw->tableName( 'image' );
                $oldImageTable = $dbw->tableName( 'oldimage' );
 
                if ( $method == 'pipe' ) {
-                       // Opening a pipe allows the SHA-1 operation to be done in parallel 
+                       // Opening a pipe allows the SHA-1 operation to be done in parallel
                        // with the database write operation, because the writes are queued
-                       // in the pipe buffer. This can improve performance by up to a 
-                       // factor of 2. 
+                       // in the pipe buffer. This can improve performance by up to a
+                       // factor of 2.
                        global $wgDBuser, $wgDBserver, $wgDBpassword, $wgDBname;
                        $cmd = 'mysql -u' . wfEscapeShellArg( $wgDBuser ) .
                                ' -h' . wfEscapeShellArg( $wgDBserver ) .
@@ -102,32 +124,46 @@ class PopulateImageSha1 extends LoggedUpdateMaintenance {
                                        "Done %d of %d, %5.3f%%  \r", $i, $numRows, $i / $numRows * 100 ) );
                                wfWaitForSlaves();
                        }
+
                        $file = wfLocalFile( $row->img_name );
                        if ( !$file ) {
                                continue;
                        }
+
                        // Upgrade the current file version...
                        $sha1 = $file->getRepo()->getFileSha1( $file->getPath() );
                        if ( strval( $sha1 ) !== '' ) { // file on disk and hashed properly
-                               $sql = "UPDATE $imageTable SET img_sha1=" . $dbw->addQuotes( $sha1 ) .
-                                       " WHERE img_name=" . $dbw->addQuotes( $file->getName() );
-                               if ( $method == 'pipe' ) {
-                                       fwrite( $pipe, "$sql;\n" );
+                               if ( $isRegen && $file->getSha1() !== $sha1 ) {
+                                       // The population was probably done already. If the old SHA1
+                                       // does not match, then both fix the SHA1 and the metadata.
+                                       $file->upgradeRow();
                                } else {
-                                       $dbw->query( $sql, __METHOD__ );
+                                       $sql = "UPDATE $imageTable SET img_sha1=" . $dbw->addQuotes( $sha1 ) .
+                                               " WHERE img_name=" . $dbw->addQuotes( $file->getName() );
+                                       if ( $method == 'pipe' ) {
+                                               fwrite( $pipe, "$sql;\n" );
+                                       } else {
+                                               $dbw->query( $sql, __METHOD__ );
+                                       }
                                }
                        }
                        // Upgrade the old file versions...
                        foreach ( $file->getHistory() as $oldFile ) {
                                $sha1 = $oldFile->getRepo()->getFileSha1( $oldFile->getPath() );
                                if ( strval( $sha1 ) !== '' ) { // file on disk and hashed properly
-                                       $sql = "UPDATE $oldImageTable SET oi_sha1=" . $dbw->addQuotes( $sha1 ) .
-                                               " WHERE (oi_name=" . $dbw->addQuotes( $oldFile->getName() ) . " AND" .
-                                               " oi_archive_name=" . $dbw->addQuotes( $oldFile->getArchiveName() ) . ")";
-                                       if ( $method == 'pipe' ) {
-                                               fwrite( $pipe, "$sql;\n" );
+                                       if ( $isRegen && $oldFile->getSha1() !== $sha1 ) {
+                                               // The population was probably done already. If the old SHA1
+                                               // does not match, then both fix the SHA1 and the metadata.
+                                               $oldFile->upgradeRow();
                                        } else {
-                                               $dbw->query( $sql, __METHOD__ );
+                                               $sql = "UPDATE $oldImageTable SET oi_sha1=" . $dbw->addQuotes( $sha1 ) .
+                                                       " WHERE (oi_name=" . $dbw->addQuotes( $oldFile->getName() ) . " AND" .
+                                                       " oi_archive_name=" . $dbw->addQuotes( $oldFile->getArchiveName() ) . ")";
+                                               if ( $method == 'pipe' ) {
+                                                       fwrite( $pipe, "$sql;\n" );
+                                               } else {
+                                                       $dbw->query( $sql, __METHOD__ );
+                                               }
                                        }
                                }
                        }
@@ -145,4 +181,4 @@ class PopulateImageSha1 extends LoggedUpdateMaintenance {
 }
 
 $maintClass = "PopulateImageSha1";
-require_once( RUN_MAINTENANCE_IF_MAIN );
+require_once RUN_MAINTENANCE_IF_MAIN;