@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.)
hq.recaptime.dev/wiki/Phorge
phorge
phabricator
1<?php
2
3final class DiffusionPathChangeQuery extends Phobject {
4
5 private $request;
6 private $limit;
7
8 public function setLimit($limit) {
9 $this->limit = $limit;
10 return $this;
11 }
12
13 public function getLimit() {
14 return $this->limit;
15 }
16
17 private function __construct() {
18 // <private>
19 }
20
21 public static function newFromDiffusionRequest(
22 DiffusionRequest $request) {
23 $query = new DiffusionPathChangeQuery();
24 $query->request = $request;
25
26 return $query;
27 }
28
29 protected function getRequest() {
30 return $this->request;
31 }
32
33 public function loadChanges() {
34 return $this->executeQuery();
35 }
36
37 protected function executeQuery() {
38
39 $drequest = $this->getRequest();
40 $repository = $drequest->getRepository();
41
42 $commit = $drequest->loadCommit();
43
44 $conn_r = $repository->establishConnection('r');
45
46 if ($this->limit) {
47 $limit = qsprintf(
48 $conn_r,
49 'LIMIT %d',
50 $this->limit + 1);
51 } else {
52 $limit = qsprintf($conn_r, '');
53 }
54
55 $raw_changes = queryfx_all(
56 $conn_r,
57 'SELECT c.*, p.path pathName, t.path targetPathName,
58 i.commitIdentifier targetCommitIdentifier
59 FROM %T c
60 LEFT JOIN %T p ON c.pathID = p.id
61 LEFT JOIN %T t ON c.targetPathID = t.id
62 LEFT JOIN %T i ON c.targetCommitID = i.id
63 WHERE c.commitID = %d AND isDirect = 1 %Q',
64 PhabricatorRepository::TABLE_PATHCHANGE,
65 PhabricatorRepository::TABLE_PATH,
66 PhabricatorRepository::TABLE_PATH,
67 $commit->getTableName(),
68 $commit->getID(),
69 $limit);
70
71 $limited = $this->limit && (count($raw_changes) > $this->limit);
72 if ($limited) {
73 $raw_changes = array_slice($raw_changes, 0, $this->limit);
74 }
75
76 $changes = array();
77
78 $raw_changes = isort($raw_changes, 'pathName');
79 foreach ($raw_changes as $raw_change) {
80 $type = $raw_change['changeType'];
81 if ($type == DifferentialChangeType::TYPE_CHILD) {
82 continue;
83 }
84
85 $change = new DiffusionPathChange();
86 $change->setPath(ltrim($raw_change['pathName'], '/'));
87 $change->setChangeType($raw_change['changeType']);
88 $change->setFileType($raw_change['fileType']);
89 $change->setCommitIdentifier($commit->getCommitIdentifier());
90
91 $target_path = $raw_change['targetPathName'];
92 if ($target_path !== null) {
93 $target_path = ltrim($target_path, '/');
94 }
95 $change->setTargetPath($target_path);
96
97 $change->setTargetCommitIdentifier($raw_change['targetCommitIdentifier']);
98
99 $id = $raw_change['pathID'];
100 $changes[$id] = $change;
101 }
102
103 // Deduce the away paths by examining all the changes, if we loaded them
104 // all.
105
106 if (!$limited) {
107 $away = array();
108 foreach ($changes as $change) {
109 if ($change->getTargetPath()) {
110 $away[$change->getTargetPath()][] = $change->getPath();
111 }
112 }
113 foreach ($changes as $change) {
114 if (isset($away[$change->getPath()])) {
115 $change->setAwayPaths($away[$change->getPath()]);
116 }
117 }
118 }
119
120 return $changes;
121 }
122}