[ Index ]

PHP Cross Reference of MediaWiki-1.24.0

title

Body

[close]

/maintenance/ -> populateImageSha1.php (source)

   1  <?php
   2  /**
   3   * Optional upgrade script to populate the img_sha1 field
   4   *
   5   * This program is free software; you can redistribute it and/or modify
   6   * it under the terms of the GNU General Public License as published by
   7   * the Free Software Foundation; either version 2 of the License, or
   8   * (at your option) any later version.
   9   *
  10   * This program is distributed in the hope that it will be useful,
  11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13   * GNU General Public License for more details.
  14   *
  15   * You should have received a copy of the GNU General Public License along
  16   * with this program; if not, write to the Free Software Foundation, Inc.,
  17   * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  18   * http://www.gnu.org/copyleft/gpl.html
  19   *
  20   * @file
  21   * @ingroup Maintenance
  22   */
  23  
  24  require_once  __DIR__ . '/Maintenance.php';
  25  
  26  /**
  27   * Maintenance script to populate the img_sha1 field.
  28   *
  29   * @ingroup Maintenance
  30   */
  31  class PopulateImageSha1 extends LoggedUpdateMaintenance {
  32  	public function __construct() {
  33          parent::__construct();
  34          $this->mDescription = "Populate the img_sha1 field";
  35          $this->addOption( 'force', "Recalculate sha1 for rows that already have a value" );
  36          $this->addOption( 'multiversiononly', "Calculate only for files with several versions" );
  37          $this->addOption( 'method', "Use 'pipe' to pipe to mysql command line,\n" .
  38              "\t\tdefault uses Database class", false, true );
  39          $this->addOption(
  40              'file',
  41              'Fix for a specific file, without File: namespace prefixed',
  42              false,
  43              true
  44          );
  45      }
  46  
  47  	protected function getUpdateKey() {
  48          return 'populate img_sha1';
  49      }
  50  
  51  	protected function updateSkippedMessage() {
  52          return 'img_sha1 column of image table already populated.';
  53      }
  54  
  55  	public function execute() {
  56          if ( $this->getOption( 'file' ) || $this->hasOption( 'multiversiononly' ) ) {
  57              $this->doDBUpdates(); // skip update log checks/saves
  58          } else {
  59              parent::execute();
  60          }
  61      }
  62  
  63  	public function doDBUpdates() {
  64          $method = $this->getOption( 'method', 'normal' );
  65          $file = $this->getOption( 'file', '' );
  66          $force = $this->getOption( 'force' );
  67          $isRegen = ( $force || $file != '' ); // forced recalculation?
  68  
  69          $t = -microtime( true );
  70          $dbw = wfGetDB( DB_MASTER );
  71          if ( $file != '' ) {
  72              $res = $dbw->select(
  73                  'image',
  74                  array( 'img_name' ),
  75                  array( 'img_name' => $file ),
  76                  __METHOD__
  77              );
  78              if ( !$res ) {
  79                  $this->error( "No such file: $file", true );
  80  
  81                  return false;
  82              }
  83              $this->output( "Populating img_sha1 field for specified files\n" );
  84          } else {
  85              if ( $this->hasOption( 'multiversiononly' ) ) {
  86                  $conds = array();
  87                  $this->output( "Populating and recalculating img_sha1 field for versioned files\n" );
  88              } elseif ( $force ) {
  89                  $conds = array();
  90                  $this->output( "Populating and recalculating img_sha1 field\n" );
  91              } else {
  92                  $conds = array( 'img_sha1' => '' );
  93                  $this->output( "Populating img_sha1 field\n" );
  94              }
  95              if ( $this->hasOption( 'multiversiononly' ) ) {
  96                  $res = $dbw->select( 'oldimage',
  97                      array( 'img_name' => 'DISTINCT(oi_name)' ), $conds, __METHOD__ );
  98              } else {
  99                  $res = $dbw->select( 'image', array( 'img_name' ), $conds, __METHOD__ );
 100              }
 101          }
 102  
 103          $imageTable = $dbw->tableName( 'image' );
 104          $oldImageTable = $dbw->tableName( 'oldimage' );
 105  
 106          if ( $method == 'pipe' ) {
 107              // Opening a pipe allows the SHA-1 operation to be done in parallel
 108              // with the database write operation, because the writes are queued
 109              // in the pipe buffer. This can improve performance by up to a
 110              // factor of 2.
 111              global $wgDBuser, $wgDBserver, $wgDBpassword, $wgDBname;
 112              $cmd = 'mysql -u' . wfEscapeShellArg( $wgDBuser ) .
 113                  ' -h' . wfEscapeShellArg( $wgDBserver ) .
 114                  ' -p' . wfEscapeShellArg( $wgDBpassword, $wgDBname );
 115              $this->output( "Using pipe method\n" );
 116              $pipe = popen( $cmd, 'w' );
 117          }
 118  
 119          $numRows = $res->numRows();
 120          $i = 0;
 121          foreach ( $res as $row ) {
 122              if ( $i % $this->mBatchSize == 0 ) {
 123                  $this->output( sprintf(
 124                      "Done %d of %d, %5.3f%%  \r", $i, $numRows, $i / $numRows * 100 ) );
 125                  wfWaitForSlaves();
 126              }
 127  
 128              $file = wfLocalFile( $row->img_name );
 129              if ( !$file ) {
 130                  continue;
 131              }
 132  
 133              // Upgrade the current file version...
 134              $sha1 = $file->getRepo()->getFileSha1( $file->getPath() );
 135              if ( strval( $sha1 ) !== '' ) { // file on disk and hashed properly
 136                  if ( $isRegen && $file->getSha1() !== $sha1 ) {
 137                      // The population was probably done already. If the old SHA1
 138                      // does not match, then both fix the SHA1 and the metadata.
 139                      $file->upgradeRow();
 140                  } else {
 141                      $sql = "UPDATE $imageTable SET img_sha1=" . $dbw->addQuotes( $sha1 ) .
 142                          " WHERE img_name=" . $dbw->addQuotes( $file->getName() );
 143                      if ( $method == 'pipe' ) {
 144                          fwrite( $pipe, "$sql;\n" );
 145                      } else {
 146                          $dbw->query( $sql, __METHOD__ );
 147                      }
 148                  }
 149              }
 150              // Upgrade the old file versions...
 151              foreach ( $file->getHistory() as $oldFile ) {
 152                  $sha1 = $oldFile->getRepo()->getFileSha1( $oldFile->getPath() );
 153                  if ( strval( $sha1 ) !== '' ) { // file on disk and hashed properly
 154                      if ( $isRegen && $oldFile->getSha1() !== $sha1 ) {
 155                          // The population was probably done already. If the old SHA1
 156                          // does not match, then both fix the SHA1 and the metadata.
 157                          $oldFile->upgradeRow();
 158                      } else {
 159                          $sql = "UPDATE $oldImageTable SET oi_sha1=" . $dbw->addQuotes( $sha1 ) .
 160                              " WHERE (oi_name=" . $dbw->addQuotes( $oldFile->getName() ) . " AND" .
 161                              " oi_archive_name=" . $dbw->addQuotes( $oldFile->getArchiveName() ) . ")";
 162                          if ( $method == 'pipe' ) {
 163                              fwrite( $pipe, "$sql;\n" );
 164                          } else {
 165                              $dbw->query( $sql, __METHOD__ );
 166                          }
 167                      }
 168                  }
 169              }
 170              $i++;
 171          }
 172          if ( $method == 'pipe' ) {
 173              fflush( $pipe );
 174              pclose( $pipe );
 175          }
 176          $t += microtime( true );
 177          $this->output( sprintf( "\nDone %d files in %.1f seconds\n", $numRows, $t ) );
 178  
 179          return !$file; // we only updated *some* files, don't log
 180      }
 181  }
 182  
 183  $maintClass = "PopulateImageSha1";
 184  require_once RUN_MAINTENANCE_IF_MAIN;


Generated: Fri Nov 28 14:03:12 2014 Cross-referenced by PHPXref 0.7.1