1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-12-04 20:52:43 +01:00
phorge-phorge/src/applications/differential/storage/DifferentialRevision.php

498 lines
13 KiB
PHP
Raw Normal View History

2011-01-24 20:01:53 +01:00
<?php
final class DifferentialRevision extends DifferentialDAO
implements
PhabricatorTokenReceiverInterface,
PhabricatorPolicyInterface,
PhabricatorFlaggableInterface,
PhrequentTrackableInterface,
HarbormasterBuildableInterface,
PhabricatorSubscribableInterface,
PhabricatorCustomFieldInterface {
2011-01-24 20:01:53 +01:00
protected $title = '';
protected $originalTitle;
2011-01-24 20:01:53 +01:00
protected $status;
protected $summary = '';
protected $testPlan = '';
2011-01-24 20:01:53 +01:00
protected $authorPHID;
protected $lastReviewerPHID;
2011-01-24 20:01:53 +01:00
protected $dateCommitted;
protected $lineCount = 0;
protected $attached = array();
2011-01-27 03:46:34 +01:00
protected $mailKey;
protected $branchName;
protected $arcanistProjectPHID;
protected $repositoryPHID;
protected $viewPolicy = PhabricatorPolicies::POLICY_USER;
protected $editPolicy = PhabricatorPolicies::POLICY_USER;
private $relationships = self::ATTACHABLE;
private $commits = self::ATTACHABLE;
private $activeDiff = self::ATTACHABLE;
private $diffIDs = self::ATTACHABLE;
private $hashes = self::ATTACHABLE;
private $repository = self::ATTACHABLE;
2011-01-27 03:46:34 +01:00
private $reviewerStatus = self::ATTACHABLE;
private $customFields = self::ATTACHABLE;
private $drafts = array();
private $flags = array();
const TABLE_COMMIT = 'differential_commit';
2011-01-27 03:46:34 +01:00
const RELATION_REVIEWER = 'revw';
const RELATION_SUBSCRIBED = 'subd';
public static function initializeNewRevision(PhabricatorUser $actor) {
$app = id(new PhabricatorApplicationQuery())
->setViewer($actor)
->withClasses(array('PhabricatorApplicationDifferential'))
->executeOne();
$view_policy = $app->getPolicy(
DifferentialCapabilityDefaultView::CAPABILITY);
return id(new DifferentialRevision())
->setViewPolicy($view_policy)
->setAuthorPHID($actor->getPHID())
->attachRelationships(array())
->setStatus(ArcanistDifferentialRevisionStatus::NEEDS_REVIEW);
}
2011-01-26 02:17:19 +01:00
public function getConfiguration() {
return array(
self::CONFIG_AUX_PHID => true,
self::CONFIG_SERIALIZATION => array(
'attached' => self::SERIALIZATION_JSON,
'unsubscribed' => self::SERIALIZATION_JSON,
),
2011-01-26 02:17:19 +01:00
) + parent::getConfiguration();
}
public function setTitle($title) {
$this->title = $title;
if (!$this->getID()) {
$this->originalTitle = $title;
}
return $this;
}
public function loadIDsByCommitPHIDs($phids) {
if (!$phids) {
return array();
}
$revision_ids = queryfx_all(
$this->establishConnection('r'),
'SELECT * FROM %T WHERE commitPHID IN (%Ls)',
self::TABLE_COMMIT,
$phids);
return ipull($revision_ids, 'revisionID', 'commitPHID');
}
public function loadCommitPHIDs() {
if (!$this->getID()) {
return ($this->commits = array());
}
$commits = queryfx_all(
$this->establishConnection('r'),
'SELECT commitPHID FROM %T WHERE revisionID = %d',
self::TABLE_COMMIT,
$this->getID());
$commits = ipull($commits, 'commitPHID');
return ($this->commits = $commits);
}
public function getCommitPHIDs() {
return $this->assertAttached($this->commits);
}
public function getActiveDiff() {
// TODO: Because it's currently technically possible to create a revision
// without an associated diff, we allow an attached-but-null active diff.
// It would be good to get rid of this once we make diff-attaching
// transactional.
return $this->assertAttached($this->activeDiff);
}
public function attachActiveDiff($diff) {
$this->activeDiff = $diff;
return $this;
}
public function getDiffIDs() {
return $this->assertAttached($this->diffIDs);
}
public function attachDiffIDs(array $ids) {
rsort($ids);
$this->diffIDs = array_values($ids);
return $this;
}
public function attachCommitPHIDs(array $phids) {
$this->commits = array_values($phids);
return $this;
}
public function getAttachedPHIDs($type) {
return array_keys(idx($this->attached, $type, array()));
}
public function setAttachedPHIDs($type, array $phids) {
$this->attached[$type] = array_fill_keys($phids, array());
return $this;
}
2011-01-26 02:17:19 +01:00
public function generatePHID() {
return PhabricatorPHID::generateNewPHID(
DifferentialPHIDTypeRevision::TYPECONST);
2011-01-26 02:17:19 +01:00
}
2011-01-27 03:46:34 +01:00
public function loadComments() {
if (!$this->getID()) {
return array();
}
Put all DifferentialComment loading behind DifferentialCommentQuery Summary: Ref T2222. I'm thinking about how I want to approach the Asana sync, and I want to try to do T2222 first so that we can build it cleanly on top of ApplicationTransactions. I think we can at least walk down this road a little bit and if it turns out to be scary we can take another approach. I was generally very happy with how the auth migration turned out (seemingly, it was almost completely clean), and want to pursue a similar strategy here. Basically: - Wrap the new objects in the old objects for reads/writes. - Migrate all the existing data to the new table. - Everything hard is done; move things over a piece at a time at a leisurely pace in lots of smallish, relatively-easy-to-understand changes. This deletes or abstracts all reads of the DifferentialComment table. In particular, these things are **deleted**: - The script `undo_commits.php`, which I haven't pointed anyone at in a very long time. - The `differential.getrevisionfeedback` Conduit method, which has been marked deprecated for a year or more. - The `/stats/` interface in Differential, which should be rebuilt on Fact and has never been exposed in the UI. It does a ton of joins and such which are prohibitively difficult to migrate. This leaves a small number of reading interfaces, which I replaced with a new `DifferentialCommentQuery`. Some future change will make this actually load transactions and wrap them with DifferentialComment interfaces. Test Plan: Viewed a revision; made revision comments Reviewers: btrahan Reviewed By: btrahan CC: edward, chad, aran Maniphest Tasks: T2222 Differential Revision: https://secure.phabricator.com/D6260
2013-06-21 21:51:18 +02:00
return id(new DifferentialCommentQuery())
Migrate Differential comments to ApplicationTransactions Summary: Ref T2222. This is the big one. This migrates each `DifferentialComment` to one or more ApplicationTransactions (action, cc, reviewers, update, comment, inlines), and makes `DifferentialComment` a double-reader for ApplicationTransactions. The migration is pretty straightforward: - If a comment took an action not otherwise covered, it gets an "action" transaction. This is something like "epriestley abandoned this revision.". - If a comment updated the diff, it gets an "updated diff" transaction. Very old transactions of this type may not have a diff ID (probably only at Facebook). - If a comment added or removed reviewers, it gets a "changed reviewers" transaction. - If a comment added CCs, it gets a "subscribers" transaction. - If a comment added comment text, it gets a "comment" transaction. - For each inline attached to a comment, we generate an "inline" transaction. Most comments generate a small number of transactions, but a few generate a significant number. At HEAD, the code is basically already doing this, so comments in the last day or two already obey these rules, roughly, and will all generate only one transaction (except inlines). Because we've already preallocated PHIDs in the comment text table, we only need to write to the transaction table. NOTE: This significantly degrades Differential, making inline comments pretty much useless (they each get their own transaction, and don't show line numbers or files). The data is all fine, but the UI is garbage now. This needs to be fixed before we can deploy this to users, but it's easily separable since it's all just display code. Specifically, they look like this: {F112270} Test Plan: I've migrated locally and put things through their paces, but it's hard to catch sketchy stuff locally because most of my test data is nonsense and bad migrations wouldn't necessarily look out of place. IMPORTANT: I'm planning to push this to a branch and then shift production over to the branch, and run it for a day or two before bringing it to master. I generally feel good about this change: it's not that big since we were able to separate a lot of pieces out of it, and it's pretty straightforward. That said, it's still one of the most scary/dangerous changes we've ever made. Reviewers: btrahan CC: chad, aran Maniphest Tasks: T2222 Differential Revision: https://secure.phabricator.com/D8210
2014-02-12 00:36:58 +01:00
->withRevisionPHIDs(array($this->getPHID()))
Put all DifferentialComment loading behind DifferentialCommentQuery Summary: Ref T2222. I'm thinking about how I want to approach the Asana sync, and I want to try to do T2222 first so that we can build it cleanly on top of ApplicationTransactions. I think we can at least walk down this road a little bit and if it turns out to be scary we can take another approach. I was generally very happy with how the auth migration turned out (seemingly, it was almost completely clean), and want to pursue a similar strategy here. Basically: - Wrap the new objects in the old objects for reads/writes. - Migrate all the existing data to the new table. - Everything hard is done; move things over a piece at a time at a leisurely pace in lots of smallish, relatively-easy-to-understand changes. This deletes or abstracts all reads of the DifferentialComment table. In particular, these things are **deleted**: - The script `undo_commits.php`, which I haven't pointed anyone at in a very long time. - The `differential.getrevisionfeedback` Conduit method, which has been marked deprecated for a year or more. - The `/stats/` interface in Differential, which should be rebuilt on Fact and has never been exposed in the UI. It does a ton of joins and such which are prohibitively difficult to migrate. This leaves a small number of reading interfaces, which I replaced with a new `DifferentialCommentQuery`. Some future change will make this actually load transactions and wrap them with DifferentialComment interfaces. Test Plan: Viewed a revision; made revision comments Reviewers: btrahan Reviewed By: btrahan CC: edward, chad, aran Maniphest Tasks: T2222 Differential Revision: https://secure.phabricator.com/D6260
2013-06-21 21:51:18 +02:00
->execute();
}
2011-01-30 22:20:56 +01:00
public function loadActiveDiff() {
return id(new DifferentialDiff())->loadOneWhere(
'revisionID = %d ORDER BY id DESC LIMIT 1',
$this->getID());
}
public function save() {
if (!$this->getMailKey()) {
$this->mailKey = Filesystem::readRandomCharacters(40);
}
return parent::save();
}
2011-01-30 22:20:56 +01:00
Provide a script to completely destroy revisions Summary: Someone may or may not have accidentally uploaded secrets to Differential. Provide an administrative mechanism to permanently destroy a revision. Also fix some of the transaction handling code. Test Plan: $ ./scripts/differential/destroy_revision.php --trace D1 >>> [0] <connect> <<< [0] <connect> 1,060 us >>> [1] <query> SELECT * FROM `differential_revision` WHERE `id` = 1 <<< [1] <query> 473 us Really destroy 'D1: asdbas' forever? [y/N] y >>> [2] <connect> <<< [2] <connect> 628 us >>> [3] <query> START TRANSACTION <<< [3] <query> 190 us >>> [4] <query> SELECT * FROM `differential_diff` WHERE revisionID = 1 <<< [4] <query> 510 us >>> [5] <query> SAVEPOINT Aphront_Savepoint_1 <<< [5] <query> 122 us >>> [6] <query> SELECT * FROM `differential_changeset` WHERE diffID = 1 <<< [6] <query> 307 us >>> [7] <query> SAVEPOINT Aphront_Savepoint_2 <<< [7] <query> 241 us >>> [8] <query> SELECT * FROM `differential_hunk` WHERE changesetID = 1 <<< [8] <query> 212 us >>> [9] <query> DELETE FROM `differential_hunk` WHERE `id` = 1 <<< [9] <query> 216 us >>> [10] <query> DELETE FROM `differential_changeset` WHERE `id` = 1 <<< [10] <query> 154 us >>> [11] <query> SAVEPOINT Aphront_Savepoint_2 <<< [11] <query> 118 us >>> [12] <query> SELECT * FROM `differential_hunk` WHERE changesetID = 2 <<< [12] <query> 194 us >>> [13] <query> DELETE FROM `differential_hunk` WHERE `id` = 2 <<< [13] <query> 179 us >>> [14] <query> DELETE FROM `differential_changeset` WHERE `id` = 2 <<< [14] <query> 163 us >>> [15] <query> SAVEPOINT Aphront_Savepoint_2 <<< [15] <query> 105 us >>> [16] <query> SELECT * FROM `differential_hunk` WHERE changesetID = 3 <<< [16] <query> 211 us >>> [17] <query> DELETE FROM `differential_hunk` WHERE `id` = 3 <<< [17] <query> 159 us >>> [18] <query> DELETE FROM `differential_changeset` WHERE `id` = 3 <<< [18] <query> 152 us >>> [19] <query> SAVEPOINT Aphront_Savepoint_2 <<< [19] <query> 124 us >>> [20] <query> SELECT * FROM `differential_hunk` WHERE changesetID = 4 <<< [20] <query> 191 us >>> [21] <query> DELETE FROM `differential_hunk` WHERE `id` = 4 <<< [21] <query> 155 us >>> [22] <query> DELETE FROM `differential_changeset` WHERE `id` = 4 <<< [22] <query> 149 us >>> [23] <query> SELECT * FROM `differential_diffproperty` WHERE diffID = 1 <<< [23] <query> 242 us >>> [24] <query> DELETE FROM `differential_diffproperty` WHERE `id` = 1 <<< [24] <query> 196 us >>> [25] <query> DELETE FROM `differential_diff` WHERE `id` = 1 <<< [25] <query> 169 us >>> [26] <query> DELETE FROM `differential_relationship` WHERE revisionID = 1 <<< [26] <query> 178 us >>> [27] <query> DELETE FROM `differential_commit` WHERE revisionID = 1 <<< [27] <query> 164 us >>> [28] <query> SELECT * FROM `differential_comment` WHERE revisionID = 1 <<< [28] <query> 221 us >>> [29] <query> DELETE FROM `differential_comment` WHERE `id` = 1 <<< [29] <query> 172 us >>> [30] <query> SELECT * FROM `differential_inlinecomment` WHERE revisionID = 1 <<< [30] <query> 296 us >>> [31] <query> SELECT * FROM `differential_auxiliaryfield` WHERE revisionPHID = 'PHID-DREV-ooky7ozqukpmwget32oc' <<< [31] <query> 308 us >>> [32] <query> SELECT * FROM `differential_affectedpath` WHERE revisionID = 1 <<< [32] <query> 4,173 us >>> [33] <query> DELETE FROM `differential_revision` WHERE `id` = 1 <<< [33] <query> 231 us >>> [34] <query> COMMIT <<< [34] <query> 686 us OK, destroyed revision. Reviewers: csilvers, vrana, jungejason Reviewed By: csilvers CC: aran Differential Revision: https://secure.phabricator.com/D2796
2012-06-19 20:52:50 +02:00
public function delete() {
$this->openTransaction();
$diffs = id(new DifferentialDiffQuery())
->setViewer(PhabricatorUser::getOmnipotentUser())
->withRevisionIDs(array($this->getID()))
->execute();
Provide a script to completely destroy revisions Summary: Someone may or may not have accidentally uploaded secrets to Differential. Provide an administrative mechanism to permanently destroy a revision. Also fix some of the transaction handling code. Test Plan: $ ./scripts/differential/destroy_revision.php --trace D1 >>> [0] <connect> <<< [0] <connect> 1,060 us >>> [1] <query> SELECT * FROM `differential_revision` WHERE `id` = 1 <<< [1] <query> 473 us Really destroy 'D1: asdbas' forever? [y/N] y >>> [2] <connect> <<< [2] <connect> 628 us >>> [3] <query> START TRANSACTION <<< [3] <query> 190 us >>> [4] <query> SELECT * FROM `differential_diff` WHERE revisionID = 1 <<< [4] <query> 510 us >>> [5] <query> SAVEPOINT Aphront_Savepoint_1 <<< [5] <query> 122 us >>> [6] <query> SELECT * FROM `differential_changeset` WHERE diffID = 1 <<< [6] <query> 307 us >>> [7] <query> SAVEPOINT Aphront_Savepoint_2 <<< [7] <query> 241 us >>> [8] <query> SELECT * FROM `differential_hunk` WHERE changesetID = 1 <<< [8] <query> 212 us >>> [9] <query> DELETE FROM `differential_hunk` WHERE `id` = 1 <<< [9] <query> 216 us >>> [10] <query> DELETE FROM `differential_changeset` WHERE `id` = 1 <<< [10] <query> 154 us >>> [11] <query> SAVEPOINT Aphront_Savepoint_2 <<< [11] <query> 118 us >>> [12] <query> SELECT * FROM `differential_hunk` WHERE changesetID = 2 <<< [12] <query> 194 us >>> [13] <query> DELETE FROM `differential_hunk` WHERE `id` = 2 <<< [13] <query> 179 us >>> [14] <query> DELETE FROM `differential_changeset` WHERE `id` = 2 <<< [14] <query> 163 us >>> [15] <query> SAVEPOINT Aphront_Savepoint_2 <<< [15] <query> 105 us >>> [16] <query> SELECT * FROM `differential_hunk` WHERE changesetID = 3 <<< [16] <query> 211 us >>> [17] <query> DELETE FROM `differential_hunk` WHERE `id` = 3 <<< [17] <query> 159 us >>> [18] <query> DELETE FROM `differential_changeset` WHERE `id` = 3 <<< [18] <query> 152 us >>> [19] <query> SAVEPOINT Aphront_Savepoint_2 <<< [19] <query> 124 us >>> [20] <query> SELECT * FROM `differential_hunk` WHERE changesetID = 4 <<< [20] <query> 191 us >>> [21] <query> DELETE FROM `differential_hunk` WHERE `id` = 4 <<< [21] <query> 155 us >>> [22] <query> DELETE FROM `differential_changeset` WHERE `id` = 4 <<< [22] <query> 149 us >>> [23] <query> SELECT * FROM `differential_diffproperty` WHERE diffID = 1 <<< [23] <query> 242 us >>> [24] <query> DELETE FROM `differential_diffproperty` WHERE `id` = 1 <<< [24] <query> 196 us >>> [25] <query> DELETE FROM `differential_diff` WHERE `id` = 1 <<< [25] <query> 169 us >>> [26] <query> DELETE FROM `differential_relationship` WHERE revisionID = 1 <<< [26] <query> 178 us >>> [27] <query> DELETE FROM `differential_commit` WHERE revisionID = 1 <<< [27] <query> 164 us >>> [28] <query> SELECT * FROM `differential_comment` WHERE revisionID = 1 <<< [28] <query> 221 us >>> [29] <query> DELETE FROM `differential_comment` WHERE `id` = 1 <<< [29] <query> 172 us >>> [30] <query> SELECT * FROM `differential_inlinecomment` WHERE revisionID = 1 <<< [30] <query> 296 us >>> [31] <query> SELECT * FROM `differential_auxiliaryfield` WHERE revisionPHID = 'PHID-DREV-ooky7ozqukpmwget32oc' <<< [31] <query> 308 us >>> [32] <query> SELECT * FROM `differential_affectedpath` WHERE revisionID = 1 <<< [32] <query> 4,173 us >>> [33] <query> DELETE FROM `differential_revision` WHERE `id` = 1 <<< [33] <query> 231 us >>> [34] <query> COMMIT <<< [34] <query> 686 us OK, destroyed revision. Reviewers: csilvers, vrana, jungejason Reviewed By: csilvers CC: aran Differential Revision: https://secure.phabricator.com/D2796
2012-06-19 20:52:50 +02:00
foreach ($diffs as $diff) {
$diff->delete();
}
$conn_w = $this->establishConnection('w');
queryfx(
$conn_w,
'DELETE FROM %T WHERE revisionID = %d',
self::TABLE_COMMIT,
$this->getID());
Put all DifferentialComment loading behind DifferentialCommentQuery Summary: Ref T2222. I'm thinking about how I want to approach the Asana sync, and I want to try to do T2222 first so that we can build it cleanly on top of ApplicationTransactions. I think we can at least walk down this road a little bit and if it turns out to be scary we can take another approach. I was generally very happy with how the auth migration turned out (seemingly, it was almost completely clean), and want to pursue a similar strategy here. Basically: - Wrap the new objects in the old objects for reads/writes. - Migrate all the existing data to the new table. - Everything hard is done; move things over a piece at a time at a leisurely pace in lots of smallish, relatively-easy-to-understand changes. This deletes or abstracts all reads of the DifferentialComment table. In particular, these things are **deleted**: - The script `undo_commits.php`, which I haven't pointed anyone at in a very long time. - The `differential.getrevisionfeedback` Conduit method, which has been marked deprecated for a year or more. - The `/stats/` interface in Differential, which should be rebuilt on Fact and has never been exposed in the UI. It does a ton of joins and such which are prohibitively difficult to migrate. This leaves a small number of reading interfaces, which I replaced with a new `DifferentialCommentQuery`. Some future change will make this actually load transactions and wrap them with DifferentialComment interfaces. Test Plan: Viewed a revision; made revision comments Reviewers: btrahan Reviewed By: btrahan CC: edward, chad, aran Maniphest Tasks: T2222 Differential Revision: https://secure.phabricator.com/D6260
2013-06-21 21:51:18 +02:00
$comments = id(new DifferentialCommentQuery())
Migrate Differential comments to ApplicationTransactions Summary: Ref T2222. This is the big one. This migrates each `DifferentialComment` to one or more ApplicationTransactions (action, cc, reviewers, update, comment, inlines), and makes `DifferentialComment` a double-reader for ApplicationTransactions. The migration is pretty straightforward: - If a comment took an action not otherwise covered, it gets an "action" transaction. This is something like "epriestley abandoned this revision.". - If a comment updated the diff, it gets an "updated diff" transaction. Very old transactions of this type may not have a diff ID (probably only at Facebook). - If a comment added or removed reviewers, it gets a "changed reviewers" transaction. - If a comment added CCs, it gets a "subscribers" transaction. - If a comment added comment text, it gets a "comment" transaction. - For each inline attached to a comment, we generate an "inline" transaction. Most comments generate a small number of transactions, but a few generate a significant number. At HEAD, the code is basically already doing this, so comments in the last day or two already obey these rules, roughly, and will all generate only one transaction (except inlines). Because we've already preallocated PHIDs in the comment text table, we only need to write to the transaction table. NOTE: This significantly degrades Differential, making inline comments pretty much useless (they each get their own transaction, and don't show line numbers or files). The data is all fine, but the UI is garbage now. This needs to be fixed before we can deploy this to users, but it's easily separable since it's all just display code. Specifically, they look like this: {F112270} Test Plan: I've migrated locally and put things through their paces, but it's hard to catch sketchy stuff locally because most of my test data is nonsense and bad migrations wouldn't necessarily look out of place. IMPORTANT: I'm planning to push this to a branch and then shift production over to the branch, and run it for a day or two before bringing it to master. I generally feel good about this change: it's not that big since we were able to separate a lot of pieces out of it, and it's pretty straightforward. That said, it's still one of the most scary/dangerous changes we've ever made. Reviewers: btrahan CC: chad, aran Maniphest Tasks: T2222 Differential Revision: https://secure.phabricator.com/D8210
2014-02-12 00:36:58 +01:00
->withRevisionPHIDs(array($this->getPHID()))
Put all DifferentialComment loading behind DifferentialCommentQuery Summary: Ref T2222. I'm thinking about how I want to approach the Asana sync, and I want to try to do T2222 first so that we can build it cleanly on top of ApplicationTransactions. I think we can at least walk down this road a little bit and if it turns out to be scary we can take another approach. I was generally very happy with how the auth migration turned out (seemingly, it was almost completely clean), and want to pursue a similar strategy here. Basically: - Wrap the new objects in the old objects for reads/writes. - Migrate all the existing data to the new table. - Everything hard is done; move things over a piece at a time at a leisurely pace in lots of smallish, relatively-easy-to-understand changes. This deletes or abstracts all reads of the DifferentialComment table. In particular, these things are **deleted**: - The script `undo_commits.php`, which I haven't pointed anyone at in a very long time. - The `differential.getrevisionfeedback` Conduit method, which has been marked deprecated for a year or more. - The `/stats/` interface in Differential, which should be rebuilt on Fact and has never been exposed in the UI. It does a ton of joins and such which are prohibitively difficult to migrate. This leaves a small number of reading interfaces, which I replaced with a new `DifferentialCommentQuery`. Some future change will make this actually load transactions and wrap them with DifferentialComment interfaces. Test Plan: Viewed a revision; made revision comments Reviewers: btrahan Reviewed By: btrahan CC: edward, chad, aran Maniphest Tasks: T2222 Differential Revision: https://secure.phabricator.com/D6260
2013-06-21 21:51:18 +02:00
->execute();
Provide a script to completely destroy revisions Summary: Someone may or may not have accidentally uploaded secrets to Differential. Provide an administrative mechanism to permanently destroy a revision. Also fix some of the transaction handling code. Test Plan: $ ./scripts/differential/destroy_revision.php --trace D1 >>> [0] <connect> <<< [0] <connect> 1,060 us >>> [1] <query> SELECT * FROM `differential_revision` WHERE `id` = 1 <<< [1] <query> 473 us Really destroy 'D1: asdbas' forever? [y/N] y >>> [2] <connect> <<< [2] <connect> 628 us >>> [3] <query> START TRANSACTION <<< [3] <query> 190 us >>> [4] <query> SELECT * FROM `differential_diff` WHERE revisionID = 1 <<< [4] <query> 510 us >>> [5] <query> SAVEPOINT Aphront_Savepoint_1 <<< [5] <query> 122 us >>> [6] <query> SELECT * FROM `differential_changeset` WHERE diffID = 1 <<< [6] <query> 307 us >>> [7] <query> SAVEPOINT Aphront_Savepoint_2 <<< [7] <query> 241 us >>> [8] <query> SELECT * FROM `differential_hunk` WHERE changesetID = 1 <<< [8] <query> 212 us >>> [9] <query> DELETE FROM `differential_hunk` WHERE `id` = 1 <<< [9] <query> 216 us >>> [10] <query> DELETE FROM `differential_changeset` WHERE `id` = 1 <<< [10] <query> 154 us >>> [11] <query> SAVEPOINT Aphront_Savepoint_2 <<< [11] <query> 118 us >>> [12] <query> SELECT * FROM `differential_hunk` WHERE changesetID = 2 <<< [12] <query> 194 us >>> [13] <query> DELETE FROM `differential_hunk` WHERE `id` = 2 <<< [13] <query> 179 us >>> [14] <query> DELETE FROM `differential_changeset` WHERE `id` = 2 <<< [14] <query> 163 us >>> [15] <query> SAVEPOINT Aphront_Savepoint_2 <<< [15] <query> 105 us >>> [16] <query> SELECT * FROM `differential_hunk` WHERE changesetID = 3 <<< [16] <query> 211 us >>> [17] <query> DELETE FROM `differential_hunk` WHERE `id` = 3 <<< [17] <query> 159 us >>> [18] <query> DELETE FROM `differential_changeset` WHERE `id` = 3 <<< [18] <query> 152 us >>> [19] <query> SAVEPOINT Aphront_Savepoint_2 <<< [19] <query> 124 us >>> [20] <query> SELECT * FROM `differential_hunk` WHERE changesetID = 4 <<< [20] <query> 191 us >>> [21] <query> DELETE FROM `differential_hunk` WHERE `id` = 4 <<< [21] <query> 155 us >>> [22] <query> DELETE FROM `differential_changeset` WHERE `id` = 4 <<< [22] <query> 149 us >>> [23] <query> SELECT * FROM `differential_diffproperty` WHERE diffID = 1 <<< [23] <query> 242 us >>> [24] <query> DELETE FROM `differential_diffproperty` WHERE `id` = 1 <<< [24] <query> 196 us >>> [25] <query> DELETE FROM `differential_diff` WHERE `id` = 1 <<< [25] <query> 169 us >>> [26] <query> DELETE FROM `differential_relationship` WHERE revisionID = 1 <<< [26] <query> 178 us >>> [27] <query> DELETE FROM `differential_commit` WHERE revisionID = 1 <<< [27] <query> 164 us >>> [28] <query> SELECT * FROM `differential_comment` WHERE revisionID = 1 <<< [28] <query> 221 us >>> [29] <query> DELETE FROM `differential_comment` WHERE `id` = 1 <<< [29] <query> 172 us >>> [30] <query> SELECT * FROM `differential_inlinecomment` WHERE revisionID = 1 <<< [30] <query> 296 us >>> [31] <query> SELECT * FROM `differential_auxiliaryfield` WHERE revisionPHID = 'PHID-DREV-ooky7ozqukpmwget32oc' <<< [31] <query> 308 us >>> [32] <query> SELECT * FROM `differential_affectedpath` WHERE revisionID = 1 <<< [32] <query> 4,173 us >>> [33] <query> DELETE FROM `differential_revision` WHERE `id` = 1 <<< [33] <query> 231 us >>> [34] <query> COMMIT <<< [34] <query> 686 us OK, destroyed revision. Reviewers: csilvers, vrana, jungejason Reviewed By: csilvers CC: aran Differential Revision: https://secure.phabricator.com/D2796
2012-06-19 20:52:50 +02:00
foreach ($comments as $comment) {
$comment->delete();
}
$inlines = id(new DifferentialInlineCommentQuery())
->withRevisionIDs(array($this->getID()))
->execute();
Provide a script to completely destroy revisions Summary: Someone may or may not have accidentally uploaded secrets to Differential. Provide an administrative mechanism to permanently destroy a revision. Also fix some of the transaction handling code. Test Plan: $ ./scripts/differential/destroy_revision.php --trace D1 >>> [0] <connect> <<< [0] <connect> 1,060 us >>> [1] <query> SELECT * FROM `differential_revision` WHERE `id` = 1 <<< [1] <query> 473 us Really destroy 'D1: asdbas' forever? [y/N] y >>> [2] <connect> <<< [2] <connect> 628 us >>> [3] <query> START TRANSACTION <<< [3] <query> 190 us >>> [4] <query> SELECT * FROM `differential_diff` WHERE revisionID = 1 <<< [4] <query> 510 us >>> [5] <query> SAVEPOINT Aphront_Savepoint_1 <<< [5] <query> 122 us >>> [6] <query> SELECT * FROM `differential_changeset` WHERE diffID = 1 <<< [6] <query> 307 us >>> [7] <query> SAVEPOINT Aphront_Savepoint_2 <<< [7] <query> 241 us >>> [8] <query> SELECT * FROM `differential_hunk` WHERE changesetID = 1 <<< [8] <query> 212 us >>> [9] <query> DELETE FROM `differential_hunk` WHERE `id` = 1 <<< [9] <query> 216 us >>> [10] <query> DELETE FROM `differential_changeset` WHERE `id` = 1 <<< [10] <query> 154 us >>> [11] <query> SAVEPOINT Aphront_Savepoint_2 <<< [11] <query> 118 us >>> [12] <query> SELECT * FROM `differential_hunk` WHERE changesetID = 2 <<< [12] <query> 194 us >>> [13] <query> DELETE FROM `differential_hunk` WHERE `id` = 2 <<< [13] <query> 179 us >>> [14] <query> DELETE FROM `differential_changeset` WHERE `id` = 2 <<< [14] <query> 163 us >>> [15] <query> SAVEPOINT Aphront_Savepoint_2 <<< [15] <query> 105 us >>> [16] <query> SELECT * FROM `differential_hunk` WHERE changesetID = 3 <<< [16] <query> 211 us >>> [17] <query> DELETE FROM `differential_hunk` WHERE `id` = 3 <<< [17] <query> 159 us >>> [18] <query> DELETE FROM `differential_changeset` WHERE `id` = 3 <<< [18] <query> 152 us >>> [19] <query> SAVEPOINT Aphront_Savepoint_2 <<< [19] <query> 124 us >>> [20] <query> SELECT * FROM `differential_hunk` WHERE changesetID = 4 <<< [20] <query> 191 us >>> [21] <query> DELETE FROM `differential_hunk` WHERE `id` = 4 <<< [21] <query> 155 us >>> [22] <query> DELETE FROM `differential_changeset` WHERE `id` = 4 <<< [22] <query> 149 us >>> [23] <query> SELECT * FROM `differential_diffproperty` WHERE diffID = 1 <<< [23] <query> 242 us >>> [24] <query> DELETE FROM `differential_diffproperty` WHERE `id` = 1 <<< [24] <query> 196 us >>> [25] <query> DELETE FROM `differential_diff` WHERE `id` = 1 <<< [25] <query> 169 us >>> [26] <query> DELETE FROM `differential_relationship` WHERE revisionID = 1 <<< [26] <query> 178 us >>> [27] <query> DELETE FROM `differential_commit` WHERE revisionID = 1 <<< [27] <query> 164 us >>> [28] <query> SELECT * FROM `differential_comment` WHERE revisionID = 1 <<< [28] <query> 221 us >>> [29] <query> DELETE FROM `differential_comment` WHERE `id` = 1 <<< [29] <query> 172 us >>> [30] <query> SELECT * FROM `differential_inlinecomment` WHERE revisionID = 1 <<< [30] <query> 296 us >>> [31] <query> SELECT * FROM `differential_auxiliaryfield` WHERE revisionPHID = 'PHID-DREV-ooky7ozqukpmwget32oc' <<< [31] <query> 308 us >>> [32] <query> SELECT * FROM `differential_affectedpath` WHERE revisionID = 1 <<< [32] <query> 4,173 us >>> [33] <query> DELETE FROM `differential_revision` WHERE `id` = 1 <<< [33] <query> 231 us >>> [34] <query> COMMIT <<< [34] <query> 686 us OK, destroyed revision. Reviewers: csilvers, vrana, jungejason Reviewed By: csilvers CC: aran Differential Revision: https://secure.phabricator.com/D2796
2012-06-19 20:52:50 +02:00
foreach ($inlines as $inline) {
$inline->delete();
}
$fields = id(new DifferentialAuxiliaryField())->loadAllWhere(
'revisionPHID = %s',
$this->getPHID());
foreach ($fields as $field) {
$field->delete();
}
// we have to do paths a little differentally as they do not have
// an id or phid column for delete() to act on
$dummy_path = new DifferentialAffectedPath();
queryfx(
$conn_w,
'DELETE FROM %T WHERE revisionID = %d',
$dummy_path->getTableName(),
Provide a script to completely destroy revisions Summary: Someone may or may not have accidentally uploaded secrets to Differential. Provide an administrative mechanism to permanently destroy a revision. Also fix some of the transaction handling code. Test Plan: $ ./scripts/differential/destroy_revision.php --trace D1 >>> [0] <connect> <<< [0] <connect> 1,060 us >>> [1] <query> SELECT * FROM `differential_revision` WHERE `id` = 1 <<< [1] <query> 473 us Really destroy 'D1: asdbas' forever? [y/N] y >>> [2] <connect> <<< [2] <connect> 628 us >>> [3] <query> START TRANSACTION <<< [3] <query> 190 us >>> [4] <query> SELECT * FROM `differential_diff` WHERE revisionID = 1 <<< [4] <query> 510 us >>> [5] <query> SAVEPOINT Aphront_Savepoint_1 <<< [5] <query> 122 us >>> [6] <query> SELECT * FROM `differential_changeset` WHERE diffID = 1 <<< [6] <query> 307 us >>> [7] <query> SAVEPOINT Aphront_Savepoint_2 <<< [7] <query> 241 us >>> [8] <query> SELECT * FROM `differential_hunk` WHERE changesetID = 1 <<< [8] <query> 212 us >>> [9] <query> DELETE FROM `differential_hunk` WHERE `id` = 1 <<< [9] <query> 216 us >>> [10] <query> DELETE FROM `differential_changeset` WHERE `id` = 1 <<< [10] <query> 154 us >>> [11] <query> SAVEPOINT Aphront_Savepoint_2 <<< [11] <query> 118 us >>> [12] <query> SELECT * FROM `differential_hunk` WHERE changesetID = 2 <<< [12] <query> 194 us >>> [13] <query> DELETE FROM `differential_hunk` WHERE `id` = 2 <<< [13] <query> 179 us >>> [14] <query> DELETE FROM `differential_changeset` WHERE `id` = 2 <<< [14] <query> 163 us >>> [15] <query> SAVEPOINT Aphront_Savepoint_2 <<< [15] <query> 105 us >>> [16] <query> SELECT * FROM `differential_hunk` WHERE changesetID = 3 <<< [16] <query> 211 us >>> [17] <query> DELETE FROM `differential_hunk` WHERE `id` = 3 <<< [17] <query> 159 us >>> [18] <query> DELETE FROM `differential_changeset` WHERE `id` = 3 <<< [18] <query> 152 us >>> [19] <query> SAVEPOINT Aphront_Savepoint_2 <<< [19] <query> 124 us >>> [20] <query> SELECT * FROM `differential_hunk` WHERE changesetID = 4 <<< [20] <query> 191 us >>> [21] <query> DELETE FROM `differential_hunk` WHERE `id` = 4 <<< [21] <query> 155 us >>> [22] <query> DELETE FROM `differential_changeset` WHERE `id` = 4 <<< [22] <query> 149 us >>> [23] <query> SELECT * FROM `differential_diffproperty` WHERE diffID = 1 <<< [23] <query> 242 us >>> [24] <query> DELETE FROM `differential_diffproperty` WHERE `id` = 1 <<< [24] <query> 196 us >>> [25] <query> DELETE FROM `differential_diff` WHERE `id` = 1 <<< [25] <query> 169 us >>> [26] <query> DELETE FROM `differential_relationship` WHERE revisionID = 1 <<< [26] <query> 178 us >>> [27] <query> DELETE FROM `differential_commit` WHERE revisionID = 1 <<< [27] <query> 164 us >>> [28] <query> SELECT * FROM `differential_comment` WHERE revisionID = 1 <<< [28] <query> 221 us >>> [29] <query> DELETE FROM `differential_comment` WHERE `id` = 1 <<< [29] <query> 172 us >>> [30] <query> SELECT * FROM `differential_inlinecomment` WHERE revisionID = 1 <<< [30] <query> 296 us >>> [31] <query> SELECT * FROM `differential_auxiliaryfield` WHERE revisionPHID = 'PHID-DREV-ooky7ozqukpmwget32oc' <<< [31] <query> 308 us >>> [32] <query> SELECT * FROM `differential_affectedpath` WHERE revisionID = 1 <<< [32] <query> 4,173 us >>> [33] <query> DELETE FROM `differential_revision` WHERE `id` = 1 <<< [33] <query> 231 us >>> [34] <query> COMMIT <<< [34] <query> 686 us OK, destroyed revision. Reviewers: csilvers, vrana, jungejason Reviewed By: csilvers CC: aran Differential Revision: https://secure.phabricator.com/D2796
2012-06-19 20:52:50 +02:00
$this->getID());
$result = parent::delete();
$this->saveTransaction();
return $result;
}
2011-01-26 02:17:19 +01:00
public function loadRelationships() {
2011-01-27 03:46:34 +01:00
if (!$this->getID()) {
$this->relationships = array();
return;
}
$data = array();
$subscriber_phids = PhabricatorEdgeQuery::loadDestinationPHIDs(
$this->getPHID(),
PhabricatorEdgeConfig::TYPE_OBJECT_HAS_SUBSCRIBER);
$subscriber_phids = array_reverse($subscriber_phids);
foreach ($subscriber_phids as $phid) {
$data[] = array(
'relation' => self::RELATION_SUBSCRIBED,
'objectPHID' => $phid,
'reasonPHID' => null,
);
}
$reviewer_phids = PhabricatorEdgeQuery::loadDestinationPHIDs(
$this->getPHID(),
PhabricatorEdgeConfig::TYPE_DREV_HAS_REVIEWER);
$reviewer_phids = array_reverse($reviewer_phids);
foreach ($reviewer_phids as $phid) {
$data[] = array(
'relation' => self::RELATION_REVIEWER,
'objectPHID' => $phid,
'reasonPHID' => null,
);
}
return $this->attachRelationships($data);
}
2011-01-27 03:46:34 +01:00
public function attachRelationships(array $relationships) {
$this->relationships = igroup($relationships, 'relation');
2011-01-27 03:46:34 +01:00
return $this;
2011-01-26 02:17:19 +01:00
}
2011-01-27 03:46:34 +01:00
2011-01-26 02:17:19 +01:00
public function getReviewers() {
2011-01-27 03:46:34 +01:00
return $this->getRelatedPHIDs(self::RELATION_REVIEWER);
2011-01-26 02:17:19 +01:00
}
2011-01-27 03:46:34 +01:00
2011-01-26 02:17:19 +01:00
public function getCCPHIDs() {
2011-01-27 03:46:34 +01:00
return $this->getRelatedPHIDs(self::RELATION_SUBSCRIBED);
}
private function getRelatedPHIDs($relation) {
$this->assertAttached($this->relationships);
2011-02-03 04:38:43 +01:00
return ipull($this->getRawRelations($relation), 'objectPHID');
2011-01-27 03:46:34 +01:00
}
public function getRawRelations($relation) {
return idx($this->relationships, $relation, array());
}
public function getPrimaryReviewer() {
$reviewers = $this->getReviewers();
$last = $this->lastReviewerPHID;
if (!$last || !in_array($last, $reviewers)) {
return head($this->getReviewers());
}
return $last;
}
public function loadReviewedBy() {
$reviewer = null;
if ($this->status == ArcanistDifferentialRevisionStatus::ACCEPTED ||
$this->status == ArcanistDifferentialRevisionStatus::CLOSED) {
$comments = $this->loadComments();
foreach ($comments as $comment) {
$action = $comment->getAction();
if ($action == DifferentialAction::ACTION_ACCEPT) {
$reviewer = $comment->getAuthorPHID();
} else if ($action == DifferentialAction::ACTION_REJECT ||
$action == DifferentialAction::ACTION_ABANDON ||
$action == DifferentialAction::ACTION_RETHINK) {
$reviewer = null;
}
}
}
return $reviewer;
}
public function getHashes() {
return $this->assertAttached($this->hashes);
}
public function attachHashes(array $hashes) {
$this->hashes = $hashes;
return $this;
}
public function getCapabilities() {
return array(
PhabricatorPolicyCapability::CAN_VIEW,
PhabricatorPolicyCapability::CAN_EDIT,
);
}
public function getPolicy($capability) {
switch ($capability) {
case PhabricatorPolicyCapability::CAN_VIEW:
return $this->getViewPolicy();
case PhabricatorPolicyCapability::CAN_EDIT:
return $this->getEditPolicy();
}
}
public function hasAutomaticCapability($capability, PhabricatorUser $user) {
// A revision's author (which effectively means "owner" after we added
// commandeering) can always view and edit it.
$author_phid = $this->getAuthorPHID();
if ($author_phid) {
if ($user->getPHID() == $author_phid) {
return true;
}
}
return false;
}
public function describeAutomaticCapability($capability) {
$description = array(
pht('The owner of a revision can always view and edit it.'),
);
switch ($capability) {
case PhabricatorPolicyCapability::CAN_VIEW:
$description[] = pht(
"A revision's reviewers can always view it.");
$description[] = pht(
'If a revision belongs to a repository, other users must be able '.
'to view the repository in order to view the revision.');
break;
}
return $description;
}
public function getUsersToNotifyOfTokenGiven() {
return array(
$this->getAuthorPHID(),
);
}
public function getReviewerStatus() {
return $this->assertAttached($this->reviewerStatus);
}
public function attachReviewerStatus(array $reviewers) {
assert_instances_of($reviewers, 'DifferentialReviewer');
$this->reviewerStatus = $reviewers;
return $this;
}
public function getRepository() {
return $this->assertAttached($this->repository);
}
public function attachRepository(PhabricatorRepository $repository = null) {
$this->repository = $repository;
return $this;
}
public function isClosed() {
return DifferentialRevisionStatus::isClosedStatus($this->getStatus());
}
public function getFlag(PhabricatorUser $viewer) {
return $this->assertAttachedKey($this->flags, $viewer->getPHID());
}
public function attachFlag(
PhabricatorUser $viewer,
PhabricatorFlag $flag = null) {
$this->flags[$viewer->getPHID()] = $flag;
return $this;
}
public function getDrafts(PhabricatorUser $viewer) {
return $this->assertAttachedKey($this->drafts, $viewer->getPHID());
}
public function attachDrafts(PhabricatorUser $viewer, array $drafts) {
$this->drafts[$viewer->getPHID()] = $drafts;
return $this;
}
/* -( HarbormasterBuildableInterface )------------------------------------- */
public function getHarbormasterBuildablePHID() {
return $this->loadActiveDiff()->getPHID();
}
public function getHarbormasterContainerPHID() {
return $this->getPHID();
}
/* -( PhabricatorSubscribableInterface )----------------------------------- */
public function isAutomaticallySubscribed($phid) {
// TODO: Reviewers are also automatically subscribed, but that data may
// not always be loaded, so be conservative for now. All the editing code
// has checks around this already.
return ($phid == $this->getAuthorPHID());
}
public function shouldShowSubscribersProperty() {
// TODO: For now, Differential has its own stuff.
return false;
}
public function shouldAllowSubscription($phid) {
// TODO: For now, Differential has its own stuff.
return false;
}
/* -( PhabricatorCustomFieldInterface )------------------------------------ */
public function getCustomFieldSpecificationForRole($role) {
$fields = array(
new DifferentialTitleField(),
new DifferentialSummaryField(),
new DifferentialTestPlanField(),
new DifferentialReviewersField(),
new DifferentialSubscribersField(),
new DifferentialRepositoryField(),
new DifferentialViewPolicyField(),
new DifferentialEditPolicyField(),
);
return array_fill_keys(
mpull($fields, 'getFieldKey'),
array('disabled' => false));
}
public function getCustomFieldBaseClass() {
return 'DifferentialCustomField';
}
public function getCustomFields() {
return $this->assertAttached($this->customFields);
}
public function attachCustomFields(PhabricatorCustomFieldAttachment $fields) {
$this->customFields = $fields;
return $this;
}
2011-01-24 20:01:53 +01:00
}