r104197 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r104196‎ | r104197 | r104198 >
Date:21:20, 24 November 2011
Author:aaron
Status:deferred
Tags:
Comment:
* Moved several functions from FileBackendBase to FileBackend class. This simplifies FileBackendMultiWrite. Callers outside of backend code should be using doOperations().
* Removed some 'overwriteSame' handling in FSFileBackend per r104155.
* Removed left over 'extends' from CreateFileOp.
* Made DBFileLockManager resistent to server restarts and fixed $this->locksHeld bug in doUnlock().
* Various small cleanups and fixes.
Modified paths:
  • /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/FileBackendMultiWrite.php (modified) (history)
  • /branches/FileBackend/phase3/includes/filerepo/backend/FileLockManager.php (modified) (history)
  • /branches/FileBackend/phase3/includes/filerepo/backend/FileOp.php (modified) (history)

Diff [purge]

Index: branches/FileBackend/phase3/includes/filerepo/backend/FileBackendMultiWrite.php
@@ -27,6 +27,8 @@
2828 /** @var Array List of FileBackend object informations */
2929 protected $fileBackendsInfo = array(); // array (backend index => array of settings)
3030
 31+ protected $masterIndex; // index of master backend
 32+
3133 /**
3234 * Construct a proxy backend that consist of several internal backends.
3335 * $config contains:
@@ -39,10 +41,9 @@
4042 * @param $config Array
4143 */
4244 public function __construct( array $config ) {
43 - $this->name = $config['name'];
44 - $this->lockManager = $config['lockManger'];
 45+ parent::__construct( $config );
4546
46 - $hasMaster = false;
 47+ $this->masterIndex = -1;
4748 foreach ( $config['backends'] as $index => $info ) {
4849 list( $backend, $settings ) = $info;
4950 $this->fileBackends[$index] = $backend;
@@ -51,13 +52,13 @@
5253 // Apply custom backend settings to defaults
5354 $this->fileBackendsInfo[$index] = $info + $defaults;
5455 if ( $info['isMaster'] ) {
55 - if ( $hasMaster ) {
 56+ if ( $this->masterIndex >= 0 ) {
5657 throw new MWException( 'More than one master backend defined.' );
5758 }
58 - $hasMaster = true;
 59+ $this->masterIndex = $index;
5960 }
6061 }
61 - if ( !$hasMaster ) {
 62+ if ( $this->masterIndex < 0 ) { // need backends and must have a master
6263 throw new MWException( 'No master backend defined.' );
6364 }
6465 }
@@ -127,40 +128,6 @@
128129 return $status;
129130 }
130131
131 - function store( array $params ) {
132 - $op = array( 'operation' => 'store' ) + $params;
133 - return $this->doOperation( array( $op ) );
134 - }
135 -
136 - function copy( array $params ) {
137 - $op = array( 'operation' => 'copy' ) + $params;
138 - return $this->doOperation( array( $op ) );
139 - }
140 -
141 - function canMove( array $params ) {
142 - return true; // this is irrelevant
143 - }
144 -
145 - function move( array $params ) {
146 - $op = array( 'operation' => 'move' ) + $params;
147 - return $this->doOperation( array( $op ) );
148 - }
149 -
150 - function delete( array $params ){
151 - $op = array( 'operation' => 'delete' ) + $params;
152 - return $this->doOperation( array( $op ) );
153 - }
154 -
155 - function concatenate( array $params ){
156 - $op = array( 'operation' => 'concatenate' ) + $params;
157 - return $this->doOperation( array( $op ) );
158 - }
159 -
160 - function create( array $params ) {
161 - $op = array( 'operation' => 'create' ) + $params;
162 - return $this->doOperation( array( $op ) );
163 - }
164 -
165132 function prepare( array $params ) {
166133 $status = Status::newGood();
167134 foreach ( $this->backends as $backend ) {
@@ -179,23 +146,13 @@
180147 }
181148
182149 function getFileHash( array $params ) {
183 - foreach ( $this->backends as $backend ) {
184 - // Skip non-master for consistent hash formats
185 - if ( $this->fileBackendsInfo[$index]['isMaster'] ) {
186 - return $backend->getFileHash( $params );
187 - }
188 - }
189 - return false;
 150+ // Skip non-master for consistent hash formats
 151+ return $this->backends[$this->masterIndex]->getFileHash( $params );
190152 }
191153
192154 function getHashType() {
193 - foreach ( $this->backends as $backend ) {
194 - // Skip non-master for consistent hash formats
195 - if ( $this->fileBackendsInfo[$index]['isMaster'] ) {
196 - return $backend->getHashType();
197 - }
198 - }
199 - return null; // shouldn't happen
 155+ // Skip non-master for consistent hash formats
 156+ return $this->backends[$this->masterIndex]->getHashType();
200157 }
201158
202159 function getFileProps( array $params ) {
@@ -209,9 +166,6 @@
210167 }
211168
212169 function streamFile( array $params ) {
213 - if ( !count( $this->backends ) ) {
214 - return Status::newFatal( "No file backends are defined." );
215 - }
216170 foreach ( $this->backends as $backend ) {
217171 $status = $backend->streamFile( $params );
218172 if ( $status->isOK() ) {
@@ -220,7 +174,7 @@
221175 return $status; // died mid-stream...so this is already fubar
222176 }
223177 }
224 - return Status::newFatal( "Could not stream file {$params['source']}." );
 178+ return Status::newFatal( 'backend-fail-stream', $params['source'] );
225179 }
226180
227181 function getLocalCopy( array $params ) {
Index: branches/FileBackend/phase3/includes/filerepo/backend/FileOp.php
@@ -181,8 +181,7 @@
182182 }
183183 // Give an error if the files are not identical
184184 if ( $shash !== $dhash ) {
185 - $status->fatal( 'backend-fail-notsame',
186 - $this->params['source'], $this->params['dest'] );
 185+ $status->fatal( 'backend-fail-notsame', $this->params['dest'] );
187186 }
188187 return $status; // do nothing; either OK or bad status
189188 }
@@ -361,7 +360,7 @@
362361 * overwriteDest : do nothing and pass if an identical file exists at destination
363362 * overwriteSame : override any existing file at destination
364363 */
365 -class CopyFileOp extends StoreFileOp {
 364+class CopyFileOp extends FileOp {
366365 function doPrecheck() {
367366 $status = Status::newGood();
368367 // Check if the source files exists on disk
@@ -507,11 +506,6 @@
508507 }
509508
510509 function doAttempt() {
511 - // Create a backup copy of any file that exists at destination
512 - $status = $this->checkAndBackupDest();
513 - if ( !$status->isOK() ) {
514 - return $status;
515 - }
516510 // Concatenate the file at the destination
517511 $status = $this->backend->concatenate( $this->params );
518512 return $status;
Index: branches/FileBackend/phase3/includes/filerepo/backend/FSFileBackend.php
@@ -45,11 +45,6 @@
4646 $status->fatal( 'backend-fail-delete', $param['dest'] );
4747 return $status;
4848 }
49 - } elseif ( isset( $params['overwriteSame'] ) ) {
50 - if ( !$this->filesAreSame( $params['source'], $dest ) ) {
51 - $status->fatal( 'backend-fail-notsame', $params['source'], $params['dest'] );
52 - }
53 - return $status; // do nothing; either OK or bad status
5449 } else {
5550 $status->fatal( 'backend-fail-alreadyexists', $params['dest'] );
5651 return $status;
@@ -106,11 +101,6 @@
107102 return $status;
108103 }
109104 }
110 - } elseif ( isset( $params['overwriteSame'] ) ) {
111 - if ( !$this->filesAreSame( $source, $dest ) ) {
112 - $status->fatal( 'backend-fail-notsame', $params['source'], $params['dest'] );
113 - }
114 - return $status; // do nothing; either OK or bad status
115105 } else {
116106 $status->fatal( 'backend-fail-alreadyexists', $params['dest'] );
117107 return $status;
@@ -234,7 +224,7 @@
235225 }
236226 } elseif ( isset( $params['overwriteSame'] ) ) {
237227 if ( !$this->filesAreSame( $tmpPath, $dest ) ) {
238 - $status->fatal( 'backend-fail-notsame', $tmpPath, $params['dest'] );
 228+ $status->fatal( 'backend-fail-notsame', $params['dest'] );
239229 }
240230 return $status; // do nothing; either OK or bad status
241231 }
@@ -276,11 +266,6 @@
277267 $status->fatal( 'backend-fail-delete', $param['dest'] );
278268 return $status;
279269 }
280 - } elseif ( isset( $params['overwriteSame'] ) ) {
281 - if ( !$this->fileAndDataAreSame( $dest, $params['content'] ) ) {
282 - $status->fatal( 'backend-fail-notsame-raw', $params['dest'] );
283 - }
284 - return $status; // do nothing; either OK or bad status
285270 } else {
286271 $status->fatal( 'backend-fail-alreadyexists', $params['dest'] );
287272 return $status;
Index: branches/FileBackend/phase3/includes/filerepo/backend/FileLockManager.php
@@ -214,13 +214,13 @@
215215 * This is meant for multi-wiki systems that may share share files.
216216 * One or several database servers are set up having a `file_locking`
217217 * table with one field, fl_key, the PRIMARY KEY. The table engine should
218 - * have row-level locking. All lock requests for a resource, identified by
219 - * a hash string, will map to one bucket. Each bucket maps to a single server.
 218+ * have row-level locking. All lock requests for a resource, identified
 219+ * by a hash string, will map to one bucket.
220220 *
221 - * Each bucket can also have several fallback servers.
222 - * Fallback servers get the same lock statements as the primary bucket server.
223 - * This propagation is only best-effort; lock requests will not be blocked just
224 - * because a fallback server cannot be contacted.
 221+ * Each bucket maps to one or several pier servers.
 222+ * All pier servers must agree to a lock in order for it to be acquired.
 223+ * As long as one pier server is up, lock requests will not be blocked
 224+ * just because another pier server cannot be contacted.
225225 *
226226 * For performance, deadlock detection should be disabled and a small
227227 * lock-wait timeout should be set via server config. In innoDB, this can
@@ -228,19 +228,31 @@
229229 */
230230 class DBFileLockManager extends FileLockManager {
231231 /** @var Array Map of bucket indexes to server names */
232 - protected $serverMap = array(); // (index => (server1,server2,...))
 232+ protected $serverMap; // (index => (server1, server2, ...))
 233+ protected $webTimeout; // integer number of seconds
 234+ protected $cliTimeout; // integer number of seconds
 235+ protected $resetDelay; // integer number of seconds
233236 /** @var Array Map of (locked key => lock type => 1) */
234237 protected $locksHeld = array();
235 - /** $var Array Map Lock-active database connections (name => Database) */
 238+ /** $var Array Map Lock-active database connections (server name => Database) */
236239 protected $activeConns = array();
237240
238241 /**
239242 * Construct a new instance from configuration.
240243 * $config paramaters include:
241 - * 'serverMap' : Array of no more than 16 consecutive integer keys,
242 - * starting from 0, with a list of servers as values.
243 - * The first server in each list is the main server and
244 - * the others are fallback servers.
 244+ * 'serverMap' : Array of no more than 16 consecutive integer keys,
 245+ * starting from 0, with a list of servers as values.
 246+ * The first server in each list is the main server and
 247+ * the others are pier servers.
 248+ * 'webTimeout' : Connection timeout (seconds) for non-CLI scripts.
 249+ * This tells the DB server how long to wait before giving up
 250+ * and releasing all the locks made in a session transaction.
 251+ * 'cliTimeout' : Connection timeout (seconds) for CLI scripts.
 252+ * This tells the DB server how long to wait before giving up
 253+ * and releasing all the locks made in a session transaction.
 254+ * 'resetDelay' : How long (seconds) to avoid using a DB server after it restarted.
 255+ * This should reflect the highest max_execution_time that a PHP
 256+ * script might use on this wiki. Locks are lost on server restart.
245257 *
246258 * @param Array $config
247259 */
@@ -257,6 +269,19 @@
258270 wfWarn( "No key for bucket $i in serverMap or server list is empty." );
259271 }
260272 }
 273+ if ( !empty( $config['webTimeout'] ) ) { // disallow 0
 274+ $this->webTimeout = $config['webTimeout'];
 275+ } elseif ( ini_get( 'max_execution_time' ) > 0 ) {
 276+ $this->webTimeout = ini_get( 'max_execution_time' );
 277+ } else { // cli?
 278+ $this->webTimeout = 60; // some sane number
 279+ }
 280+ $this->cliTimeout = !empty( $config['cliTimeout'] ) // disallow 0
 281+ ? $config['cliTimeout']
 282+ : 60; // some sane number
 283+ $this->resetDelay = isset( $config['resetDelay'] )
 284+ ? $config['resetDelay']
 285+ : max( $this->cliTimeout, $this->webTimeout );
