Merge "filebackend: cleaned up the FileBackend constructor"
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>
Tue, 3 Dec 2013 20:22:10 +0000 (20:22 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Tue, 3 Dec 2013 20:22:10 +0000 (20:22 +0000)
1  2 
includes/filebackend/FileBackend.php
tests/phpunit/includes/media/SVGTest.php

   * For legacy reasons, the FSFileBackend class allows manually setting the paths of
   * containers to ones that do not respect the "wiki ID".
   *
 - * In key/value stores, the container is the only hierarchy (the rest is emulated).
 + * In key/value (object) stores, containers are the only hierarchy (the rest is emulated).
   * FS-based backends are somewhat more restrictive due to the existence of real
   * directory files; a regular file cannot have the same name as a directory. Other
   * backends with virtual directories may not have this limitation. Callers should
   * store files in such a way that no files and directories are under the same path.
   *
 + * In general, this class allows for callers to access storage through the same
 + * interface, without regard to the underlying storage system. However, calling code
 + * must follow certain patterns and be aware of certain things to ensure compatibility:
 + *   - a) Always call prepare() on the parent directory before trying to put a file there;
 + *        key/value stores only need the container to exist first, but filesystems need
 + *        all the parent directories to exist first (prepare() is aware of all this)
 + *   - b) Always call clean() on a directory when it might become empty to avoid empty
 + *        directory buildup on filesystems; key/value stores never have empty directories,
 + *        so doing this helps preserve consistency in both cases
 + *   - c) Likewise, do not rely on the existence of empty directories for anything;
 + *        calling directoryExists() on a path that prepare() was previously called on
 + *        will return false for key/value stores if there are no files under that path
 + *   - d) Never alter the resulting FSFile returned from getLocalReference(), as it could
 + *        either be a copy of the source file in /tmp or the original source file itself
 + *   - e) Use a file layout that results in never attempting to store files over directories
 + *        or directories over files; key/value stores allow this but filesystems do not
 + *   - f) Use ASCII file names (e.g. base32, IDs, hashes) to avoid Unicode issues in Windows
 + *   - g) Do not assume that move operations are atomic (difficult with key/value stores)
 + *   - h) Do not assume that file stat or read operations always have immediate consistency;
 + *        various methods have a "latest" flag that should always be used if up-to-date
 + *        information is required (this trades performance for correctness as needed)
 + *   - i) Do not assume that directory listings have immediate consistency
 + *
   * Methods of subclasses should avoid throwing exceptions at all costs.
   * As a corollary, external dependencies should be kept to a minimum.
   *
@@@ -83,7 -60,7 +83,7 @@@
   * @since 1.19
   */
  abstract class FileBackend {
 -      /** @var  string Unique backend name */
 +      /** @var string Unique backend name */
        protected $name;
  
        /** @var string Unique wiki name */
         *                   This name should not be changed after use (e.g. with journaling).
         *                   Note that the name is *not* used in actual container names.
         *   - wikiId      : Prefix to container names that is unique to this backend.
-        *                   If not provided, this defaults to the current wiki ID.
         *                   It should only consist of alphanumberic, '-', and '_' characters.
         *                   This ID is what avoids collisions if multiple logical backends
         *                   use the same storage system, so this should be set carefully.
-        *   - lockManager : Registered name of a file lock manager to use.
-        *   - fileJournal : File journal configuration; see FileJournal::factory().
-        *                   Journals simply log changes to files stored in the backend.
+        *   - lockManager : LockManager object to use for any file locking.
+        *                   If not provided, then no file locking will be enforced.
+        *   - fileJournal : FileJournal object to use for logging changes to files.
+        *                   If not provided, then change journaling will be disabled.
         *   - readOnly    : Write operations are disallowed if this is a non-empty string.
         *                   It should be an explanation for the backend being read-only.
         *   - parallelize : When to do file operations in parallel (when possible).
                if ( !preg_match( '!^[a-zA-Z0-9-_]{1,255}$!', $this->name ) ) {
                        throw new MWException( "Backend name `{$this->name}` is invalid." );
                }
-               $this->wikiId = isset( $config['wikiId'] )
-                       ? $config['wikiId']
-                       : wfWikiID(); // e.g. "my_wiki-en_"
-               $this->lockManager = ( $config['lockManager'] instanceof LockManager )
+               $this->wikiId = $config['wikiId']; // e.g. "my_wiki-en_"
+               $this->lockManager = isset( $config['lockManager'] )
                        ? $config['lockManager']
-                       : LockManagerGroup::singleton( $this->wikiId )->get( $config['lockManager'] );
+                       : new NullLockManager( array() );
                $this->fileJournal = isset( $config['fileJournal'] )
-                       ? ( ( $config['fileJournal'] instanceof FileJournal )
-                               ? $config['fileJournal']
-                               : FileJournal::factory( $config['fileJournal'], $this->name ) )
+                       ? $config['fileJournal']
                        : FileJournal::factory( array( 'class' => 'NullFileJournal' ), $this->name );
                $this->readOnly = isset( $config['readOnly'] )
                        ? (string)$config['readOnly']
@@@ -1,6 -1,5 +1,6 @@@
  <?php
 -class SVGTest extends MediaWikiTestCase {
 +
 +class SvgTest extends MediaWikiTestCase {
  
        protected function setUp() {
                parent::setUp();
@@@ -11,7 -10,7 +11,7 @@@
  
                $this->backend = new FSFileBackend( array(
                        'name' => 'localtesting',
-                       'lockManager' => 'nullLockManager',
+                       'wikiId' => wfWikiId(),
                        'containerPaths' => array( 'data' => $this->filePath )
                ) );
                $this->repo = new FSRepo( array(
@@@ -20,7 -19,7 +20,7 @@@
                        'backend' => $this->backend
                ) );
  
 -              $this->handler = new SVGHandler;
 +              $this->handler = new SvgHandler;
        }
  
        /**