3 final class DifferentialChangesetQuery
4 extends PhabricatorCursorPagedPolicyAwareQuery
{
12 private $needAttachToDiffs;
15 public function withIDs(array $ids) {
20 public function withPHIDs(array $phids) {
21 $this->phids
= $phids;
25 public function withDiffs(array $diffs) {
26 assert_instances_of($diffs, 'DifferentialDiff');
27 $this->diffs
= $diffs;
31 public function withDiffPHIDs(array $phids) {
32 $this->diffPHIDs
= $phids;
36 public function needAttachToDiffs($attach) {
37 $this->needAttachToDiffs
= $attach;
41 public function needHunks($need) {
42 $this->needHunks
= $need;
46 protected function willExecute() {
47 // If we fail to load any changesets (which is possible in the case of an
48 // empty commit) we'll never call didFilterPage(). Attach empty changeset
49 // lists now so that we end up with the right result.
50 if ($this->needAttachToDiffs
) {
51 foreach ($this->diffs
as $diff) {
52 $diff->attachChangesets(array());
57 public function newResultObject() {
58 return new DifferentialChangeset();
61 protected function willFilterPage(array $changesets) {
62 // First, attach all the diffs we already have. We can just do this
63 // directly without worrying about querying for them. When we don't have
64 // a diff, record that we need to load it.
66 $have_diffs = mpull($this->diffs
, null, 'getID');
68 $have_diffs = array();
72 foreach ($changesets as $key => $changeset) {
73 $diff_id = $changeset->getDiffID();
74 if (isset($have_diffs[$diff_id])) {
75 $changeset->attachDiff($have_diffs[$diff_id]);
77 $must_load[$key] = $changeset;
81 // Load all the diffs we don't have.
82 $need_diff_ids = mpull($must_load, 'getDiffID');
83 $more_diffs = array();
85 $more_diffs = id(new DifferentialDiffQuery())
86 ->setViewer($this->getViewer())
87 ->setParentQuery($this)
88 ->withIDs($need_diff_ids)
90 $more_diffs = mpull($more_diffs, null, 'getID');
93 // Attach the diffs we loaded.
94 foreach ($must_load as $key => $changeset) {
95 $diff_id = $changeset->getDiffID();
96 if (isset($more_diffs[$diff_id])) {
97 $changeset->attachDiff($more_diffs[$diff_id]);
99 // We didn't have the diff, and could not load it (it does not exist,
100 // or we can't see it), so filter this result out.
101 unset($changesets[$key]);
108 protected function didFilterPage(array $changesets) {
109 if ($this->needAttachToDiffs
) {
110 $changeset_groups = mgroup($changesets, 'getDiffID');
111 foreach ($this->diffs
as $diff) {
112 $diff_changesets = idx($changeset_groups, $diff->getID(), array());
113 $diff->attachChangesets($diff_changesets);
117 if ($this->needHunks
) {
118 id(new DifferentialHunkQuery())
119 ->setViewer($this->getViewer())
120 ->setParentQuery($this)
121 ->withChangesets($changesets)
122 ->needAttachToChangesets(true)
129 protected function buildWhereClauseParts(AphrontDatabaseConnection
$conn) {
130 $where = parent
::buildWhereClauseParts($conn);
132 if ($this->diffs
!== null) {
136 mpull($this->diffs
, 'getID'));
139 if ($this->ids
!== null) {
146 if ($this->phids
!== null) {
153 if ($this->diffPHIDs
!== null) {
154 $diff_ids = queryfx_all(
156 'SELECT id FROM %R WHERE phid IN (%Ls)',
157 new DifferentialDiff(),
159 $diff_ids = ipull($diff_ids, 'id', null);
162 throw new PhabricatorEmptyQueryException();
174 public function getQueryApplicationClass() {
175 return 'PhabricatorDifferentialApplication';