261286 }
262287
263288 function doLock( array $keys, $type ) {
@@ -284,8 +309,8 @@
285310 foreach ( $keysToLock as $bucket => $keys ) {
286311 // Acquire the locks for this server. Three main cases can happen:
287312 // (a) First server is up; common case
288 - // (b) First server is down but a fallback is up
289 - // (c) First server is down and no fallbacks are up (or none defined)
 313+ // (b) First server is down but a pier is up
 314+ // (c) First server is down and no pier are up (or none defined)
290315 $count = $this->doLockingSelectAll( $bucket, $keys, $type );
291316 if ( $count == -1 ) {
292317 // Resources already locked by another process.
@@ -300,7 +325,7 @@
301326 $status->merge( $this->doUnlock( $lockedKeys, $type ) );
302327 return $status; // error
303328 }
304 - // Record locks as active
 329+ // Record these locks as active
305330 foreach ( $keys as $key ) {
306331 $this->locksHeld[$key][$type] = 1; // locked
307332 }
@@ -326,6 +351,9 @@
327352 }
328353 unset( $this->locksHeld[$key][$lockType] );
329354 }
 355+ if ( !count( $this->locksHeld[$key] ) ) {
 356+ unset( $this->locksHeld[$key] ); // no SH or EX locks left for key
 357+ }
