diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index c40f79b052..eaaa4d9e66 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -3017,6 +3017,7 @@ phutil_register_library_map(array( 'PhabricatorGDSetupCheck' => 'applications/config/check/PhabricatorGDSetupCheck.php', 'PhabricatorGarbageCollector' => 'infrastructure/daemon/garbagecollector/PhabricatorGarbageCollector.php', 'PhabricatorGarbageCollectorManagementCollectWorkflow' => 'infrastructure/daemon/garbagecollector/management/PhabricatorGarbageCollectorManagementCollectWorkflow.php', + 'PhabricatorGarbageCollectorManagementCompactEdgesWorkflow' => 'infrastructure/daemon/garbagecollector/management/PhabricatorGarbageCollectorManagementCompactEdgesWorkflow.php', 'PhabricatorGarbageCollectorManagementSetPolicyWorkflow' => 'infrastructure/daemon/garbagecollector/management/PhabricatorGarbageCollectorManagementSetPolicyWorkflow.php', 'PhabricatorGarbageCollectorManagementWorkflow' => 'infrastructure/daemon/garbagecollector/management/PhabricatorGarbageCollectorManagementWorkflow.php', 'PhabricatorGeneralCachePurger' => 'applications/cache/purger/PhabricatorGeneralCachePurger.php', @@ -8484,6 +8485,7 @@ phutil_register_library_map(array( 'PhabricatorGDSetupCheck' => 'PhabricatorSetupCheck', 'PhabricatorGarbageCollector' => 'Phobject', 'PhabricatorGarbageCollectorManagementCollectWorkflow' => 'PhabricatorGarbageCollectorManagementWorkflow', + 'PhabricatorGarbageCollectorManagementCompactEdgesWorkflow' => 'PhabricatorGarbageCollectorManagementWorkflow', 'PhabricatorGarbageCollectorManagementSetPolicyWorkflow' => 'PhabricatorGarbageCollectorManagementWorkflow', 'PhabricatorGarbageCollectorManagementWorkflow' => 'PhabricatorManagementWorkflow', 'PhabricatorGeneralCachePurger' => 'PhabricatorCachePurger', diff --git a/src/infrastructure/daemon/garbagecollector/management/PhabricatorGarbageCollectorManagementCompactEdgesWorkflow.php b/src/infrastructure/daemon/garbagecollector/management/PhabricatorGarbageCollectorManagementCompactEdgesWorkflow.php new file mode 100644 index 0000000000..c47d159850 --- /dev/null +++ b/src/infrastructure/daemon/garbagecollector/management/PhabricatorGarbageCollectorManagementCompactEdgesWorkflow.php @@ -0,0 +1,103 @@ +setName('compact-edges') + ->setExamples('**compact-edges**') + ->setSynopsis( + pht( + 'Rebuild old edge transactions storage to use a more compact '. + 'format.')) + ->setArguments(array()); + } + + public function execute(PhutilArgumentParser $args) { + $tables = id(new PhutilClassMapQuery()) + ->setAncestorClass('PhabricatorApplicationTransaction') + ->execute(); + + foreach ($tables as $table) { + $this->compactEdges($table); + } + + return 0; + } + + private function compactEdges(PhabricatorApplicationTransaction $table) { + $conn = $table->establishConnection('w'); + $class = get_class($table); + + echo tsprintf( + "%s\n", + pht( + 'Rebuilding transactions for "%s"...', + $class)); + + $cursor = 0; + $updated = 0; + while (true) { + $rows = $table->loadAllWhere( + 'transactionType = %s + AND id > %d + AND (oldValue LIKE %> OR newValue LIKE %>) + ORDER BY id ASC LIMIT 100', + PhabricatorTransactions::TYPE_EDGE, + $cursor, + // We're looking for transactions with JSON objects in their value + // fields: the new style transactions have JSON lists instead and + // start with "[" rather than "{". + '{', + '{'); + + if (!$rows) { + break; + } + + foreach ($rows as $row) { + $id = $row->getID(); + + $old = $row->getOldValue(); + $new = $row->getNewValue(); + + if (!is_array($old) || !is_array($new)) { + echo tsprintf( + "%s\n", + pht( + 'Transaction %s (of type %s) has unexpected data, skipping.', + $id, + $class)); + } + + $record = PhabricatorEdgeChangeRecord::newFromTransaction($row); + + $old_data = $record->getModernOldEdgeTransactionData(); + $old_json = phutil_json_encode($old_data); + + $new_data = $record->getModernNewEdgeTransactionData(); + $new_json = phutil_json_encode($new_data); + + queryfx( + $conn, + 'UPDATE %T SET oldValue = %s, newValue = %s WHERE id = %d', + $table->getTableName(), + $old_json, + $new_json, + $id); + + $updated++; + + $cursor = $row->getID(); + } + } + + echo tsprintf( + "%s\n", + pht( + 'Done, compacted %s edge transactions.', + new PhutilNumber($updated))); + } + +}