Correct a parameter order swap in "diffusion.historyquery" for Mercurial
[phabricator.git] / src / applications / diffusion / query / DiffusionQuery.php
blob4b2258da06bce21707fa1043268ff575fe1c0a1d
1 <?php
3 abstract class DiffusionQuery extends PhabricatorQuery {
5 private $request;
7 final protected function __construct() {
8 // <protected>
11 protected static function newQueryObject(
12 $base_class,
13 DiffusionRequest $request) {
15 $repository = $request->getRepository();
17 $obj = self::initQueryObject($base_class, $repository);
18 $obj->request = $request;
20 return $obj;
23 final protected static function initQueryObject(
24 $base_class,
25 PhabricatorRepository $repository) {
27 $map = array(
28 PhabricatorRepositoryType::REPOSITORY_TYPE_GIT => 'Git',
29 PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL => 'Mercurial',
30 PhabricatorRepositoryType::REPOSITORY_TYPE_SVN => 'Svn',
33 $name = idx($map, $repository->getVersionControlSystem());
34 if (!$name) {
35 throw new Exception(pht('Unsupported VCS!'));
38 $class = str_replace('Diffusion', 'Diffusion'.$name, $base_class);
39 $obj = new $class();
40 return $obj;
43 final protected function getRequest() {
44 return $this->request;
47 final public static function callConduitWithDiffusionRequest(
48 PhabricatorUser $user,
49 DiffusionRequest $drequest,
50 $method,
51 array $params = array(),
52 $return_future = false) {
54 $repository = $drequest->getRepository();
56 $core_params = array(
57 'repository' => $repository->getPHID(),
60 if ($drequest->getBranch() !== null) {
61 $core_params['branch'] = $drequest->getBranch();
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]);
74 $params = $params + $core_params;
76 $future = $repository->newConduitFuture(
77 $user,
78 $method,
79 $params,
80 $drequest->getIsClusterRequest());
82 if (!$return_future) {
83 return $future->resolve();
86 return $future;
89 public function execute() {
90 return $this->executeQuery();
93 abstract protected function executeQuery();
96 /* -( Query Utilities )---------------------------------------------------- */
99 final public static function loadCommitsByIdentifiers(
100 array $identifiers,
101 DiffusionRequest $drequest) {
102 if (!$identifiers) {
103 return array();
106 $commits = array();
107 $commit_data = array();
109 $repository = $drequest->getRepository();
111 $commits = id(new PhabricatorRepositoryCommit())->loadAllWhere(
112 'repositoryID = %d AND commitIdentifier IN (%Ls)',
113 $repository->getID(),
114 $identifiers);
115 $commits = mpull($commits, null, 'getCommitIdentifier');
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.
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();
131 $commit_list[$identifier] = $commit_obj;
133 $commits = $commit_list;
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');
143 foreach ($commits as $commit) {
144 if (!$commit->getID()) {
145 continue;
147 if (idx($commit_data, $commit->getID())) {
148 $commit->attachCommitData($commit_data[$commit->getID()]);
152 return $commits;
155 final public static function loadHistoryForCommitIdentifiers(
156 array $identifiers,
157 DiffusionRequest $drequest) {
159 if (!$identifiers) {
160 return array();
163 $repository = $drequest->getRepository();
164 $commits = self::loadCommitsByIdentifiers($identifiers, $drequest);
166 if (!$commits) {
167 return array();
170 $path = $drequest->getPath();
172 $conn_r = $repository->establishConnection('r');
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);
183 $commit_ids = array_filter(mpull($commits, 'getID'));
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');
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.
208 $change = idx($path_changes, $commit->getID());
209 if ($change) {
210 $item->setChangeType($change['changeType']);
211 $item->setFileType($change['fileType']);
214 $history[] = $item;
217 return $history;