r104366 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r104365‎ | r104366 | r104367 >
Date:21:48, 27 November 2011
Author:aaron
Status:deferred
Tags:
Comment:
* Renamed resolveVirtualPath() -> resolveStoragePath()
* Added splitStoragePath() function
* Renamed storagePathsToLock() -> storagePathsUsed()
* Added FileBackendGroup class to handle registration
* Made File::getTimestamp() use FileBackend::getFileTimestamp()
* Replaced unlink() in LocalFile::cleanupDeletedBatch()
Modified paths:
  • /branches/FileBackend/phase3/includes/AutoLoader.php (modified) (history)
  • /branches/FileBackend/phase3/includes/filerepo/FileRepo.php (modified) (history)
  • /branches/FileBackend/phase3/includes/filerepo/LocalRepo.php (modified) (history)
  • /branches/FileBackend/phase3/includes/filerepo/backend/FSFileBackend.php (modified) (history)
  • /branches/FileBackend/phase3/includes/filerepo/backend/FileBackend.php (modified) (history)
  • /branches/FileBackend/phase3/includes/filerepo/backend/FileBackendGroup.php (added) (history)
  • /branches/FileBackend/phase3/includes/filerepo/backend/FileBackendMultiWrite.php (modified) (history)
  • /branches/FileBackend/phase3/includes/filerepo/backend/FileOp.php (modified) (history)
  • /branches/FileBackend/phase3/includes/filerepo/file/File.php (modified) (history)

Diff [purge]

