@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
3/**
4 * @extends PhabricatorCursorPagedPolicyAwareQuery<PhabricatorFileChunk>
5 */
6final class PhabricatorFileChunkQuery
7 extends PhabricatorCursorPagedPolicyAwareQuery {
8
9 private $chunkHandles;
10 private $rangeStart;
11 private $rangeEnd;
12 private $isComplete;
13 private $needDataFiles;
14
15 public function withChunkHandles(array $handles) {
16 $this->chunkHandles = $handles;
17 return $this;
18 }
19
20 public function withByteRange($start, $end) {
21 $this->rangeStart = $start;
22 $this->rangeEnd = $end;
23 return $this;
24 }
25
26 public function withIsComplete($complete) {
27 $this->isComplete = $complete;
28 return $this;
29 }
30
31 public function needDataFiles($need) {
32 $this->needDataFiles = $need;
33 return $this;
34 }
35
36 protected function loadPage() {
37 $table = new PhabricatorFileChunk();
38 $conn_r = $table->establishConnection('r');
39
40 $data = queryfx_all(
41 $conn_r,
42 'SELECT * FROM %T %Q %Q %Q',
43 $table->getTableName(),
44 $this->buildWhereClause($conn_r),
45 $this->buildOrderClause($conn_r),
46 $this->buildLimitClause($conn_r));
47
48 return $table->loadAllFromArray($data);
49 }
50
51 protected function willFilterPage(array $chunks) {
52
53 if ($this->needDataFiles) {
54 $file_phids = mpull($chunks, 'getDataFilePHID');
55 $file_phids = array_filter($file_phids);
56 if ($file_phids) {
57 $files = id(new PhabricatorFileQuery())
58 ->setViewer($this->getViewer())
59 ->setParentQuery($this)
60 ->withPHIDs($file_phids)
61 ->execute();
62 $files = mpull($files, null, 'getPHID');
63 } else {
64 $files = array();
65 }
66
67 foreach ($chunks as $key => $chunk) {
68 $data_phid = $chunk->getDataFilePHID();
69 if (!$data_phid) {
70 $chunk->attachDataFile(null);
71 continue;
72 }
73
74 $file = idx($files, $data_phid);
75 if (!$file) {
76 unset($chunks[$key]);
77 $this->didRejectResult($chunk);
78 continue;
79 }
80
81 $chunk->attachDataFile($file);
82 }
83
84 if (!$chunks) {
85 return $chunks;
86 }
87 }
88
89 return $chunks;
90 }
91
92 protected function buildWhereClause(AphrontDatabaseConnection $conn) {
93 $where = array();
94
95 if ($this->chunkHandles !== null) {
96 $where[] = qsprintf(
97 $conn,
98 'chunkHandle IN (%Ls)',
99 $this->chunkHandles);
100 }
101
102 if ($this->rangeStart !== null) {
103 $where[] = qsprintf(
104 $conn,
105 'byteEnd > %d',
106 $this->rangeStart);
107 }
108
109 if ($this->rangeEnd !== null) {
110 $where[] = qsprintf(
111 $conn,
112 'byteStart < %d',
113 $this->rangeEnd);
114 }
115
116 if ($this->isComplete !== null) {
117 if ($this->isComplete) {
118 $where[] = qsprintf(
119 $conn,
120 'dataFilePHID IS NOT NULL');
121 } else {
122 $where[] = qsprintf(
123 $conn,
124 'dataFilePHID IS NULL');
125 }
126 }
127
128 $where[] = $this->buildPagingClause($conn);
129
130 return $this->formatWhereClause($conn, $where);
131 }
132
133 public function getQueryApplicationClass() {
134 return PhabricatorFilesApplication::class;
135 }
136
137}