diff --git a/resources/sql/autopatches/20140211.dx.1.nullablechangesetid.sql b/resources/sql/autopatches/20140211.dx.1.nullablechangesetid.sql new file mode 100644 index 0000000000..3132bec7ab --- /dev/null +++ b/resources/sql/autopatches/20140211.dx.1.nullablechangesetid.sql @@ -0,0 +1,2 @@ +ALTER TABLE {$NAMESPACE}_differential.differential_transaction_comment + CHANGE changesetID changesetID INT UNSIGNED; diff --git a/resources/sql/autopatches/20140211.dx.2.migcommenttext.php b/resources/sql/autopatches/20140211.dx.2.migcommenttext.php new file mode 100644 index 0000000000..438e85b58b --- /dev/null +++ b/resources/sql/autopatches/20140211.dx.2.migcommenttext.php @@ -0,0 +1,71 @@ +establishConnection('w'); +$rows = new LiskRawMigrationIterator($conn_w, 'differential_comment'); + +$content_source = PhabricatorContentSource::newForSource( + PhabricatorContentSource::SOURCE_LEGACY, + array())->serialize(); + +echo "Migrating Differential comment text to modern storage...\n"; +foreach ($rows as $row) { + $id = $row['id']; + echo "Migrating Differential comment {$id}...\n"; + if (!strlen($row['content'])) { + echo "Comment has no text, continuing.\n"; + continue; + } + + $revision = id(new DifferentialRevision())->load($row['revisionID']); + if (!$revision) { + echo "Comment has no valid revision, continuing.\n"; + continue; + } + + $revision_phid = $revision->getPHID(); + + $dst_table = 'differential_inline_comment'; + + $xaction_phid = PhabricatorPHID::generateNewPHID( + PhabricatorApplicationTransactionPHIDTypeTransaction::TYPECONST, + DifferentialPHIDTypeRevision::TYPECONST); + + $comment_phid = PhabricatorPHID::generateNewPHID( + PhabricatorPHIDConstants::PHID_TYPE_XCMT, + DifferentialPHIDTypeRevision::TYPECONST); + + queryfx( + $conn_w, + 'INSERT IGNORE INTO %T + (phid, transactionPHID, authorPHID, viewPolicy, editPolicy, + commentVersion, content, contentSource, isDeleted, + dateCreated, dateModified, revisionPHID, changesetID, + legacyCommentID) + VALUES (%s, %s, %s, %s, %s, + %d, %s, %s, %d, + %d, %d, %s, %nd, + %d)', + 'differential_transaction_comment', + + // phid, transactionPHID, authorPHID, viewPolicy, editPolicy + $comment_phid, + $xaction_phid, + $row['authorPHID'], + 'public', + $row['authorPHID'], + + // commentVersion, content, contentSource, isDeleted + 1, + $row['content'], + $content_source, + 0, + + // dateCreated, dateModified, revisionPHID, changesetID, legacyCommentID + $row['dateCreated'], + $row['dateModified'], + $revision_phid, + null, + $row['id']); +} + +echo "Done.\n"; diff --git a/src/applications/differential/query/DifferentialCommentQuery.php b/src/applications/differential/query/DifferentialCommentQuery.php index 6a82262d3c..3c61cc2345 100644 --- a/src/applications/differential/query/DifferentialCommentQuery.php +++ b/src/applications/differential/query/DifferentialCommentQuery.php @@ -24,7 +24,15 @@ final class DifferentialCommentQuery $this->buildWhereClause($conn_r), $this->buildLimitClause($conn_r)); - return $table->loadAllFromArray($data); + $comments = $table->loadAllFromArray($data); + + // We've moved the actual text storage into DifferentialTransactionComment, + // so load the relevant pieces of text we need. + if ($comments) { + $this->loadCommentText($comments); + } + + return $comments; } private function buildWhereClause(AphrontDatabaseConnection $conn_r) { @@ -40,4 +48,25 @@ final class DifferentialCommentQuery return $this->formatWhereClause($where); } + private function loadCommentText(array $comments) { + $table = new DifferentialTransactionComment(); + $conn_r = $table->establishConnection('r'); + + $data = queryfx_all( + $conn_r, + 'SELECT * FROM %T WHERE legacyCommentID IN (%Ld) AND changesetID IS NULL', + $table->getTableName(), + mpull($comments, 'getID')); + $texts = $table->loadAllFromArray($data); + $texts = mpull($texts, null, 'getLegacyCommentID'); + + foreach ($comments as $comment) { + $text = idx($texts, $comment->getID()); + if ($text) { + $comment->setProxyComment($text); + } + } + } + + } diff --git a/src/applications/differential/storage/DifferentialComment.php b/src/applications/differential/storage/DifferentialComment.php index 8d56afdf01..557cbb6508 100644 --- a/src/applications/differential/storage/DifferentialComment.php +++ b/src/applications/differential/storage/DifferentialComment.php @@ -13,14 +13,44 @@ final class DifferentialComment extends DifferentialDAO protected $authorPHID; protected $revisionID; protected $action; - protected $content; + protected $content = ''; protected $cache; protected $metadata = array(); protected $contentSource; private $arbitraryDiffForFacebook; + private $proxyComment; + + public function getContent() { + return $this->getProxyComment()->getContent(); + } + + public function setContent($content) { + // NOTE: We no longer read this field, but there's no cost to continuing + // to write it in case something goes horribly wrong, since it makes it + // far easier to back out of this. + $this->content = $content; + $this->getProxyComment()->setContent($content); + return $this; + } + + private function getProxyComment() { + if (!$this->proxyComment) { + $this->proxyComment = new DifferentialTransactionComment(); + } + return $this->proxyComment; + } + + public function setProxyComment(DifferentialTransactionComment $proxy) { + if ($this->proxyComment) { + throw new Exception(pht('You can not overwrite a proxy comment.')); + } + $this->proxyComment = $proxy; + return $this; + } public function setRevision(DifferentialRevision $revision) { + $this->getProxyComment()->setRevisionPHID($revision->getPHID()); return $this->setRevisionID($revision->getID()); } @@ -93,4 +123,31 @@ final class DifferentialComment extends DifferentialDAO return (bool)$this->getID(); } + public function save() { + $this->openTransaction(); + $result = parent::save(); + + $content_source = PhabricatorContentSource::newForSource( + PhabricatorContentSource::SOURCE_LEGACY, + array()); + + $xaction_phid = PhabricatorPHID::generateNewPHID( + PhabricatorApplicationTransactionPHIDTypeTransaction::TYPECONST, + DifferentialPHIDTypeRevision::TYPECONST); + + $proxy = $this->getProxyComment(); + $proxy + ->setAuthorPHID($this->getAuthorPHID()) + ->setViewPolicy('public') + ->setEditPolicy($this->getAuthorPHID()) + ->setContentSource($content_source) + ->setCommentVersion(1) + ->setLegacyCommentID($this->getID()) + ->setTransactionPHID($xaction_phid) + ->save(); + $this->saveTransaction(); + + return $result; + } + }