Esempio n. 1
0
	/**
	 * Return the history of this file, line by line.
	 * starts with current version, then old versions.
	 * uses $this->historyLine to check which line to return:
	 *  0      return line for current version
	 *  1      query for old versions, return first one
	 *  2, ... return next old version from above query
	 * @return bool
	 */
	public function nextHistoryLine() {
		# Polymorphic function name to distinguish foreign and local fetches
		$fname = get_class( $this ) . '::' . __FUNCTION__;

		$dbr = $this->repo->getSlaveDB();

		if ( $this->historyLine == 0 ) {// called for the first time, return line from cur
			$this->historyRes = $dbr->select( 'image',
				array(
					'*',
					"'' AS oi_archive_name",
					'0 as oi_deleted',
					'img_sha1'
				),
				array( 'img_name' => $this->title->getDBkey() ),
				$fname
			);

			if ( 0 == $dbr->numRows( $this->historyRes ) ) {
				$this->historyRes = null;
				return false;
			}
		} elseif ( $this->historyLine == 1 ) {
			$this->historyRes = $dbr->select( 'oldimage', '*',
				array( 'oi_name' => $this->title->getDBkey() ),
				$fname,
				array( 'ORDER BY' => 'oi_timestamp DESC' )
			);
		}
		$this->historyLine ++;

		return $dbr->fetchObject( $this->historyRes );
	}
Esempio n. 2
0
 protected function checkFiles(LocalRepo $repo, array $paths, $verbose)
 {
     if (!count($paths)) {
         return;
     }
     $dbr = $repo->getSlaveDB();
     $curNames = [];
     $oldNames = [];
     $imgIN = [];
     $oiWheres = [];
     foreach ($paths as $path) {
         $name = basename($path);
         if (preg_match('#^archive/#', $path)) {
             if ($verbose) {
                 $this->output("Checking old file {$name}\n");
             }
             $oldNames[] = $name;
             list(, $base) = explode('!', $name, 2);
             // <TS_MW>!<img_name>
             $oiWheres[] = $dbr->makeList(['oi_name' => $base, 'oi_archive_name' => $name], LIST_AND);
         } else {
             if ($verbose) {
                 $this->output("Checking current file {$name}\n");
             }
             $curNames[] = $name;
             $imgIN[] = $name;
         }
     }
     $res = $dbr->query($dbr->unionQueries([$dbr->selectSQLText('image', ['name' => 'img_name', 'old' => 0], $imgIN ? ['img_name' => $imgIN] : '1=0'), $dbr->selectSQLText('oldimage', ['name' => 'oi_archive_name', 'old' => 1], $oiWheres ? $dbr->makeList($oiWheres, LIST_OR) : '1=0')], true), __METHOD__);
     $curNamesFound = [];
     $oldNamesFound = [];
     foreach ($res as $row) {
         if ($row->old) {
             $oldNamesFound[] = $row->name;
         } else {
             $curNamesFound[] = $row->name;
         }
     }
     foreach (array_diff($curNames, $curNamesFound) as $name) {
         $file = $repo->newFile($name);
         // Print name and public URL to ease recovery
         if ($file) {
             $this->output($name . "\n" . $file->getCanonicalUrl() . "\n\n");
         } else {
             $this->error("Cannot get URL for bad file title '{$name}'");
         }
     }
     foreach (array_diff($oldNames, $oldNamesFound) as $name) {
         list(, $base) = explode('!', $name, 2);
         // <TS_MW>!<img_name>
         $file = $repo->newFromArchiveName(Title::makeTitle(NS_FILE, $base), $name);
         // Print name and public URL to ease recovery
         $this->output($name . "\n" . $file->getCanonicalUrl() . "\n\n");
     }
 }
Esempio n. 3
0
 /**
  * Create a OldLocalFile from a SHA-1 key
  * Do not call this except from inside a repo class.
  *
  * @param string $sha1 Base-36 SHA-1
  * @param LocalRepo $repo
  * @param string|bool $timestamp MW_timestamp (optional)
  *
  * @return bool|OldLocalFile
  */
 static function newFromKey($sha1, $repo, $timestamp = false)
 {
     $dbr = $repo->getSlaveDB();
     $conds = array('oi_sha1' => $sha1);
     if ($timestamp) {
         $conds['oi_timestamp'] = $dbr->timestamp($timestamp);
     }
     $row = $dbr->selectRow('oldimage', self::selectFields(), $conds, __METHOD__);
     if ($row) {
         return self::newFromRow($row, $repo);
     } else {
         return false;
     }
 }
