diff --git a/src/applications/files/storage/PhabricatorFile.php b/src/applications/files/storage/PhabricatorFile.php --- a/src/applications/files/storage/PhabricatorFile.php +++ b/src/applications/files/storage/PhabricatorFile.php @@ -318,13 +318,17 @@ $params); $old_engine = $this->instantiateStorageEngine(); + $old_identifier = $this->getStorageEngine(); $old_handle = $this->getStorageHandle(); $this->setStorageEngine($new_identifier); $this->setStorageHandle($new_handle); $this->save(); - $old_engine->deleteFile($old_handle); + $this->deleteFileDataIfUnused( + $old_engine, + $old_identifier, + $old_handle); return $this; } @@ -438,30 +442,43 @@ $ret = parent::delete(); $this->saveTransaction(); - // Check to see if other files are using storage - $other_file = id(new PhabricatorFile())->loadAllWhere( - 'storageEngine = %s AND storageHandle = %s AND - storageFormat = %s AND id != %d LIMIT 1', + $this->deleteFileDataIfUnused( + $this->instantiateStorageEngine(), $this->getStorageEngine(), - $this->getStorageHandle(), - $this->getStorageFormat(), - $this->getID()); + $this->getStorageHandle()); - // If this is the only file using the storage, delete storage - if (!$other_file) { - $engine = $this->instantiateStorageEngine(); + return $ret; + } + + + /** + * Destroy stored file data if there are no remaining files which reference + * it. + */ + private function deleteFileDataIfUnused( + PhabricatorFileStorageEngine $engine, + $engine_identifier, + $handle) { + + // Check to see if any files are using storage. + $usage = id(new PhabricatorFile())->loadAllWhere( + 'storageEngine = %s AND storageHandle = %s LIMIT 1', + $engine_identifier, + $handle); + + // If there are no files using the storage, destroy the actual storage. + if (!$usage) { try { - $engine->deleteFile($this->getStorageHandle()); + $engine->deleteFile($handle); } catch (Exception $ex) { // In the worst case, we're leaving some data stranded in a storage - // engine, which is fine. + // engine, which is not a big deal. phlog($ex); } } - - return $ret; } + public static function hashFileContent($data) { return sha1($data); }