3 final class PhabricatorFilesManagementCompactWorkflow
4 extends PhabricatorFilesManagementWorkflow
{
6 protected function didConstruct() {
7 $arguments = $this->newIteratorArguments();
10 'help' => pht('Show what would be compacted.'),
17 'Merge identical files to share the same storage. In some cases, '.
18 'this can repair files with missing data.'))
19 ->setArguments($arguments);
22 public function execute(PhutilArgumentParser
$args) {
23 $console = PhutilConsole
::getConsole();
25 $iterator = $this->buildIterator($args);
26 $is_dry_run = $args->getArg('dry-run');
28 foreach ($iterator as $file) {
29 $monogram = $file->getMonogram();
31 $hash = $file->getContentHash();
35 pht('%s: No content hash.', $monogram));
39 // Find other files with the same content hash. We're going to point
40 // them at the data for this file.
41 $similar_files = id(new PhabricatorFile())->loadAllWhere(
42 'contentHash = %s AND id != %d AND
43 (storageEngine != %s OR storageHandle != %s)',
46 $file->getStorageEngine(),
47 $file->getStorageHandle());
48 if (!$similar_files) {
51 pht('%s: No other files with the same content hash.', $monogram));
55 // Only compact files into this one if we can load the data. This
56 // prevents us from breaking working files if we're missing some data.
58 $data = $file->loadFileData();
59 } catch (Exception
$ex) {
67 '%s: Unable to load file data; declining to compact.',
72 foreach ($similar_files as $similar_file) {
77 '%s: Would compact storage with %s.',
79 $similar_file->getMonogram()));
86 '%s: Compacting storage with %s.',
88 $similar_file->getMonogram()));
92 $old_instance = $similar_file->instantiateStorageEngine();
93 $old_engine = $similar_file->getStorageEngine();
94 $old_handle = $similar_file->getStorageHandle();
95 } catch (Exception
$ex) {
96 // If the old stuff is busted, we just won't try to delete the
102 ->setStorageEngine($file->getStorageEngine())
103 ->setStorageHandle($file->getStorageHandle())
107 $similar_file->deleteFileDataIfUnused(