@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<?php
2
3$conn_w = id(new DifferentialRevision())->establishConnection('w');
4$rows = new LiskRawMigrationIterator($conn_w, 'differential_comment');
5
6$content_source = PhabricatorContentSource::newForSource(
7 PhabricatorOldWorldContentSource::SOURCECONST)->serialize();
8
9echo pht('Migrating Differential comments to modern storage...')."\n";
10foreach ($rows as $row) {
11 $id = $row['id'];
12 echo pht('Migrating comment %d...', $id)."\n";
13
14 $revision = id(new DifferentialRevision())->load($row['revisionID']);
15 if (!$revision) {
16 echo pht('No revision, continuing.')."\n";
17 continue;
18 }
19
20 $revision_phid = $revision->getPHID();
21
22 $comments = queryfx_all(
23 $conn_w,
24 'SELECT * FROM %T WHERE legacyCommentID = %d',
25 'differential_transaction_comment',
26 $id);
27
28 $main_comments = array();
29 $inline_comments = array();
30
31 foreach ($comments as $comment) {
32 if ($comment['changesetID']) {
33 $inline_comments[] = $comment;
34 } else {
35 $main_comments[] = $comment;
36 }
37 }
38
39 $metadata = json_decode($row['metadata'], true);
40 if (!is_array($metadata)) {
41 $metadata = array();
42 }
43
44 $key_cc = 'added-ccs';
45 $key_add_rev = 'added-reviewers';
46 $key_rem_rev = 'removed-reviewers';
47 $key_diff_id = 'diff-id';
48
49 $xactions = array();
50
51 // Build the main action transaction.
52 switch ($row['action']) {
53 case DifferentialAction::ACTION_COMMENT:
54 case DifferentialAction::ACTION_ADDREVIEWERS:
55 case DifferentialAction::ACTION_ADDCCS:
56 case DifferentialAction::ACTION_UPDATE:
57 case DifferentialTransaction::TYPE_INLINE:
58 // These actions will have their transactions created by other rules.
59 break;
60 default:
61 // Otherwise, this is a normal action (like an accept or reject).
62 $xactions[] = array(
63 'type' => DifferentialTransaction::TYPE_ACTION,
64 'old' => null,
65 'new' => $row['action'],
66 );
67 break;
68 }
69
70 // Build the diff update transaction, if one exists.
71 $diff_id = idx($metadata, $key_diff_id);
72 if (!is_scalar($diff_id)) {
73 $diff_id = null;
74 }
75
76 if ($diff_id || $row['action'] == DifferentialAction::ACTION_UPDATE) {
77 $xactions[] = array(
78 'type' => DifferentialRevisionUpdateTransaction::TRANSACTIONTYPE,
79 'old' => null,
80 'new' => $diff_id,
81 );
82 }
83
84 // Build the add/remove reviewers transaction, if one exists.
85 $add_rev = idx($metadata, $key_add_rev, array());
86 if (!is_array($add_rev)) {
87 $add_rev = array();
88 }
89 $rem_rev = idx($metadata, $key_rem_rev, array());
90 if (!is_array($rem_rev)) {
91 $rem_rev = array();
92 }
93
94 if ($add_rev || $rem_rev) {
95 $old = array();
96 foreach ($rem_rev as $phid) {
97 if (!is_scalar($phid)) {
98 continue;
99 }
100 $old[$phid] = array(
101 'src' => $revision_phid,
102 'type' => DifferentialRevisionHasReviewerEdgeType::EDGECONST,
103 'dst' => $phid,
104 );
105 }
106
107 $new = array();
108 foreach ($add_rev as $phid) {
109 if (!is_scalar($phid)) {
110 continue;
111 }
112 $new[$phid] = array(
113 'src' => $revision_phid,
114 'type' => DifferentialRevisionHasReviewerEdgeType::EDGECONST,
115 'dst' => $phid,
116 );
117 }
118
119 $xactions[] = array(
120 'type' => PhabricatorTransactions::TYPE_EDGE,
121 'old' => $old,
122 'new' => $new,
123 'meta' => array(
124 'edge:type' => DifferentialRevisionHasReviewerEdgeType::EDGECONST,
125 ),
126 );
127 }
128
129 // Build the CC transaction, if one exists.
130 $add_cc = idx($metadata, $key_cc, array());
131 if (!is_array($add_cc)) {
132 $add_cc = array();
133 }
134
135 if ($add_cc) {
136 $xactions[] = array(
137 'type' => PhabricatorTransactions::TYPE_SUBSCRIBERS,
138 'old' => array(),
139 'new' => array_fuse($add_cc),
140 );
141 }
142
143
144 // Build the main comment transaction.
145 foreach ($main_comments as $main) {
146 $xactions[] = array(
147 'type' => PhabricatorTransactions::TYPE_COMMENT,
148 'old' => null,
149 'new' => null,
150 'phid' => $main['transactionPHID'],
151 'comment' => $main,
152 );
153 }
154
155 // Build inline comment transactions.
156 foreach ($inline_comments as $inline) {
157 $xactions[] = array(
158 'type' => DifferentialTransaction::TYPE_INLINE,
159 'old' => null,
160 'new' => null,
161 'phid' => $inline['transactionPHID'],
162 'comment' => $inline,
163 );
164 }
165
166 foreach ($xactions as $xaction) {
167 // Generate a new PHID, if we don't already have one from the comment
168 // table. We pregenerated into the comment table to make this a little
169 // easier, so we only need to write to one table.
170 $xaction_phid = idx($xaction, 'phid');
171 if (!$xaction_phid) {
172 $xaction_phid = PhabricatorPHID::generateNewPHID(
173 PhabricatorApplicationTransactionTransactionPHIDType::TYPECONST,
174 DifferentialRevisionPHIDType::TYPECONST);
175 }
176 unset($xaction['phid']);
177
178 $comment_phid = null;
179 $comment_version = 0;
180 if (idx($xaction, 'comment')) {
181 $comment_phid = $xaction['comment']['phid'];
182 $comment_version = 1;
183 }
184
185 $old = idx($xaction, 'old');
186 $new = idx($xaction, 'new');
187 $meta = idx($xaction, 'meta', array());
188
189 queryfx(
190 $conn_w,
191 'INSERT INTO %T (phid, authorPHID, objectPHID, viewPolicy, editPolicy,
192 commentPHID, commentVersion, transactionType, oldValue, newValue,
193 contentSource, metadata, dateCreated, dateModified)
194 VALUES (%s, %s, %s, %s, %s, %ns, %d, %s, %ns, %ns, %s, %s, %d, %d)',
195 'differential_transaction',
196
197 // PHID, authorPHID, objectPHID
198 $xaction_phid,
199 (string)$row['authorPHID'],
200 $revision_phid,
201
202 // viewPolicy, editPolicy, commentPHID, commentVersion
203 'public',
204 (string)$row['authorPHID'],
205 $comment_phid,
206 $comment_version,
207
208 // transactionType, oldValue, newValue, contentSource, metadata
209 $xaction['type'],
210 json_encode($old),
211 json_encode($new),
212 $content_source,
213 json_encode($meta),
214
215 // dates
216 $row['dateCreated'],
217 $row['dateModified']);
218 }
219
220}
221echo pht('Done.')."\n";