1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-12-04 20:52:43 +01:00
phorge-phorge/resources/sql/autopatches/20170320.reviewers.03.migrate.php
epriestley 8ad5d28686 Migrate old reviewer edges to new storage
Summary:
Ref T10967. We still have double writes, so all reviewers are being written to both old and new storage. This migrates all the data in the old storage to the new storage, so both storage tables should have a complete set of data and be getting identical updates as we move forward.

After this, I can move readers over one at a time and eventually get rid of the old writes and old storage.

This loads all of the edge data into memory in a big chunk. I reached out to one install to get some more information about their data size. Ours is quite manageable and I think even large installs will probably fit into memory, but we can do this in chunks if not.

However, because the Edge table doesn't have an `id` column, we can't use either the `RawMigrationIterator` or the `MigrationIterator`, and would need to write a new `EdgeMigrationIterator`. This isn't tons of work but might not be necessary.

Test Plan: Ran the migration locally, spot-checked the results in the database for sanity and correctness.

Reviewers: chad

Reviewed By: chad

Maniphest Tasks: T10967

Differential Revision: https://secure.phabricator.com/D17515
2017-03-20 16:44:40 -07:00

125 lines
3.3 KiB
PHP

<?php
$table = new DifferentialRevision();
$diff_table = new DifferentialDiff();
$reviewer_table = new DifferentialReviewer();
$table_name = PhabricatorEdgeConfig::TABLE_NAME_EDGE;
$data_name = PhabricatorEdgeConfig::TABLE_NAME_EDGEDATA;
$conn = $table->establishConnection('w');
// Previously "DifferentialRevisionHasReviewerEdgeType::EDGECONST".
$edge_type = 35;
// NOTE: We can't use normal migration iterators for edges because they don't
// have an "id" column. For now, try just loading the whole result set: the
// actual size of the rows is small. If we run into issues, we could write an
// EdgeIterator.
$every_edge = queryfx_all(
$conn,
'SELECT * FROM %T edge LEFT JOIN %T data ON edge.dataID = data.id
WHERE edge.type = %d',
$table_name,
$data_name,
$edge_type);
foreach ($every_edge as $edge) {
if ($edge['type'] != $edge_type) {
// Ignore edges which aren't "reviewers", like subscribers.
continue;
}
try {
$data = phutil_json_decode($edge['data']);
$data = idx($data, 'data');
} catch (Exception $ex) {
// Just ignore any kind of issue with the edge data, we'll use a default
// below.
$data = null;
}
if (!$data) {
$data = array(
'status' => 'added',
);
}
$status = idx($data, 'status');
$diff_phid = null;
// NOTE: At one point, the code to populate "diffID" worked correctly, but
// it seems to have later been broken. Salvage it if we can, and look up
// the corresponding diff PHID.
$diff_id = idx($data, 'diffID');
if ($diff_id) {
$row = queryfx_one(
$conn,
'SELECT phid FROM %T WHERE id = %d',
$diff_table->getTableName(),
$diff_id);
if ($row) {
$diff_phid = $row['phid'];
}
}
if (!$diff_phid) {
// If the status is "accepted" or "rejected", look up the current diff
// PHID so we can distinguish between "accepted" and "accepted older".
switch ($status) {
case 'accepted':
case 'rejected':
case 'commented':
$row = queryfx_one(
$conn,
'SELECT diff.phid FROM %T diff JOIN %T revision
ON diff.revisionID = revision.id
WHERE revision.phid = %s
ORDER BY diff.id DESC LIMIT 1',
$diff_table->getTableName(),
$table->getTableName(),
$edge['src']);
if ($row) {
$diff_phid = $row['phid'];
}
break;
}
}
// We now represent some states (like "Commented" and "Accepted Older") as
// a primary state plus an extra flag, instead of making "Commented" a
// primary state. Map old states to new states and flags.
if ($status == 'commented') {
$status = 'added';
$comment_phid = $diff_phid;
$action_phid = null;
} else {
$comment_phid = null;
$action_phid = $diff_phid;
}
if ($status == 'accepted-older') {
$status = 'accepted';
}
if ($status == 'rejected-older') {
$status = 'rejected';
}
queryfx(
$conn,
'INSERT INTO %T (revisionPHID, reviewerPHID, reviewerStatus,
lastActionDiffPHID, lastCommentDiffPHID, dateCreated, dateModified)
VALUES (%s, %s, %s, %ns, %ns, %d, %d)
ON DUPLICATE KEY UPDATE dateCreated = VALUES(dateCreated)',
$reviewer_table->getTableName(),
$edge['src'],
$edge['dst'],
$status,
$action_phid,
$comment_phid,
$edge['dateCreated'],
$edge['dateCreated']);
}