Index: trunk/phase3/includes/upload/UploadStash.php |
— | — | @@ -238,7 +238,31 @@ |
239 | 239 | // insert the file metadata into the db. |
240 | 240 | wfDebug( __METHOD__ . " inserting $stashPath under $key\n" ); |
241 | 241 | $dbw = $this->repo->getMasterDb(); |
| 242 | + |
| 243 | + // select happens on the master so this can all be in a transaction, which |
| 244 | + // avoids a race condition that's likely with multiple people uploading from the same |
| 245 | + // set of files |
| 246 | + $dbw->begin(); |
| 247 | + // first, check to see if it's already there. |
| 248 | + $row = $dbw->selectRow( |
| 249 | + 'uploadstash', |
| 250 | + 'us_user, us_timestamp', |
| 251 | + array('us_key' => $key), |
| 252 | + __METHOD__ |
| 253 | + ); |
242 | 254 | |
| 255 | + // The current user can't have this key if: |
| 256 | + // - the key is owned by someone else and |
| 257 | + // - the age of the key is less than REPO_AGE |
| 258 | + if( is_object( $row ) ) { |
| 259 | + if( $row->us_user != $this->userId && |
| 260 | + $row->wfTimestamp( TS_UNIX, $row->us_timestamp ) > time() - UploadStash::REPO_AGE * 3600 |
| 261 | + ) { |
| 262 | + $dbw->rollback(); |
| 263 | + throw new UploadStashWrongOwnerException( "Attempting to upload a duplicate of a file that someone else has stashed" ); |
| 264 | + } |
| 265 | + } |
| 266 | + |
243 | 267 | $this->fileMetadata[$key] = array( |
244 | 268 | 'us_user' => $this->userId, |
245 | 269 | 'us_key' => $key, |
— | — | @@ -255,13 +279,15 @@ |
256 | 280 | 'us_timestamp' => $dbw->timestamp(), |
257 | 281 | 'us_status' => 'finished' |
258 | 282 | ); |
259 | | - |
260 | | - |
261 | | - $dbw->insert( |
| 283 | + |
| 284 | + // if a row exists but previous checks on it passed, let the current user take over this key. |
| 285 | + $dbw->replace( |
262 | 286 | 'uploadstash', |
| 287 | + 'us_key', |
263 | 288 | $this->fileMetadata[$key], |
264 | 289 | __METHOD__ |
265 | 290 | ); |
| 291 | + $dbw->commit(); |
266 | 292 | |
267 | 293 | // store the insertid in the class variable so immediate retrieval (possibly laggy) isn't necesary. |
268 | 294 | $this->fileMetadata[$key]['us_id'] = $dbw->insertId(); |