@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Migrate audit comments to transactions

Summary:
Ref T4896. Depends on D10052. This is the major/scary migration, but not really so bad. It is substantially similar to D8210, but less complex because there are fewer actions here.

This moves `PhabricatorAuditComment` storage to `PhabricatorAuditTransaction`, then reads `PhabricatorAuditComment`s as a proxy around the new objects.

Test Plan:
- Before migrating, browsed around. Nothing appeared broken.
- Migrated cleanly.
- Viewed old transactions (inlines, comments, accept/reject/etc, add auditors, add ccs, implicit CCs).
- Added all of those comment types.
- Edited a draft.
- Deleted a draft.
- Spot checked the database for sanity.

Reviewers: btrahan, joshuaspence

Reviewed By: joshuaspence

Subscribers: epriestley

Maniphest Tasks: T4896

Differential Revision: https://secure.phabricator.com/D10055

+326 -73
+150
resources/sql/autopatches/20140725.audit.1.migxactions.php
··· 1 + <?php 2 + 3 + $conn_w = id(new PhabricatorAuditTransaction())->establishConnection('w'); 4 + $rows = new LiskRawMigrationIterator($conn_w, 'audit_comment'); 5 + 6 + $content_source = PhabricatorContentSource::newForSource( 7 + PhabricatorContentSource::SOURCE_LEGACY, 8 + array())->serialize(); 9 + 10 + echo "Migrating Audit comments to modern storage...\n"; 11 + foreach ($rows as $row) { 12 + $id = $row['id']; 13 + echo "Migrating comment {$id}...\n"; 14 + 15 + $comments = queryfx_all( 16 + $conn_w, 17 + 'SELECT * FROM %T WHERE legacyCommentID = %d', 18 + 'audit_transaction_comment', 19 + $id); 20 + 21 + $main_comments = array(); 22 + $inline_comments = array(); 23 + 24 + foreach ($comments as $comment) { 25 + if ($comment['pathID']) { 26 + $inline_comments[] = $comment; 27 + } else { 28 + $main_comments[] = $comment; 29 + } 30 + } 31 + 32 + $metadata = json_decode($row['metadata'], true); 33 + if (!is_array($metadata)) { 34 + $metadata = array(); 35 + } 36 + 37 + $xactions = array(); 38 + 39 + // Build the main action transaction. 40 + switch ($row['action']) { 41 + case PhabricatorAuditActionConstants::ADD_AUDITORS: 42 + $phids = idx($metadata, 'added-auditors', array()); 43 + $xactions[] = array( 44 + 'type' => $row['action'], 45 + 'old' => null, 46 + 'new' => array_fuse($phids), 47 + ); 48 + break; 49 + case PhabricatorAuditActionConstants::ADD_CCS: 50 + $phids = idx($metadata, 'added-ccs', array()); 51 + $xactions[] = array( 52 + 'type' => $row['action'], 53 + 'old' => null, 54 + 'new' => array_fuse($phids), 55 + ); 56 + break; 57 + case PhabricatorAuditActionConstants::COMMENT: 58 + case PhabricatorAuditActionConstants::INLINE: 59 + // These actions will have their transactions created by other rules. 60 + break; 61 + default: 62 + // Otherwise, this is an accept/concern/etc action. 63 + $xactions[] = array( 64 + 'type' => PhabricatorAuditActionConstants::ACTION, 65 + 'old' => null, 66 + 'new' => $row['action'], 67 + ); 68 + break; 69 + } 70 + 71 + 72 + // Build the main comment transaction. 73 + foreach ($main_comments as $main) { 74 + $xactions[] = array( 75 + 'type' => PhabricatorTransactions::TYPE_COMMENT, 76 + 'old' => null, 77 + 'new' => null, 78 + 'phid' => $main['transactionPHID'], 79 + 'comment' => $main, 80 + ); 81 + } 82 + 83 + // Build inline comment transactions. 84 + foreach ($inline_comments as $inline) { 85 + $xactions[] = array( 86 + 'type' => PhabricatorAuditActionConstants::INLINE, 87 + 'old' => null, 88 + 'new' => null, 89 + 'phid' => $inline['transactionPHID'], 90 + 'comment' => $inline, 91 + ); 92 + } 93 + 94 + foreach ($xactions as $xaction) { 95 + // Generate a new PHID, if we don't already have one from the comment 96 + // table. We pregenerated into the comment table to make this a little 97 + // easier, so we only need to write to one table. 98 + $xaction_phid = idx($xaction, 'phid'); 99 + if (!$xaction_phid) { 100 + $xaction_phid = PhabricatorPHID::generateNewPHID( 101 + PhabricatorApplicationTransactionTransactionPHIDType::TYPECONST, 102 + PhabricatorRepositoryCommitPHIDType::TYPECONST); 103 + } 104 + unset($xaction['phid']); 105 + 106 + $comment_phid = null; 107 + $comment_version = 0; 108 + if (idx($xaction, 'comment')) { 109 + $comment_phid = $xaction['comment']['phid']; 110 + $comment_version = 1; 111 + } 112 + 113 + $old = idx($xaction, 'old'); 114 + $new = idx($xaction, 'new'); 115 + $meta = idx($xaction, 'meta', array()); 116 + 117 + queryfx( 118 + $conn_w, 119 + 'INSERT INTO %T (phid, authorPHID, objectPHID, viewPolicy, editPolicy, 120 + commentPHID, commentVersion, transactionType, oldValue, newValue, 121 + contentSource, metadata, dateCreated, dateModified) 122 + VALUES (%s, %s, %s, %s, %s, %ns, %d, %s, %ns, %ns, %s, %s, %d, %d)', 123 + 'audit_transaction', 124 + 125 + // PHID, authorPHID, objectPHID 126 + $xaction_phid, 127 + $row['actorPHID'], 128 + $row['targetPHID'], 129 + 130 + // viewPolicy, editPolicy, commentPHID, commentVersion 131 + 'public', 132 + $row['actorPHID'], 133 + $comment_phid, 134 + $comment_version, 135 + 136 + // transactionType, oldValue, newValue, contentSource, metadata 137 + $xaction['type'], 138 + json_encode($old), 139 + json_encode($new), 140 + $content_source, 141 + json_encode($meta), 142 + 143 + // dates 144 + $row['dateCreated'], 145 + $row['dateModified']); 146 + } 147 + 148 + } 149 + 150 + echo "Done.\n";
+1 -4
src/__phutil_library_map__.php
··· 3929 3929 'PhabricatorAsanaConfigOptions' => 'PhabricatorApplicationConfigOptions', 3930 3930 'PhabricatorAuditAddCommentController' => 'PhabricatorAuditController', 3931 3931 'PhabricatorAuditApplication' => 'PhabricatorApplication', 3932 - 'PhabricatorAuditComment' => array( 3933 - 'PhabricatorAuditDAO', 3934 - 'PhabricatorMarkupInterface', 3935 - ), 3932 + 'PhabricatorAuditComment' => 'PhabricatorMarkupInterface', 3936 3933 'PhabricatorAuditCommentEditor' => 'PhabricatorEditor', 3937 3934 'PhabricatorAuditController' => 'PhabricatorController', 3938 3935 'PhabricatorAuditDAO' => 'PhabricatorLiskDAO',
+1
src/applications/audit/constants/PhabricatorAuditActionConstants.php
··· 10 10 const ADD_CCS = 'add_ccs'; 11 11 const ADD_AUDITORS = 'add_auditors'; 12 12 const INLINE = 'audit:inline'; 13 + const ACTION = 'audit:action'; 13 14 14 15 public static function getActionNameMap() { 15 16 $map = array(
+7 -3
src/applications/audit/editor/PhabricatorAuditCommentEditor.php
··· 262 262 $commit->updateAuditStatus($requests); 263 263 $commit->save(); 264 264 265 + $content_source = PhabricatorContentSource::newForSource( 266 + PhabricatorContentSource::SOURCE_LEGACY, 267 + array()); 268 + 265 269 foreach ($comments as $comment) { 266 270 $comment 267 271 ->setActorPHID($actor->getPHID()) 268 272 ->setTargetPHID($commit->getPHID()) 273 + ->setContentSource($content_source) 269 274 ->save(); 270 275 } 271 276 272 277 foreach ($inline_comments as $inline) { 273 278 $xaction = id(new PhabricatorAuditComment()) 279 + ->setProxyComment($inline->getTransactionCommentForSave()) 274 280 ->setAction(PhabricatorAuditActionConstants::INLINE) 275 281 ->setActorPHID($actor->getPHID()) 276 282 ->setTargetPHID($commit->getPHID()) 283 + ->setContentSource($content_source) 277 284 ->save(); 278 - 279 - $inline->setAuditCommentID($xaction->getID()); 280 - $inline->save(); 281 285 282 286 $comments[] = $xaction; 283 287 }
+161 -64
src/applications/audit/storage/PhabricatorAuditComment.php
··· 1 1 <?php 2 2 3 - final class PhabricatorAuditComment extends PhabricatorAuditDAO 3 + final class PhabricatorAuditComment 4 4 implements PhabricatorMarkupInterface { 5 5 6 6 const METADATA_ADDED_AUDITORS = 'added-auditors'; ··· 8 8 9 9 const MARKUP_FIELD_BODY = 'markup:body'; 10 10 11 - protected $phid; 12 - protected $actorPHID; 13 - protected $targetPHID; 14 - protected $action; 15 - protected $content = ''; 16 - protected $metadata = array(); 11 + private $proxyComment; 12 + private $proxy; 13 + 14 + public function __construct() { 15 + $this->proxy = new PhabricatorAuditTransaction(); 16 + } 17 + 18 + public function __clone() { 19 + $this->proxy = clone $this->proxy; 20 + if ($this->proxyComment) { 21 + $this->proxyComment = clone $this->proxyComment; 22 + } 23 + } 24 + 25 + public static function newFromModernTransaction( 26 + PhabricatorAuditTransaction $xaction) { 27 + 28 + $obj = new PhabricatorAuditComment(); 29 + $obj->proxy = $xaction; 30 + 31 + if ($xaction->hasComment()) { 32 + $obj->proxyComment = $xaction->getComment(); 33 + } 17 34 18 - private $proxyComment; 35 + return $obj; 36 + } 19 37 20 38 public static function loadComments( 21 39 PhabricatorUser $viewer, 22 40 $commit_phid) { 23 41 24 - $comments = id(new PhabricatorAuditComment())->loadAllWhere( 25 - 'targetPHID = %s', 26 - $commit_phid); 42 + $xactions = id(new PhabricatorAuditTransactionQuery()) 43 + ->setViewer($viewer) 44 + ->withObjectPHIDs(array($commit_phid)) 45 + ->needComments(true) 46 + ->execute(); 27 47 28 - if ($comments) { 29 - $table = new PhabricatorAuditTransactionComment(); 30 - $conn_r = $table->establishConnection('r'); 48 + $comments = array(); 49 + foreach ($xactions as $xaction) { 50 + $comments[] = self::newFromModernTransaction($xaction); 51 + } 31 52 32 - $data = queryfx_all( 33 - $conn_r, 34 - 'SELECT * FROM %T WHERE legacyCommentID IN (%Ld) AND pathID IS NULL', 35 - $table->getTableName(), 36 - mpull($comments, 'getID')); 37 - $texts = $table->loadAllFromArray($data); 38 - $texts = mpull($texts, null, 'getLegacyCommentID'); 53 + return $comments; 54 + } 39 55 40 - foreach ($comments as $comment) { 41 - $text = idx($texts, $comment->getID()); 42 - if ($text) { 43 - $comment->setProxyComment($text); 44 - } 45 - } 46 - } 56 + public function getPHID() { 57 + return $this->proxy->getPHID(); 58 + } 47 59 48 - return $comments; 60 + public function getActorPHID() { 61 + return $this->proxy->getAuthorPHID(); 49 62 } 50 63 51 - public function getConfiguration() { 52 - return array( 53 - self::CONFIG_SERIALIZATION => array( 54 - 'metadata' => self::SERIALIZATION_JSON, 55 - ), 56 - self::CONFIG_AUX_PHID => true, 57 - ) + parent::getConfiguration(); 64 + public function setActorPHID($actor_phid) { 65 + $this->proxy->setAuthorPHID($actor_phid); 66 + return $this; 58 67 } 59 68 60 - public function generatePHID() { 61 - return PhabricatorPHID::generateNewPHID('ACMT'); 69 + public function setTargetPHID($target_phid) { 70 + $this->getProxyComment()->setCommitPHID($target_phid); 71 + $this->proxy->setObjectPHID($target_phid); 72 + return $this; 62 73 } 63 74 75 + public function getTargetPHID() { 76 + return $this->proxy->getObjectPHID(); 77 + } 64 78 65 79 public function getContent() { 66 80 return $this->getProxyComment()->getContent(); 67 81 } 68 82 69 83 public function setContent($content) { 70 - // NOTE: We no longer read this field, but there's no cost to continuing 71 - // to write it in case something goes horribly wrong, since it makes it 72 - // far easier to back out of this. 73 - $this->content = $content; 74 84 $this->getProxyComment()->setContent($content); 75 85 return $this; 76 86 } 77 87 88 + public function setContentSource($content_source) { 89 + $this->proxy->setContentSource($content_source); 90 + $this->proxyComment->setContentSource($content_source); 91 + return $this; 92 + } 93 + 94 + public function getContentSource() { 95 + return $this->proxy->getContentSource(); 96 + } 97 + 78 98 private function getProxyComment() { 79 99 if (!$this->proxyComment) { 80 100 $this->proxyComment = new PhabricatorAuditTransactionComment(); ··· 90 110 return $this; 91 111 } 92 112 93 - public function setTargetPHID($target_phid) { 94 - $this->getProxyComment()->setCommitPHID($target_phid); 95 - return parent::setTargetPHID($target_phid); 113 + public function setAction($action) { 114 + switch ($action) { 115 + case PhabricatorAuditActionConstants::INLINE: 116 + case PhabricatorAuditActionConstants::ADD_CCS: 117 + case PhabricatorAuditActionConstants::ADD_AUDITORS: 118 + $this->proxy->setTransactionType($action); 119 + break; 120 + case PhabricatorAuditActionConstants::COMMENT: 121 + $this->proxy->setTransactionType(PhabricatorTransactions::TYPE_COMMENT); 122 + break; 123 + default: 124 + $this->proxy 125 + ->setTransactionType(PhabricatorAuditActionConstants::ACTION) 126 + ->setNewValue($action); 127 + break; 128 + } 129 + 130 + return $this; 96 131 } 97 132 98 - public function save() { 99 - $this->openTransaction(); 100 - $result = parent::save(); 133 + public function getAction() { 134 + $type = $this->proxy->getTransactionType(); 135 + switch ($type) { 136 + case PhabricatorTransactions::TYPE_COMMENT: 137 + return PhabricatorAuditActionConstants::COMMENT; 138 + case PhabricatorAuditActionConstants::INLINE: 139 + case PhabricatorAuditActionConstants::ADD_CCS: 140 + case PhabricatorAuditActionConstants::ADD_AUDITORS: 141 + return $type; 142 + default: 143 + return $this->proxy->getNewValue(); 144 + } 145 + } 101 146 102 - if (strlen($this->getContent())) { 103 - $content_source = PhabricatorContentSource::newForSource( 104 - PhabricatorContentSource::SOURCE_LEGACY, 105 - array()); 147 + public function setMetadata(array $metadata) { 148 + if (!$this->proxy->getTransactionType()) { 149 + throw new Exception(pht('Call setAction() before getMetadata()!')); 150 + } 106 151 107 - $xaction_phid = PhabricatorPHID::generateNewPHID( 108 - PhabricatorApplicationTransactionTransactionPHIDType::TYPECONST, 109 - PhabricatorRepositoryCommitPHIDType::TYPECONST); 152 + $type = $this->proxy->getTransactionType(); 153 + switch ($type) { 154 + case PhabricatorAuditActionConstants::ADD_CCS: 155 + $raw_phids = idx($metadata, self::METADATA_ADDED_CCS, array()); 156 + break; 157 + case PhabricatorAuditActionConstants::ADD_AUDITORS: 158 + $raw_phids = idx($metadata, self::METADATA_ADDED_AUDITORS, array()); 159 + break; 160 + default: 161 + throw new Exception(pht('No metadata expected!')); 162 + } 163 + 164 + $this->proxy->setOldValue(array()); 165 + $this->proxy->setNewValue(array_fuse($raw_phids)); 110 166 111 - $proxy = $this->getProxyComment(); 112 - $proxy 167 + return $this; 168 + } 169 + 170 + public function getMetadata() { 171 + if (!$this->proxy->getTransactionType()) { 172 + throw new Exception(pht('Call setAction() before getMetadata()!')); 173 + } 174 + 175 + $type = $this->proxy->getTransactionType(); 176 + $new_value = $this->proxy->getNewValue(); 177 + switch ($type) { 178 + case PhabricatorAuditActionConstants::ADD_CCS: 179 + return array( 180 + self::METADATA_ADDED_CCS => array_keys($new_value), 181 + ); 182 + case PhabricatorAuditActionConstants::ADD_AUDITORS: 183 + return array( 184 + self::METADATA_ADDED_AUDITORS => array_keys($new_value), 185 + ); 186 + } 187 + 188 + return array(); 189 + } 190 + 191 + public function save() { 192 + $this->proxy->openTransaction(); 193 + $this->proxy 194 + ->setViewPolicy('public') 195 + ->setEditPolicy($this->getActorPHID()) 196 + ->save(); 197 + 198 + if (strlen($this->getContent())) { 199 + $this->getProxyComment() 113 200 ->setAuthorPHID($this->getActorPHID()) 114 201 ->setViewPolicy('public') 115 202 ->setEditPolicy($this->getActorPHID()) 116 - ->setContentSource($content_source) 117 203 ->setCommentVersion(1) 118 - ->setLegacyCommentID($this->getID()) 119 - ->setTransactionPHID($xaction_phid) 204 + ->setTransactionPHID($this->proxy->getPHID()) 205 + ->save(); 206 + 207 + $this->proxy 208 + ->setCommentVersion(1) 209 + ->setCommentPHID($this->getProxyComment()->getPHID()) 120 210 ->save(); 121 211 } 212 + $this->proxy->saveTransaction(); 122 213 123 - $this->saveTransaction(); 214 + return $this; 215 + } 124 216 125 - return $result; 217 + public function getDateCreated() { 218 + return $this->proxy->getDateCreated(); 219 + } 220 + 221 + public function getDateModified() { 222 + return $this->proxy->getDateModified(); 126 223 } 127 224 128 225 ··· 130 227 131 228 132 229 public function getMarkupFieldKey($field) { 133 - return 'AC:'.$this->getID(); 230 + return 'AC:'.$this->getPHID(); 134 231 } 135 232 136 233 public function newMarkupEngine($field) { ··· 146 243 } 147 244 148 245 public function shouldUseMarkupCache($field) { 149 - return (bool)$this->getID(); 246 + return (bool)$this->getPHID(); 150 247 } 151 248 152 249 }
+4
src/applications/audit/storage/PhabricatorAuditInlineComment.php
··· 14 14 $this->proxy = clone $this->proxy; 15 15 } 16 16 17 + public function getTransactionPHID() { 18 + return $this->proxy->getTransactionPHID(); 19 + } 20 + 17 21 public function getTransactionCommentForSave() { 18 22 $content_source = PhabricatorContentSource::newForSource( 19 23 PhabricatorContentSource::SOURCE_LEGACY,
+2 -2
src/applications/diffusion/view/DiffusionCommentListView.php
··· 65 65 66 66 public function render() { 67 67 68 - $inline_comments = mgroup($this->inlineComments, 'getAuditCommentID'); 68 + $inline_comments = mgroup($this->inlineComments, 'getTransactionPHID'); 69 69 70 70 $num = 1; 71 71 72 72 $comments = array(); 73 73 foreach ($this->comments as $comment) { 74 74 75 - $inlines = idx($inline_comments, $comment->getID(), array()); 75 + $inlines = idx($inline_comments, $comment->getPHID(), array()); 76 76 77 77 $view = id(new DiffusionCommentView()) 78 78 ->setMarkupEngine($this->getMarkupEngine())