Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/phabricator
Path: blob/master/src/applications/differential/query/DifferentialChangesetQuery.php
12262 views
1
<?php
2
3
final class DifferentialChangesetQuery
4
extends PhabricatorCursorPagedPolicyAwareQuery {
5
6
private $ids;
7
private $phids;
8
private $diffPHIDs;
9
10
private $diffs;
11
12
private $needAttachToDiffs;
13
private $needHunks;
14
15
public function withIDs(array $ids) {
16
$this->ids = $ids;
17
return $this;
18
}
19
20
public function withPHIDs(array $phids) {
21
$this->phids = $phids;
22
return $this;
23
}
24
25
public function withDiffs(array $diffs) {
26
assert_instances_of($diffs, 'DifferentialDiff');
27
$this->diffs = $diffs;
28
return $this;
29
}
30
31
public function withDiffPHIDs(array $phids) {
32
$this->diffPHIDs = $phids;
33
return $this;
34
}
35
36
public function needAttachToDiffs($attach) {
37
$this->needAttachToDiffs = $attach;
38
return $this;
39
}
40
41
public function needHunks($need) {
42
$this->needHunks = $need;
43
return $this;
44
}
45
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());
53
}
54
}
55
}
56
57
public function newResultObject() {
58
return new DifferentialChangeset();
59
}
60
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.
65
if ($this->diffs) {
66
$have_diffs = mpull($this->diffs, null, 'getID');
67
} else {
68
$have_diffs = array();
69
}
70
71
$must_load = 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]);
76
} else {
77
$must_load[$key] = $changeset;
78
}
79
}
80
81
// Load all the diffs we don't have.
82
$need_diff_ids = mpull($must_load, 'getDiffID');
83
$more_diffs = array();
84
if ($need_diff_ids) {
85
$more_diffs = id(new DifferentialDiffQuery())
86
->setViewer($this->getViewer())
87
->setParentQuery($this)
88
->withIDs($need_diff_ids)
89
->execute();
90
$more_diffs = mpull($more_diffs, null, 'getID');
91
}
92
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]);
98
} else {
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]);
102
}
103
}
104
105
return $changesets;
106
}
107
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);
114
}
115
}
116
117
if ($this->needHunks) {
118
id(new DifferentialHunkQuery())
119
->setViewer($this->getViewer())
120
->setParentQuery($this)
121
->withChangesets($changesets)
122
->needAttachToChangesets(true)
123
->execute();
124
}
125
126
return $changesets;
127
}
128
129
protected function buildWhereClauseParts(AphrontDatabaseConnection $conn) {
130
$where = parent::buildWhereClauseParts($conn);
131
132
if ($this->diffs !== null) {
133
$where[] = qsprintf(
134
$conn,
135
'diffID IN (%Ld)',
136
mpull($this->diffs, 'getID'));
137
}
138
139
if ($this->ids !== null) {
140
$where[] = qsprintf(
141
$conn,
142
'id IN (%Ld)',
143
$this->ids);
144
}
145
146
if ($this->phids !== null) {
147
$where[] = qsprintf(
148
$conn,
149
'phid IN (%Ls)',
150
$this->phids);
151
}
152
153
if ($this->diffPHIDs !== null) {
154
$diff_ids = queryfx_all(
155
$conn,
156
'SELECT id FROM %R WHERE phid IN (%Ls)',
157
new DifferentialDiff(),
158
$this->diffPHIDs);
159
$diff_ids = ipull($diff_ids, 'id', null);
160
161
if (!$diff_ids) {
162
throw new PhabricatorEmptyQueryException();
163
}
164
165
$where[] = qsprintf(
166
$conn,
167
'diffID IN (%Ld)',
168
$diff_ids);
169
}
170
171
return $where;
172
}
173
174
public function getQueryApplicationClass() {
175
return 'PhabricatorDifferentialApplication';
176
}
177
178
}
179
180