Index: branches/FileBackend/phase3/includes/filerepo/file/File.php
@@ -835,10 +835,10 @@
836836 global $wgStylePath, $wgStyleDirectory;
837837
838838 $try = array( 'fileicon-' . $this->getExtension() . '.png', 'fileicon.png' );
839 - foreach( $try as $icon ) {
 839+ foreach ( $try as $icon ) {
840840 $path = '/common/images/icons/' . $icon;
841841 $filepath = $wgStyleDirectory . $path;
842 - if( file_exists( $filepath ) ) {
 842+ if ( file_exists( $filepath ) ) { // always FS
843843 return new ThumbnailImage( $this, $wgStylePath . $path, 120, 120 );
844844 }
845845 }
@@ -1450,17 +1450,13 @@
14511451 }
14521452
14531453 /**
1454 - * Get the 14-character timestamp of the file upload, or false if
1455 - * it doesn't exist
 1454+ * Get the 14-character timestamp of the file upload
14561455 *
1457 - * @return string
 1456+ * @return string|false TS_MW timestamp or false on failure
14581457 */
14591458 function getTimestamp() {
1460 - $path = $this->getPath();
1461 - if ( !$this->repo->fileExists( $path ) ) {
1462 - return false;
1463 - }
1464 - return wfTimestamp( TS_MW, filemtime( $path ) );
 1459+ $this->assertRepoDefined();
 1460+ return $this->repo->getBackend()->getFileTimestamp( $this->getPath() );
14651461 }
14661462
14671463 /**
Index: branches/FileBackend/phase3/includes/filerepo/LocalRepo.php
@@ -56,6 +56,7 @@
5757 * @return FileRepoStatus
5858 */
5959 function cleanupDeletedBatch( $storageKeys ) {
 60+ $backend = $this->backend; // convenience
6061 $root = $this->getZonePath( 'deleted' );
6162 $dbw = $this->getMasterDB();
6263 $status = $this->newGood();
@@ -70,10 +71,8 @@
7172 $hidden = $this->hiddenFileHasKey( $key, 'lock' );
7273 if ( !$deleted && !$hidden ) { // not in use now
7374 wfDebug( __METHOD__ . ": deleting $key\n" );
74 - wfSuppressWarnings();
75 - $unlink = unlink( $path );
76 - wfRestoreWarnings();
77 - if ( !$unlink ) {
 75+ $op = array( 'operation' => 'delete', 'source' => $path );
 76+ if ( !$backend->doOperations( array( $op ) )->isOK() ) {
7877 $status->error( 'undelete-cleanup-error', $path );
7978 $status->failCount++;
8079 }
Index: branches/FileBackend/phase3/includes/filerepo/backend/FileBackendMultiWrite.php
@@ -81,7 +81,7 @@
8282 // locks two or three times (depending on the number of backends).
8383 if ( $index == 0 ) {
8484 foreach ( $performOps as $index => $fileOp ) {
85 - $filesToLock = array_merge( $filesToLock, $fileOp->storagePathsToLock() );
 85+ $filesToLock = array_merge( $filesToLock, $fileOp->storagePathsUsed() );
8686 }
8787 }
8888 }
Index: branches/FileBackend/phase3/includes/filerepo/backend/FileOp.php
@@ -117,7 +117,7 @@
118118 *
119119 * @return Array
120120 */
121 - public function storagePathsToLock() {
 121+ public function storagePathsUsed() {
122122 return array();
123123 }
124124
@@ -301,7 +301,7 @@
302302 return md5_file( $this->params['source'] );
303303 }
304304
305 - function storagePathsToLock() {
 305+ function storagePathsUsed() {
306306 return array( $this->params['dest'] );
307307 }
308308 }
@@ -347,7 +347,7 @@
348348 return md5( $this->params['content'] );
349349 }
350350
351 - function storagePathsToLock() {
 351+ function storagePathsUsed() {
352352 return array( $this->params['dest'] );
353353 }
354354 }
@@ -400,7 +400,7 @@
401401 return $this->getFileMD5( $this->params['source'] );
402402 }
403403
404 - function storagePathsToLock() {
 404+ function storagePathsUsed() {
405405 return array( $this->params['source'], $this->params['dest'] );
406406 }
407407 }
@@ -485,7 +485,7 @@
486486 return $this->getFileMD5( $this->params['source'] );
487487 }
488488
489 - function storagePathsToLock() {
 489+ function storagePathsUsed() {
490490 return array( $this->params['source'], $this->params['dest'] );
491491 }
492492 }
@@ -531,7 +531,7 @@
532532 return null; // defer this until we finish building the new file
533533 }
534534
535 - function storagePathsToLock() {
 535+ function storagePathsUsed() {
536536 return array_merge( $this->params['sources'], $this->params['dest'] );
537537 }
538538 }
@@ -569,7 +569,7 @@
570570 return $status;
571571 }
572572
573 - function storagePathsToLock() {
 573+ function storagePathsUsed() {
574574 return array( $this->params['source'] );
575575 }
576576 }
Index: branches/FileBackend/phase3/includes/filerepo/backend/FSFileBackend.php
@@ -37,7 +37,7 @@
3838 function store( array $params ) {
3939 $status = Status::newGood();
4040
41 - list( $c, $dest ) = $this->resolveVirtualPath( $params['dest'] );
 41+ list( $c, $dest ) = $this->resolveStoragePath( $params['dest'] );
4242 if ( $dest === null ) {
4343 $status->fatal( 'backend-fail-invalidpath', $params['dest'] );
4444 return $status;
@@ -87,12 +87,12 @@
8888 function move( array $params ) {
8989 $status = Status::newGood();
9090
91 - list( $c, $source ) = $this->resolveVirtualPath( $params['source'] );
 91+ list( $c, $source ) = $this->resolveStoragePath( $params['source'] );
9292 if ( $source === null ) {
9393 $status->fatal( 'backend-fail-invalidpath', $params['source'] );
9494 return $status;
9595 }
96 - list( $c, $dest ) = $this->resolveVirtualPath( $params['dest'] );
 96+ list( $c, $dest ) = $this->resolveStoragePath( $params['dest'] );
9797 if ( $dest === null ) {
9898 $status->fatal( 'backend-fail-invalidpath', $params['dest'] );
9999 return $status;
@@ -135,7 +135,7 @@
136136 function delete( array $params ) {
137137 $status = Status::newGood();
138138
139 - list( $c, $source ) = $this->resolveVirtualPath( $params['source'] );
 139+ list( $c, $source ) = $this->resolveStoragePath( $params['source'] );
140140 if ( $source === null ) {
141141 $status->fatal( 'backend-fail-invalidpath', $params['source'] );
142142 return $status;
@@ -162,7 +162,7 @@
163163 function concatenate( array $params ) {
164164 $status = Status::newGood();
165165
166 - list( $c, $dest ) = $this->resolveVirtualPath( $params['dest'] );
 166+ list( $c, $dest ) = $this->resolveStoragePath( $params['dest'] );
167167 if ( $dest === null ) {
168168 $status->fatal( 'backend-fail-invalidpath', $params['dest'] );
169169 return $status;
@@ -193,7 +193,7 @@
194194 return $status;
195195 }
196196 foreach ( $params['sources'] as $virtualSource ) {
197 - list( $c, $source ) = $this->resolveVirtualPath( $virtualSource );
 197+ list( $c, $source ) = $this->resolveStoragePath( $virtualSource );
198198 if ( $source === null ) {
199199 $status->fatal( 'backend-fail-invalidpath', $virtualSource );
200200 return $status;
@@ -262,7 +262,7 @@
263263 function create( array $params ) {
264264 $status = Status::newGood();
265265
266 - list( $c, $dest ) = $this->resolveVirtualPath( $params['dest'] );
 266+ list( $c, $dest ) = $this->resolveStoragePath( $params['dest'] );
267267 if ( $dest === null ) {
268268 $status->fatal( 'backend-fail-invalidpath', $params['dest'] );
269269 return $status;
@@ -303,7 +303,7 @@
304304
305305 function prepare( array $params ) {
306306 $status = Status::newGood();
307 - list( $c, $dir ) = $this->resolveVirtualPath( $params['directory'] );
 307+ list( $c, $dir ) = $this->resolveStoragePath( $params['directory'] );
308308 if ( $dir === null ) {
309309 $status->fatal( 'backend-fail-invalidpath', $params['directory'] );
310310 return $status; // invalid storage path
@@ -323,7 +323,7 @@
324324
325325 function secure( array $params ) {
326326 $status = Status::newGood();
327 - list( $c, $dir ) = $this->resolveVirtualPath( $params['directory'] );
 327+ list( $c, $dir ) = $this->resolveStoragePath( $params['directory'] );
328328 if ( $dir === null ) {
329329 $status->fatal( 'backend-fail-invalidpath', $params['directory'] );
330330 return $status; // invalid storage path
@@ -356,7 +356,7 @@
357357 }
358358
359359 function fileExists( array $params ) {
360 - list( $c, $source ) = $this->resolveVirtualPath( $params['source'] );
 360+ list( $c, $source ) = $this->resolveStoragePath( $params['source'] );
361361 if ( $source === null ) {
362362 return false; // invalid storage path
363363 }
@@ -368,7 +368,7 @@
369369 }
370370
371371 function getFileHash( array $params ) {
372 - list( $c, $source ) = $this->resolveVirtualPath( $params['source'] );
 372+ list( $c, $source ) = $this->resolveStoragePath( $params['source'] );
373373 if ( $source === null ) {
374374 return false; // invalid storage path
375375 }
@@ -376,7 +376,7 @@
377377 }
378378
379379 function getFileTimestamp( array $params ) {
380 - list( $c, $source ) = $this->resolveVirtualPath( $params['source'] );
 380+ list( $c, $source ) = $this->resolveStoragePath( $params['source'] );
381381 if ( $source === null ) {
382382 return false; // invalid storage path
383383 }
@@ -385,7 +385,7 @@
386386 }
387387
388388 function getFileProps( array $params ) {
389 - list( $c, $source ) = $this->resolveVirtualPath( $params['source'] );
 389+ list( $c, $source ) = $this->resolveStoragePath( $params['source'] );
390390 if ( $source === null ) {
391391 return FSFile::placeholderProps(); // invalid storage path
392392 }
@@ -394,7 +394,7 @@
395395 }
396396
397397 function getFileList( array $params ) {
398 - list( $c, $dir ) = $this->resolveVirtualPath( $params['directory'] );
 398+ list( $c, $dir ) = $this->resolveStoragePath( $params['directory'] );
399399 if ( $dir === null ) { // invalid storage path
400400 return array(); // empty result
401401 }
@@ -404,7 +404,7 @@
405405 function streamFile( array $params ) {
406406 $status = Status::newGood();
407407
408 - list( $c, $source ) = $this->resolveVirtualPath( $params['source'] );
 408+ list( $c, $source ) = $this->resolveStoragePath( $params['source'] );
409409 if ( $source === null ) {
410410 $status->fatal( 'backend-fail-invalidpath', $params['source'] );
411411 return $status;
@@ -420,7 +420,7 @@
421421 }
422422
423423 function getLocalCopy( array $params ) {
424 - list( $c, $source ) = $this->resolveVirtualPath( $params['source'] );
 424+ list( $c, $source ) = $this->resolveStoragePath( $params['source'] );
425425 if ( $source === null ) {
426426 return null;
427427 }
Index: branches/FileBackend/phase3/includes/filerepo/backend/FileBackendGroup.php
@@ -0,0 +1,88 @@
 2+<?php
 3+/**
 4+ * @file
 5+ * @ingroup FileRepo
 6+ * @ingroup FileBackend
 7+ */
 8+
 9+/**
 10+ * Class to handle file backend registration
 11+ *
 12+ * @ingroup FileRepo
 13+ * @ingroup FileBackend
 14+ */
 15+class FileBackendGroup {
 16+ protected static $instance = null;
 17+
 18+ /** @var Array of (name => ('class' =>, 'config' =>, 'instance' =>)) */
 19+ protected $backends = array();
 20+
 21+ protected function __construct() {}
 22+ protected function __clone() {}
 23+
 24+ public static function singleton() {
 25+ if ( self::$instance == null ) {
 26+ self::$instance = new self();
 27+ }
 28+ return self::$instance;
 29+ }
 30+
 31+ /**
 32+ * Register a file backend from configuration
 33+ *
 34+ * @param $config Array
 35+ * @return void
 36+ * @throws MWException
 37+ */
 38+ public function register( array $config ) {
 39+ if ( !isset( $config['name'] ) ) {
 40+ throw new MWException( "Cannot register a backend with no name." );
 41+ }
 42+ $name = $config['name'];
 43+ if ( !isset( $config['class'] ) ) {
 44+ throw new MWException( "Cannot register backend `{$name}` with no class." );
 45+ }
 46+ $class = $config['class'];
 47+
 48+ unset( $config['class'] ); // backend won't need this
 49+ $this->backends[$name] = array(
 50+ 'class' => $class,
 51+ 'config' => $config,
 52+ 'instance' => null
 53+ );
 54+ }
 55+
 56+ /**
 57+ * Get the backend object with a given name
 58+ *
 59+ * @param $name string
 60+ * @return FileBackendBase
 61+ * @throws MWException
 62+ */
 63+ public function getBackend( $name ) {
 64+ if ( !isset( $this->backends[$name] ) ) {
 65+ throw new MWException( "No backend defined with the name `$name`." );
 66+ }
 67+ // Lazy-load the actual backend instance
 68+ if ( !isset( $this->backends[$name]['instance'] ) ) {
 69+ $class = $this->backends[$name]['class'];
 70+ $config = $this->backends[$name]['config'];
 71+ $this->backends[$name]['instance'] = new $class( $config );
 72+ }
 73+ return $this->backends[$name]['instance'];
 74+ }
 75+
 76+ /**
 77+ * Get an appropriate backend object from a storage path
 78+ *
 79+ * @param $storagePath string
 80+ * @return FileBackendBase|null Backend or null on failure
 81+ */
 82+ public function backendFromPath( $storagePath ) {
 83+ list( $backend, $c, $p ) = FileBackend::splitStoragePath( $storagePath );
 84+ if ( $backend !== null && isset( $this->backends[$backend] ) ) {
 85+ return $this->backends[$backend];
 86+ }
 87+ return null;
 88+ }
 89+}
Property changes on: branches/FileBackend/phase3/includes/filerepo/backend/FileBackendGroup.php
___________________________________________________________________
Added: svn:eol-style
190 + native
Index: branches/FileBackend/phase3/includes/filerepo/backend/FileBackend.php
@@ -392,7 +392,7 @@
393393 // Build up a list of files to lock...
394394 $filesToLock = array();
395395 foreach ( $performOps as $index => $fileOp ) {
396 - $filesToLock = array_merge( $filesToLock, $fileOp->storagePathsToLock() );
 396+ $filesToLock = array_merge( $filesToLock, $fileOp->storagePathsUsed() );
397397 }
398398
399399 // Try to lock those files...
@@ -481,21 +481,37 @@
482482
483483 /**
484484 * Split a storage path (e.g. "mwstore://backend/container/path/to/object")
485 - * into a container name and a full object name within that container.
 485+ * into a backend name, a container name, and a relative object path.
486486 *
487487 * @param $storagePath string
 488+ * @return Array (backend, container, rel object) or (null, null, null)
 489+ */
 490+ final public static function splitStoragePath( $storagePath ) {
 491+ if ( self::isStoragePath( $storagePath ) ) {
 492+ // Note: strlen( 'mwstore://' ) = 10
 493+ $parts = explode( '/', substr( $storagePath, 10 ), 3 );
 494+ if ( count( $parts ) == 3 ) {
 495+ return $parts;
 496+ }
 497+ }
 498+ return array( null, null, null );
 499+ }
 500+
 501+ /**
 502+ * Split a storage path (e.g. "mwstore://backend/container/path/to/object")
 503+ * into a backend name, a container name and an internal relative object name.
 504+ *
 505+ * @param $storagePath string
488506 * @return Array (container, object name) or (null, null) if path is invalid
489507 */
490 - final protected function resolveVirtualPath( $storagePath ) {
491 - if ( strpos( $storagePath, 'mwstore://' ) === 0 ) {
492 - $m = explode( '/', substr( $storagePath, 10 ), 3 );
493 - if ( count( $m ) == 3 ) {
494 - list( $backend, $container, $relPath ) = $m;
495 - if ( $backend === $this->name ) { // sanity
496 - $relPath = $this->resolveContainerPath( $container, $relPath );
497 - if ( $relPath !== null ) {
498 - return array( $container, $relPath ); // (container, path)
499 - }
 508+ final protected function resolveStoragePath( $storagePath ) {
 509+ $parts = self::splitStoragePath( $storagePath );
 510+ if ( $parts[0] !== null ) { // either all null or all not null
 511+ list( $backend, $container, $relPath ) = $parts;
 512+ if ( $backend === $this->name ) { // sanity
 513+ $relPath = $this->resolveContainerPath( $container, $relPath );
 514+ if ( $relPath !== null ) {
 515+ return array( $container, $relPath ); // (container, path)
500516 }
501517 }
502518 }
Index: branches/FileBackend/phase3/includes/filerepo/FileRepo.php
@@ -753,7 +753,7 @@
754754 // Cleanup for disk source files...
755755 foreach ( $sourceFSFilesToDelete as $file ) {
756756 wfSuppressWarnings();
757 - unlink( $file );
 757+ unlink( $file ); // FS cleanup
758758 wfRestoreWarnings();
759759 }
760760
@@ -802,7 +802,7 @@
803803 // Cleanup for disk source files...
804804 foreach ( $sourceFSFilesToDelete as $file ) {
805805 wfSuppressWarnings();
806 - unlink( $path );
 806+ unlink( $path ); // FS cleanup
807807 wfRestoreWarnings();
808808 }
809809 }
@@ -964,7 +964,7 @@
965965 // Cleanup for disk source files...
966966 foreach ( $sourceFSFilesToDelete as $file ) {
967967 wfSuppressWarnings();
968 - unlink( $file );
 968+ unlink( $file ); // FS cleanup
969969 wfRestoreWarnings();
970970 }
971971
@@ -1005,9 +1005,9 @@
10061006 $result[$key] = $this->backend->fileExists( array( 'source' => $file ) );
10071007 } else {
10081008 if ( $flags & self::FILES_ONLY ) {
1009 - $result[$key] = is_file( $file );
 1009+ $result[$key] = is_file( $file ); // FS only
10101010 } else {
1011 - $result[$key] = file_exists( $file ); // @TODO: kill this
 1011+ $result[$key] = file_exists( $file ); // FS only
10121012 }
10131013 }
10141014 }
Index: branches/FileBackend/phase3/includes/AutoLoader.php
@@ -484,6 +484,7 @@
485485 'TempFSFile' => 'includes/filerepo/file/TempFSFile.php',
486486
487487 # includes/filerepo/backend
 488+ 'FileBackendGroup' => 'includes/filerepo/backend/FileBackendGroup',
488489 'FileBackendBase' => 'includes/filerepo/backend/FileBackend.php',
489490 'FileBackend' => 'includes/filerepo/backend/FileBackend.php',
490491 'FileBackendMultiWrite' => 'includes/filerepo/backend/FileBackendMultiWrite.php',

Status & tagging log