1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-12-24 06:20:56 +01:00

Migrate all Differential reviewer data to edges

Summary:
Ref T1279. @champo did a lot of this work already; we've been doing double writes for a long time.

Add "double reads" (reading the edge table as both the "relationship" table and as the "reviewer status" table), and migrate all the data.

I'm not bothering to try to recover old reviewer status (e.g., we could infer from transactions who accepted old revisions) because it wold be very complicated and doesn't seem too valuable.

Test Plan:
  - Without doing the migration, used Differential. Verified that reads and writes worked. Most of the data was there anyway since we've been double-writing.
  - Performed the migration. Verified that everything was still unchanged.
  - Dropped the edge table, verified all reviweer data vanished.
  - Migrated again, verified the reviewer stuff was restored.
  - Did various cc/reviewer/subscriber queries, got consistent results.

Reviewers: btrahan

Reviewed By: btrahan

CC: champo, aran

Maniphest Tasks: T1279

Differential Revision: https://secure.phabricator.com/D7227
This commit is contained in:
epriestley 2013-10-05 13:48:45 -07:00
parent bd8071bb33
commit 65ddefad8b
4 changed files with 117 additions and 22 deletions

View file

@ -0,0 +1,46 @@
<?php
$table = new DifferentialRevision();
$conn_w = $table->establishConnection('w');
// NOTE: We migrate by revision because the relationship table doesn't have
// an "id" column.
foreach (new LiskMigrationIterator($table) as $revision) {
$revision_id = $revision->getID();
$revision_phid = $revision->getPHID();
echo "Migrating reviewers for D{$revision_id}...\n";
$reviewer_phids = queryfx_all(
$conn_w,
'SELECT objectPHID FROM %T WHERE revisionID = %d
AND relation = %s ORDER BY sequence',
'differential_relationship',
$revision_id,
'revw');
$reviewer_phids = ipull($reviewer_phids, 'objectPHID');
if (!$reviewer_phids) {
continue;
}
$editor = id(new PhabricatorEdgeEditor())
->setActor(PhabricatorUser::getOmnipotentUser());
foreach ($reviewer_phids as $dst) {
$editor->addEdge(
$revision_phid,
PhabricatorEdgeConfig::TYPE_DREV_HAS_REVIEWER,
$dst,
array(
'data' => array(
'status' => DifferentialReviewerStatus::STATUS_ADDED,
),
));
}
$editor->save();
}
echo "Done.\n";

View file

