diff --git a/resources/sql/autopatches/20170320.reviewers.03.migrate.php b/resources/sql/autopatches/20170320.reviewers.03.migrate.php new file mode 100644 index 0000000000..04abb5c141 --- /dev/null +++ b/resources/sql/autopatches/20170320.reviewers.03.migrate.php @@ -0,0 +1,125 @@ +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']); +}