330358 }
331359 }
332360
@@ -354,9 +382,9 @@
355383 # This won't handle the case of server reboots however.
356384 $options = array();
357385 if ( php_sapi_name() == 'cli' ) { // maintenance scripts
358 - $options['connTimeout'] = 60; // some sane amount
 386+ $options['connTimeout'] = $this->cliTimeout;
359387 } else { // web requests
360 - $options['connTimeout'] = ini_get( 'max_execution_time' );
 388+ $options['connTimeout'] = $this->webTimeout;
361389 }
362390 $this->activeConns[$server]->setSessionOptions( $options );
363391 }
@@ -375,9 +403,9 @@
376404
377405 /**
378406 * Attept to acquire a lock on the primary server as well
379 - * as all fallback servers for a bucket. Returns the number
380 - * of servers with locks made or -1 if any of them claimed
381 - * that any of the keys were already locked by another process.
 407+ * as all pier servers for a bucket. Returns the number of
 408+ * servers with locks made or -1 if any of them claimed that
 409+ * any of the keys were already locked by another process.
382410 * This should avoid throwing any exceptions.
383411 *
384412 * @param $bucket integer
@@ -391,12 +419,14 @@
392420 $server = $this->serverMap[$bucket][$i];
393421 try {
394422 $this->doLockingSelect( $server, $keys, $type );
395 - ++$locksMade; // success for this fallback
 423+ if ( $this->checkServerUptime( $server ) ) {
 424+ ++$locksMade; // success for this pier
 425+ }
396426 } catch ( DBError $e ) {
397427 if ( $this->lastErrorIndicatesLocked( $server ) ) {
398428 return -1; // resource locked
399429 }
400 - // oh well; best effort (@TODO: logging?)
 430+ // oh well; logged via wfLogDBError()
401431 }
402432 }
403433 return $locksMade;
@@ -413,7 +443,7 @@
414444 try {
415445 $db->commit(); // finish transaction
416446 } catch ( DBError $e ) {
417 - // oh well; best effort (@TODO: logging?)
 447+ // oh well; best effort
418448 }
419449 }
420450 $this->activeConns = array();
@@ -436,6 +466,22 @@
437467 }
438468
439469 /**
 470+ * Check if the DB server has been up long enough to be safe
 471+ * to use. This is to get around the problems of locks falling
 472+ * off when servers restart.
 473+ *
 474+ * @param $server string
 475+ * @return bool
 476+ */
 477+ protected function checkServerUptime( $server ) {
 478+ if ( isset( $this->activeConns[$server] ) ) { // sanity
 479+ $db = $this->activeConns[$server];
 480+ return ( $db->getServerUptime() >= $this->resetDelay );
 481+ }
 482+ return false;
 483+ }
 484+
 485+ /**
440486 * Get the bucket for lock key.
441487 * This should avoid throwing any exceptions.
442488 *
Index: branches/FileBackend/phase3/includes/filerepo/backend/FileBackend.php
@@ -6,14 +6,16 @@
77
88 /**
99 * Base class for all file backend classes (including multi-write backends).
10 - * This class defines the methods as abstract that must be implemented subclasses.
 10+ * This class defines the methods as abstract that subclasses must implement.
 11+ *
 12+ * Outside callers can assume that all backends will have these functions.
1113 *
1214 * All "storage paths" are of the format "mwstore://backend/container/path".
1315 * The paths use typical file system notation, though any particular backend may
1416 * not actually be using a local filesystem. Therefore, the paths are only virtual.
1517 *
16 - * All functions should avoid throwing exceptions at all costs.
17 - * As a corollary, external dependencies should be kept to a minimal.
 18+ * Methods should avoid throwing exceptions at all costs.
 19+ * As a corollary, external dependencies should be kept to a minimum.
1820 */
1921 abstract class FileBackendBase {
2022 protected $name; // unique backend name
@@ -82,107 +84,26 @@
8385 abstract public function prepare( array $params );
8486
8587 /**
86 - * Store a file into the backend from a file on disk.
 88+ * Check if a file exits at a storage path in the backend.
8789 * Do not call this function from places outside FileBackend and FileOp.
8890 * $params include:
89 - * source : source path on disk
90 - * dest : destination storage path
91 - * overwriteDest : do nothing and pass if an identical file exists at destination
 91+ * source : source storage path
9292 *
9393 * @param Array $params
94 - * @return Status
95 - */
96 - abstract public function store( array $params );
97 -
98 - /**
99 - * Copy a file from one storage path to another in the backend.
100 - * Do not call this function from places outside FileBackend and FileOp.
101 - * $params include:
102 - * source : source storage path
103 - * dest : destination storage path
104 - * overwriteDest : do nothing and pass if an identical file exists at destination
105 - *
106 - * @param Array $params
107 - * @return Status
108 - */
109 - abstract public function copy( array $params );
110 -
111 - /**
112 - * Copy a file from one storage path to another in the backend.
113 - * This can be left as a dummy function as long as hasMove() returns false.
114 - * Do not call this function from places outside FileBackend and FileOp.
115 - * $params include:
116 - * source : source storage path
117 - * dest : destination storage path
118 - * overwriteDest : do nothing and pass if an identical file exists at destination
119 - *
120 - * @param Array $params
121 - * @return Status
122 - */
123 - abstract public function move( array $params );
124 -
125 - /**
126 - * Delete a file at the storage path.
127 - * Do not call this function from places outside FileBackend and FileOp.
128 - * $params include:
129 - * source : source storage path
130 - *
131 - * @param Array $params
132 - * @return Status
133 - */
134 - abstract public function delete( array $params );
135 -
136 - /**
137 - * Combines files from severals storage paths into a new file in the backend.
138 - * Do not call this function from places outside FileBackend and FileOp.
139 - * $params include:
140 - * source : source storage path
141 - * dest : destination storage path
142 - * overwriteDest : do nothing and pass if an identical file exists at destination
143 - * overwriteSame : override any existing file at destination
144 - *
145 - * @param Array $params
146 - * @return Status
147 - */
148 - abstract public function concatenate( array $params );
149 -
150 - /**
151 - * Create a file in the backend with the given contents.
152 - * Do not call this function from places outside FileBackend and FileOp.
153 - * $params include:
154 - * contents : the raw file contents
155 - * dest : destination storage path
156 - * overwriteDest : do nothing and pass if an identical file exists at destination
157 - *
158 - * @param Array $params
159 - * @return Status
160 - */
161 - abstract public function create( array $params );
162 -
163 - /**
164 - * Whether this backend implements move() and is applies to a potential
165 - * move from one storage path to another. No backends hits are required.
166 - * For example, moving objects accross containers may not be supported.
167 - * Do not call this function from places outside FileBackend and FileOp.
168 - * $params include:
169 - * source : source storage path
170 - * dest : destination storage path
171 - *
172 - * @param Array $params
17394 * @return bool
17495 */
175 - abstract public function canMove( array $params );
 96+ abstract public function fileExists( array $params );
17697
17798 /**
178 - * Check if a file exits at a storage path in the backend.
179 - * Do not call this function from places outside FileBackend and FileOp.
 99+ * Get a hash of the file that exists at a storage path in the backend.
 100+ * Typically this will be a SHA-1 hash, MD5 hash, or something similar.
180101 * $params include:
181102 * source : source storage path
182103 *
183104 * @param Array $params
184 - * @return bool
 105+ * @return string|null Gives null if the file does not exist
185106 */
186 - abstract public function fileExists( array $params );
 107+ abstract public function getFileHash( array $params );
187108
188109 /**
189110 * Get the format of the hash that getFileHash() uses
@@ -194,17 +115,6 @@
195116 }
196117
197118 /**
198 - * Get a hash of the file that exists at a storage path in the backend.
199 - * Typically this will be a SHA-1 hash, MD5 hash, or something similar.
200 - * $params include:
201 - * source : source storage path
202 - *
203 - * @param Array $params
204 - * @return string|null Gives null if the file does not exist
205 - */
206 - abstract public function getFileHash( array $params );
207 -
208 - /**
209119 * Get the properties of the file that exists at a storage path in the backend
210120 * $params include:
211121 * source : source storage path
@@ -275,18 +185,107 @@
276186 }
277187
278188 /**
279 - * Base class for all single-write backends
 189+ * Base class for all single-write backends.
 190+ * This class defines the methods as abstract that subclasses must implement.
280191 */
281192 abstract class FileBackend extends FileBackendBase {
282 - function canMove( array $params ) {
283 - return false; // not implemented
284 - }
 193+ /**
 194+ * Store a file into the backend from a file on disk.
 195+ * Do not call this function from places outside FileBackend and FileOp.
 196+ * $params include:
 197+ * source : source path on disk
 198+ * dest : destination storage path
 199+ * overwriteDest : do nothing and pass if an identical file exists at destination
 200+ *
 201+ * @param Array $params
 202+ * @return Status
 203+ */
 204+ abstract public function store( array $params );
285205
286 - function move( array $params ) {
 206+ /**
 207+ * Copy a file from one storage path to another in the backend.
 208+ * Do not call this function from places outside FileBackend and FileOp.
 209+ * $params include:
 210+ * source : source storage path
 211+ * dest : destination storage path
 212+ * overwriteDest : do nothing and pass if an identical file exists at destination
 213+ *
 214+ * @param Array $params
 215+ * @return Status
 216+ */
 217+ abstract public function copy( array $params );
 218+
 219+ /**
 220+ * Copy a file from one storage path to another in the backend.
 221+ * This can be left as a dummy function as long as hasMove() returns false.
 222+ * Do not call this function from places outside FileBackend and FileOp.
 223+ * $params include:
 224+ * source : source storage path
 225+ * dest : destination storage path
 226+ * overwriteDest : do nothing and pass if an identical file exists at destination
 227+ *
 228+ * @param Array $params
 229+ * @return Status
 230+ */
 231+ public function move( array $params ) {
287232 throw new MWException( "This function is not implemented." );
288233 }
289234
290235 /**
 236+ * Delete a file at the storage path.
 237+ * Do not call this function from places outside FileBackend and FileOp.
 238+ * $params include:
 239+ * source : source storage path
 240+ *
 241+ * @param Array $params
 242+ * @return Status
 243+ */
 244+ abstract public function delete( array $params );
 245+
 246+ /**
 247+ * Combines files from severals storage paths into a new file in the backend.
 248+ * Do not call this function from places outside FileBackend and FileOp.
 249+ * $params include:
 250+ * source : source storage path
 251+ * dest : destination storage path
 252+ * overwriteDest : do nothing and pass if an identical file exists at destination
 253+ * overwriteSame : override any existing file at destination
 254+ *
 255+ * @param Array $params
 256+ * @return Status
 257+ */
 258+ abstract public function concatenate( array $params );
 259+
 260+ /**
 261+ * Create a file in the backend with the given contents.
 262+ * Do not call this function from places outside FileBackend and FileOp.
 263+ * $params include:
 264+ * contents : the raw file contents
 265+ * dest : destination storage path
 266+ * overwriteDest : do nothing and pass if an identical file exists at destination
 267+ *
 268+ * @param Array $params
 269+ * @return Status
 270+ */
 271+ abstract public function create( array $params );
 272+
 273+ /**
 274+ * Whether this backend implements move() and is applies to a potential
 275+ * move from one storage path to another. No backends hits are required.
 276+ * For example, moving objects accross containers may not be supported.
 277+ * Do not call this function from places outside FileBackend and FileOp.
 278+ * $params include:
 279+ * source : source storage path
 280+ * dest : destination storage path
 281+ *
 282+ * @param Array $params
 283+ * @return bool
 284+ */
 285+ public function canMove( array $params ) {
 286+ return false; // not implemented
 287+ }
 288+
 289+ /**
291290 * Get the list of supported operations and their corresponding FileOp classes.
292291 *
293292 * @return Array

Past revisions this follows-up on

RevisionCommit summaryAuthorDate
r104155* Made doOperations() check for most errors upfront before changing files aro...aaron11:02, 24 November 2011

Status & tagging log