Esempio n. 4
0
 /**
  * Helper function: do the actual database query to fetch file metadata.
  *
  * @param string $key
  * @param int $readFromDB Constant (default: DB_REPLICA)
  * @return bool
  */
 protected function fetchFileMetadata($key, $readFromDB = DB_REPLICA)
 {
     // populate $fileMetadata[$key]
     $dbr = null;
     if ($readFromDB === DB_MASTER) {
         // sometimes reading from the master is necessary, if there's replication lag.
         $dbr = $this->repo->getMasterDB();
     } else {
         $dbr = $this->repo->getSlaveDB();
     }
     $row = $dbr->selectRow('uploadstash', '*', ['us_key' => $key], __METHOD__);
     if (!is_object($row)) {
         // key wasn't present in the database. this will happen sometimes.
         return false;
     }
     $this->fileMetadata[$key] = (array) $row;
     $this->fileMetadata[$key]['us_props'] = $dbr->decodeBlob($row->us_props);
     return true;
 }
Esempio n. 5
0
 protected function checkFiles(LocalRepo $repo, array $names, $verbose)
 {
     if (!count($names)) {
         return;
     }
     $dbr = $repo->getSlaveDB();
     $imgIN = array();
     $oiWheres = array();
     foreach ($names as $name) {
         if (strpos($name, '!') !== false) {
             if ($verbose) {
                 $this->output("Checking old file {$name}\n");
             }
             list(, $base) = explode('!', $name);
             // <TS_MW>!<img_name>
             $oiWheres[] = $dbr->makeList(array('oi_name' => $base, 'oi_archive_name' => $name), LIST_AND);
         } else {
             if ($verbose) {
                 $this->output("Checking current file {$name}\n");
             }
             $imgIN[] = $name;
         }
     }
     $res = $dbr->query($dbr->unionQueries(array($dbr->selectSQLText('image', array('name' => 'img_name'), array('img_name' => $imgIN)), $dbr->selectSQLText('oldimage', array('name' => 'oi_archive_name'), $dbr->makeList($oiWheres, LIST_OR))), true), __METHOD__);
     $namesFound = array();
     foreach ($res as $row) {
         $namesFound[] = $row->name;
     }
     $namesOrphans = array_diff($names, $namesFound);
     foreach ($namesOrphans as $name) {
         // Print name and public URL to ease recovery
         if (strpos($name, '!') !== false) {
             list(, $base) = explode('!', $name);
             // <TS_MW>!<img_name>
             $file = $repo->newFromArchiveName(Title::makeTitle(NS_FILE, $base), $name);
         } else {
             $file = $repo->newFile($name);
         }
         $this->output($name . "\n" . $file->getUrl() . "\n\n");
     }
 }
 protected function purgeFromArchiveTable(LocalRepo $repo, LocalFile $file)
 {
     $dbr = $repo->getSlaveDB();
     $res = $dbr->select('filearchive', array('fa_archive_name'), array('fa_name' => $file->getName()), __METHOD__);
     foreach ($res as $row) {
         if ($row->fa_archive_name === null) {
             // Was not an old version (current version names checked already)
             continue;
         }
         $ofile = $repo->newFromArchiveName($file->getTitle(), $row->fa_archive_name);
         // If there is an orphaned storage file still there...delete it
         if (!$file->exists() && $repo->fileExists($ofile->getPath())) {
             $dpath = $this->getDeletedPath($repo, $ofile);
             if ($repo->fileExists($dpath)) {
                 // Sanity check to avoid data loss
                 $repo->getBackend()->delete(array('src' => $ofile->getPath()));
                 $this->output("Deleted orphan file: {$ofile->getPath()}.\n");
             } else {
                 $this->error("File was not deleted: {$ofile->getPath()}.\n");
             }
         }
         $file->purgeOldThumbnails($row->fa_archive_name);
     }
 }