Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/phabricator
Path: blob/master/src/applications/diffusion/query/DiffusionQuery.php
12242 views
1
<?php
2
3
abstract class DiffusionQuery extends PhabricatorQuery {
4
5
private $request;
6
7
final protected function __construct() {
8
// <protected>
9
}
10
11
protected static function newQueryObject(
12
$base_class,
13
DiffusionRequest $request) {
14
15
$repository = $request->getRepository();
16
17
$obj = self::initQueryObject($base_class, $repository);
18
$obj->request = $request;
19
20
return $obj;
21
}
22
23
final protected static function initQueryObject(
24
$base_class,
25
PhabricatorRepository $repository) {
26
27
$map = array(
28
PhabricatorRepositoryType::REPOSITORY_TYPE_GIT => 'Git',
29
PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL => 'Mercurial',
30
PhabricatorRepositoryType::REPOSITORY_TYPE_SVN => 'Svn',
31
);
32
33
$name = idx($map, $repository->getVersionControlSystem());
34
if (!$name) {
35
throw new Exception(pht('Unsupported VCS!'));
36
}
37
38
$class = str_replace('Diffusion', 'Diffusion'.$name, $base_class);
39
$obj = new $class();
40
return $obj;
41
}
42
43
final protected function getRequest() {
44
return $this->request;
45
}
46
47
final public static function callConduitWithDiffusionRequest(
48
PhabricatorUser $user,
49
DiffusionRequest $drequest,
50
$method,
51
array $params = array(),
52
$return_future = false) {
53
54
$repository = $drequest->getRepository();
55
56
$core_params = array(
57
'repository' => $repository->getPHID(),
58
);
59
60
if ($drequest->getBranch() !== null) {
61
$core_params['branch'] = $drequest->getBranch();
62
}
63
64
// If the method we're calling doesn't actually take some of the implicit
65
// parameters we derive from the DiffusionRequest, omit them.
66
$method_object = ConduitAPIMethod::getConduitMethod($method);
67
$method_params = $method_object->getParamTypes();
68
foreach ($core_params as $key => $value) {
69
if (empty($method_params[$key])) {
70
unset($core_params[$key]);
71
}
72
}
73
74
$params = $params + $core_params;
75
76
$future = $repository->newConduitFuture(
77
$user,
78
$method,
79
$params,
80
$drequest->getIsClusterRequest());
81
82
if (!$return_future) {
83
return $future->resolve();
84
}
85
86
return $future;
87
}
88
89
public function execute() {
90
return $this->executeQuery();
91
}
92
93
abstract protected function executeQuery();
94
95
96
/* -( Query Utilities )---------------------------------------------------- */
97
98
99
final public static function loadCommitsByIdentifiers(
100
array $identifiers,
101
DiffusionRequest $drequest) {
102
if (!$identifiers) {
103
return array();
104
}
105
106
$commits = array();
107
$commit_data = array();
108
109
$repository = $drequest->getRepository();
110
111
$commits = id(new PhabricatorRepositoryCommit())->loadAllWhere(
112
'repositoryID = %d AND commitIdentifier IN (%Ls)',
113
$repository->getID(),
114
$identifiers);
115
$commits = mpull($commits, null, 'getCommitIdentifier');
116
117
// Build empty commit objects for every commit, so we can show unparsed
118
// commits in history views (as "Importing") instead of not showing them.
119
// This makes the process of importing and parsing commits clearer to the
120
// user.
121
122
$commit_list = array();
123
foreach ($identifiers as $identifier) {
124
$commit_obj = idx($commits, $identifier);
125
if (!$commit_obj) {
126
$commit_obj = new PhabricatorRepositoryCommit();
127
$commit_obj->setRepositoryID($repository->getID());
128
$commit_obj->setCommitIdentifier($identifier);
129
$commit_obj->makeEphemeral();
130
}
131
$commit_list[$identifier] = $commit_obj;
132
}
133
$commits = $commit_list;
134
135
$commit_ids = array_filter(mpull($commits, 'getID'));
136
if ($commit_ids) {
137
$commit_data = id(new PhabricatorRepositoryCommitData())->loadAllWhere(
138
'commitID in (%Ld)',
139
$commit_ids);
140
$commit_data = mpull($commit_data, null, 'getCommitID');
141
}
142
143
foreach ($commits as $commit) {
144
if (!$commit->getID()) {
145
continue;
146
}
147
if (idx($commit_data, $commit->getID())) {
148
$commit->attachCommitData($commit_data[$commit->getID()]);
149
}
150
}
151
152
return $commits;
153
}
154
155
final public static function loadHistoryForCommitIdentifiers(
156
array $identifiers,
157
DiffusionRequest $drequest) {
158
159
if (!$identifiers) {
160
return array();
161
}
162
163
$repository = $drequest->getRepository();
164
$commits = self::loadCommitsByIdentifiers($identifiers, $drequest);
165
166
if (!$commits) {
167
return array();
168
}
169
170
$path = $drequest->getPath();
171
172
$conn_r = $repository->establishConnection('r');
173
174
$path_normal = DiffusionPathIDQuery::normalizePath($path);
175
$paths = queryfx_all(
176
$conn_r,
177
'SELECT id, path FROM %T WHERE pathHash IN (%Ls)',
178
PhabricatorRepository::TABLE_PATH,
179
array(md5($path_normal)));
180
$paths = ipull($paths, 'id', 'path');
181
$path_id = idx($paths, $path_normal);
182
183
$commit_ids = array_filter(mpull($commits, 'getID'));
184
185
$path_changes = array();
186
if ($path_id && $commit_ids) {
187
$path_changes = queryfx_all(
188
$conn_r,
189
'SELECT * FROM %T WHERE commitID IN (%Ld) AND pathID = %d',
190
PhabricatorRepository::TABLE_PATHCHANGE,
191
$commit_ids,
192
$path_id);
193
$path_changes = ipull($path_changes, null, 'commitID');
194
}
195
196
$history = array();
197
foreach ($identifiers as $identifier) {
198
$item = new DiffusionPathChange();
199
$item->setCommitIdentifier($identifier);
200
$commit = idx($commits, $identifier);
201
if ($commit) {
202
$item->setCommit($commit);
203
try {
204
$item->setCommitData($commit->getCommitData());
205
} catch (Exception $ex) {
206
// Ignore, commit just doesn't have data.
207
}
208
$change = idx($path_changes, $commit->getID());
209
if ($change) {
210
$item->setChangeType($change['changeType']);
211
$item->setFileType($change['fileType']);
212
}
213
}
214
$history[] = $item;
215
}
216
217
return $history;
218
}
219
}
220
221