Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F15384955
D18584.id44630.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
11 KB
Referenced Files
None
Subscribers
None
D18584.id44630.diff
View Options
diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php
--- a/src/__phutil_library_map__.php
+++ b/src/__phutil_library_map__.php
@@ -2667,6 +2667,7 @@
'PhabricatorDifferentialConfigOptions' => 'applications/differential/config/PhabricatorDifferentialConfigOptions.php',
'PhabricatorDifferentialExtractWorkflow' => 'applications/differential/management/PhabricatorDifferentialExtractWorkflow.php',
'PhabricatorDifferentialManagementWorkflow' => 'applications/differential/management/PhabricatorDifferentialManagementWorkflow.php',
+ 'PhabricatorDifferentialMigrateHunkWorkflow' => 'applications/differential/management/PhabricatorDifferentialMigrateHunkWorkflow.php',
'PhabricatorDifferentialRevisionTestDataGenerator' => 'applications/differential/lipsum/PhabricatorDifferentialRevisionTestDataGenerator.php',
'PhabricatorDiffusionApplication' => 'applications/diffusion/application/PhabricatorDiffusionApplication.php',
'PhabricatorDiffusionBlameSetting' => 'applications/settings/setting/PhabricatorDiffusionBlameSetting.php',
@@ -5367,6 +5368,7 @@
'DifferentialChangeset' => array(
'DifferentialDAO',
'PhabricatorPolicyInterface',
+ 'PhabricatorDestructibleInterface',
),
'DifferentialChangesetDetailView' => 'AphrontView',
'DifferentialChangesetFileTreeSideNavBuilder' => 'Phobject',
@@ -5461,6 +5463,7 @@
'DifferentialHunk' => array(
'DifferentialDAO',
'PhabricatorPolicyInterface',
+ 'PhabricatorDestructibleInterface',
),
'DifferentialHunkParser' => 'Phobject',
'DifferentialHunkParserTestCase' => 'PhabricatorTestCase',
@@ -7999,6 +8002,7 @@
'PhabricatorDifferentialConfigOptions' => 'PhabricatorApplicationConfigOptions',
'PhabricatorDifferentialExtractWorkflow' => 'PhabricatorDifferentialManagementWorkflow',
'PhabricatorDifferentialManagementWorkflow' => 'PhabricatorManagementWorkflow',
+ 'PhabricatorDifferentialMigrateHunkWorkflow' => 'PhabricatorDifferentialManagementWorkflow',
'PhabricatorDifferentialRevisionTestDataGenerator' => 'PhabricatorTestDataGenerator',
'PhabricatorDiffusionApplication' => 'PhabricatorApplication',
'PhabricatorDiffusionBlameSetting' => 'PhabricatorInternalSetting',
diff --git a/src/applications/differential/management/PhabricatorDifferentialMigrateHunkWorkflow.php b/src/applications/differential/management/PhabricatorDifferentialMigrateHunkWorkflow.php
new file mode 100644
--- /dev/null
+++ b/src/applications/differential/management/PhabricatorDifferentialMigrateHunkWorkflow.php
@@ -0,0 +1,86 @@
+<?php
+
+final class PhabricatorDifferentialMigrateHunkWorkflow
+ extends PhabricatorDifferentialManagementWorkflow {
+
+ protected function didConstruct() {
+ $this
+ ->setName('migrate-hunk')
+ ->setExamples('**migrate-hunk** --id __hunk__ --to __storage__')
+ ->setSynopsis(pht('Migrate storage engines for a hunk.'))
+ ->setArguments(
+ array(
+ array(
+ 'name' => 'id',
+ 'param' => 'id',
+ 'help' => pht('Hunk ID to migrate.'),
+ ),
+ array(
+ 'name' => 'to',
+ 'param' => 'storage',
+ 'help' => pht('Storage engine to migrate to.'),
+ ),
+ ));
+ }
+
+ public function execute(PhutilArgumentParser $args) {
+ $id = $args->getArg('id');
+ if (!$id) {
+ throw new PhutilArgumentUsageException(
+ pht('Specify a hunk to migrate with --id.'));
+ }
+
+ $storage = $args->getArg('to');
+ switch ($storage) {
+ case DifferentialModernHunk::DATATYPE_TEXT:
+ case DifferentialModernHunk::DATATYPE_FILE:
+ break;
+ default:
+ throw new PhutilArgumentUsageException(
+ pht('Specify a hunk storage engine with --to.'));
+ }
+
+ $hunk = $this->loadHunk($id);
+ $old_data = $hunk->getChanges();
+
+ switch ($storage) {
+ case DifferentialModernHunk::DATATYPE_TEXT:
+ $hunk->saveAsText();
+ $this->logOkay(
+ pht('TEXT'),
+ pht('Convereted hunk to text storage.'));
+ break;
+ case DifferentialModernHunk::DATATYPE_FILE:
+ $hunk->saveAsFile();
+ $this->logOkay(
+ pht('FILE'),
+ pht('Convereted hunk to file storage.'));
+ break;
+ }
+
+ $hunk = $this->loadHunk($id);
+ $new_data = $hunk->getChanges();
+
+ if ($old_data !== $new_data) {
+ throw new Exception(
+ pht(
+ 'Integrity check failed: new file data differs fom old data!'));
+ }
+
+ return 0;
+ }
+
+ private function loadHunk($id) {
+ $hunk = id(new DifferentialModernHunk())->load($id);
+ if (!$hunk) {
+ throw new PhutilArgumentUsageException(
+ pht(
+ 'No hunk exists with ID "%s".',
+ $id));
+ }
+
+ return $hunk;
+ }
+
+
+}
diff --git a/src/applications/differential/storage/DifferentialChangeset.php b/src/applications/differential/storage/DifferentialChangeset.php
--- a/src/applications/differential/storage/DifferentialChangeset.php
+++ b/src/applications/differential/storage/DifferentialChangeset.php
@@ -1,7 +1,10 @@
<?php
-final class DifferentialChangeset extends DifferentialDAO
- implements PhabricatorPolicyInterface {
+final class DifferentialChangeset
+ extends DifferentialDAO
+ implements
+ PhabricatorPolicyInterface,
+ PhabricatorDestructibleInterface {
protected $diffID;
protected $oldFile;
@@ -236,4 +239,25 @@
return $this->getDiff()->hasAutomaticCapability($capability, $viewer);
}
+
+/* -( PhabricatorDestructibleInterface )----------------------------------- */
+
+
+ public function destroyObjectPermanently(
+ PhabricatorDestructionEngine $engine) {
+ $this->openTransaction();
+
+ $hunks = id(new DifferentialModernHunk())->loadAllWhere(
+ 'changesetID = %d',
+ $this->getID());
+ foreach ($hunks as $hunk) {
+ $engine->destroyObject($hunk);
+ }
+
+ $this->delete();
+
+ $this->saveTransaction();
+ }
+
+
}
diff --git a/src/applications/differential/storage/DifferentialDiff.php b/src/applications/differential/storage/DifferentialDiff.php
--- a/src/applications/differential/storage/DifferentialDiff.php
+++ b/src/applications/differential/storage/DifferentialDiff.php
@@ -727,7 +727,7 @@
$this->delete();
foreach ($this->loadChangesets() as $changeset) {
- $changeset->delete();
+ $engine->destroyObject($changeset);
}
$properties = id(new DifferentialDiffProperty())->loadAllWhere(
diff --git a/src/applications/differential/storage/DifferentialHunk.php b/src/applications/differential/storage/DifferentialHunk.php
--- a/src/applications/differential/storage/DifferentialHunk.php
+++ b/src/applications/differential/storage/DifferentialHunk.php
@@ -1,7 +1,10 @@
<?php
-abstract class DifferentialHunk extends DifferentialDAO
- implements PhabricatorPolicyInterface {
+abstract class DifferentialHunk
+ extends DifferentialDAO
+ implements
+ PhabricatorPolicyInterface,
+ PhabricatorDestructibleInterface {
protected $changesetID;
protected $oldOffset;
@@ -228,4 +231,14 @@
return $this->getChangeset()->hasAutomaticCapability($capability, $viewer);
}
+
+/* -( PhabricatorDestructibleInterface )----------------------------------- */
+
+
+ public function destroyObjectPermanently(
+ PhabricatorDestructionEngine $engine) {
+ $this->delete();
+ }
+
+
}
diff --git a/src/applications/differential/storage/DifferentialModernHunk.php b/src/applications/differential/storage/DifferentialModernHunk.php
--- a/src/applications/differential/storage/DifferentialModernHunk.php
+++ b/src/applications/differential/storage/DifferentialModernHunk.php
@@ -15,6 +15,7 @@
private $rawData;
private $forcedEncoding;
+ private $fileData;
public function getTableName() {
return 'differential_hunk_modern';
@@ -87,6 +88,57 @@
return parent::save();
}
+ public function saveAsText() {
+ $old_type = $this->getDataType();
+ $old_data = $this->getData();
+
+ if ($old_type == self::DATATYPE_TEXT) {
+ return $this;
+ }
+
+ $raw_data = $this->getRawData();
+
+ $this->setDataType(self::DATATYPE_TEXT);
+ $this->setData($raw_data);
+
+ $result = $this->save();
+
+ $this->destroyData($old_type, $old_data);
+
+ return $result;
+ }
+
+ public function saveAsFile() {
+ $old_type = $this->getDataType();
+ $old_data = $this->getData();
+
+ if ($old_type == self::DATATYPE_FILE) {
+ return $this;
+ }
+
+ $raw_data = $this->getRawData();
+
+ $file = PhabricatorFile::newFromFileData(
+ $raw_data,
+ array(
+ 'name' => 'differential-hunk',
+ 'mime-type' => 'application/octet-stream',
+ 'viewPolicy' => PhabricatorPolicies::POLICY_NOONE,
+ ));
+
+ $this->setDataType(self::DATATYPE_FILE);
+ $this->setData($file->getPHID());
+
+ // NOTE: Because hunks don't have a PHID and we just load hunk data with
+ // the ominipotent viewer, we do not need to attach the file to anything.
+
+ $result = $this->save();
+
+ $this->destroyData($old_type, $old_data);
+
+ return $result;
+ }
+
private function getRawData() {
if ($this->rawData === null) {
$type = $this->getDataType();
@@ -98,6 +150,8 @@
$data = $data;
break;
case self::DATATYPE_FILE:
+ $data = $this->loadFileData();
+ break;
default:
throw new Exception(
pht('Hunk has unsupported data type "%s"!', $type));
@@ -123,4 +177,75 @@
return $this->rawData;
}
+ private function loadFileData() {
+ if ($this->fileData === null) {
+ $type = $this->getDataType();
+ if ($type !== self::DATATYPE_FILE) {
+ throw new Exception(
+ pht(
+ 'Unable to load file data for hunk with wrong data type ("%s").',
+ $type));
+ }
+
+ $file_phid = $this->getData();
+
+ $file = $this->loadRawFile($file_phid);
+ $data = $file->loadFileData();
+
+ $this->fileData = $data;
+ }
+
+ return $this->fileData;
+ }
+
+ private function loadRawFile($file_phid) {
+ $viewer = PhabricatorUser::getOmnipotentUser();
+
+
+ $files = id(new PhabricatorFileQuery())
+ ->setViewer($viewer)
+ ->withPHIDs(array($file_phid))
+ ->execute();
+ if (!$files) {
+ throw new Exception(
+ pht(
+ 'Failed to load file ("%s") with hunk data.',
+ $file_phid));
+ }
+
+ $file = head($files);
+
+ return $file;
+ }
+
+
+ public function destroyObjectPermanently(
+ PhabricatorDestructionEngine $engine) {
+
+ $type = $this->getDataType();
+ $data = $this->getData();
+
+ $this->destroyData($type, $data, $engine);
+
+ return parent::destroyObjectPermanently($engine);
+ }
+
+
+ private function destroyData(
+ $type,
+ $data,
+ PhabricatorDestructionEngine $engine = null) {
+
+ if (!$engine) {
+ $engine = new PhabricatorDestructionEngine();
+ }
+
+ switch ($type) {
+ case self::DATATYPE_FILE:
+ $file = $this->loadRawFile($data);
+ $engine->destroyObject($file);
+ break;
+ }
+ }
+
}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Mar 15, 9:16 PM (1 w, 3 d ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
7430244
Default Alt Text
D18584.id44630.diff (11 KB)
Attached To
Mode
D18584: Support storage of Differential hunk data in Files
Attached
Detach File
Event Timeline
Log In to Comment