@ -2751,7 +2751,11 @@ phutil_register_library_map(array(
'HeraldRuleTransactionComment' => 'PhabricatorApplicationTransactionComment', 'HeraldRuleTransactionComment' => 'PhabricatorApplicationTransactionComment',
'HeraldRuleViewController' => 'HeraldController', 'HeraldRuleViewController' => 'HeraldController',
'HeraldTestConsoleController' => 'HeraldController', 'HeraldTestConsoleController' => 'HeraldController',
'HeraldTranscript' => 'HeraldDAO', 'HeraldTranscript' =>
array(
0 => 'HeraldDAO',
1 => 'PhabricatorPolicyInterface',
),
'HeraldTranscriptController' => 'HeraldController', 'HeraldTranscriptController' => 'HeraldController',
'HeraldTranscriptListController' => 'HeraldController', 'HeraldTranscriptListController' => 'HeraldController',
'HeraldTranscriptQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 'HeraldTranscriptQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',

View file

@ -599,25 +599,32 @@ final class DifferentialRevisionQuery
if ($this->reviewers) { if ($this->reviewers) {
$joins[] = qsprintf( $joins[] = qsprintf(
$conn_r, $conn_r,
'JOIN %T reviewer_rel ON reviewer_rel.revisionID = r.id '. 'JOIN %T e_reviewers ON e_reviewers.src = r.phid '.
'AND reviewer_rel.relation = %s '. 'AND e_reviewers.type = %s '.
'AND reviewer_rel.objectPHID in (%Ls)', 'AND e_reviewers.dst in (%Ls)',
DifferentialRevision::RELATIONSHIP_TABLE, PhabricatorEdgeConfig::TABLE_NAME_EDGE,
DifferentialRevision::RELATION_REVIEWER, PhabricatorEdgeConfig::TYPE_DREV_HAS_REVIEWER,
$this->reviewers); $this->reviewers);
} }
if ($this->subscribers) { if ($this->subscribers) {
// TODO: These can be expressed as a JOIN again (and the corresponding
// WHERE clause removed) once subscribers move to edges.
$joins[] = qsprintf( $joins[] = qsprintf(
$conn_r, $conn_r,
'JOIN %T sub_rel ON sub_rel.revisionID = r.id '. 'LEFT JOIN %T sub_rel_cc ON sub_rel_cc.revisionID = r.id '.
'AND sub_rel.relation IN (%Ls) '. 'AND sub_rel_cc.relation = %s '.
'AND sub_rel.objectPHID in (%Ls)', 'AND sub_rel_cc.objectPHID in (%Ls)',
DifferentialRevision::RELATIONSHIP_TABLE, DifferentialRevision::RELATIONSHIP_TABLE,
array(
DifferentialRevision::RELATION_SUBSCRIBED, DifferentialRevision::RELATION_SUBSCRIBED,
DifferentialRevision::RELATION_REVIEWER, $this->subscribers);
), $joins[] = qsprintf(
$conn_r,
'LEFT JOIN %T sub_rel_reviewer ON sub_rel_reviewer.src = r.phid '.
'AND sub_rel_reviewer.type = %s '.
'AND sub_rel_reviewer.dst in (%Ls)',
PhabricatorEdgeConfig::TABLE_NAME_EDGE,
PhabricatorEdgeConfig::TYPE_DREV_HAS_REVIEWER,
$this->subscribers); $this->subscribers);
} }
@ -710,6 +717,13 @@ final class DifferentialRevisionQuery
$this->arcanistProjectPHIDs); $this->arcanistProjectPHIDs);
} }
if ($this->subscribers) {
$where[] = qsprintf(
$conn_r,
'(sub_rel_cc.objectPHID IS NOT NULL)
OR (sub_rel_reviewer.dst IS NOT NULL)');
}
switch ($this->status) { switch ($this->status) {
case self::STATUS_ANY: case self::STATUS_ANY:
break; break;
@ -889,16 +903,30 @@ final class DifferentialRevisionQuery
assert_instances_of($revisions, 'DifferentialRevision'); assert_instances_of($revisions, 'DifferentialRevision');
$relationships = queryfx_all( $relationships = queryfx_all(
$conn_r, $conn_r,
'SELECT * FROM %T WHERE revisionID in (%Ld) ORDER BY sequence', 'SELECT * FROM %T WHERE revisionID in (%Ld)
AND relation != %s ORDER BY sequence',
DifferentialRevision::RELATIONSHIP_TABLE, DifferentialRevision::RELATIONSHIP_TABLE,
mpull($revisions, 'getID')); mpull($revisions, 'getID'),
DifferentialRevision::RELATION_REVIEWER);
$relationships = igroup($relationships, 'revisionID'); $relationships = igroup($relationships, 'revisionID');
$type_reviewer = PhabricatorEdgeConfig::TYPE_DREV_HAS_REVIEWER;
$edges = id(new PhabricatorEdgeQuery())
->withSourcePHIDs(mpull($revisions, 'getPHID'))
->withEdgeTypes(array($type_reviewer))
->execute();
foreach ($revisions as $revision) { foreach ($revisions as $revision) {
$revision->attachRelationships( $data = idx($relationships, $revision->getID(), array());
idx( $revision_edges = $edges[$revision->getPHID()][$type_reviewer];
$relationships, foreach ($revision_edges as $dst_phid => $edge_data) {
$revision->getID(), $data[] = array(
array())); 'relation' => DifferentialRevision::RELATION_REVIEWER,
'objectPHID' => $dst_phid,
);
}
$revision->attachRelationships($data);
} }
} }

View file

@ -223,11 +223,28 @@ final class DifferentialRevision extends DifferentialDAO
return; return;
} }
// Read "subscribed" and "unsubscribed" data out of the old relationship
// table.
$data = queryfx_all( $data = queryfx_all(
$this->establishConnection('r'), $this->establishConnection('r'),
'SELECT * FROM %T WHERE revisionID = %d ORDER BY sequence', 'SELECT * FROM %T WHERE revisionID = %d
AND relation != %s ORDER BY sequence',
self::RELATIONSHIP_TABLE, self::RELATIONSHIP_TABLE,
$this->getID()); $this->getID(),
self::RELATION_REVIEWER);
// Read "reviewer" data out of the new table.
$reviewer_phids = PhabricatorEdgeQuery::loadDestinationPHIDs(
$this->getPHID(),
PhabricatorEdgeConfig::TYPE_DREV_HAS_REVIEWER);
foreach ($reviewer_phids as $phid) {
$data[] = array(
'relation' => self::RELATION_REVIEWER,
'objectPHID' => $phid,
);
}
return $this->attachRelationships($data); return $this->attachRelationships($data);
} }