Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/phabricator
Path: blob/master/src/applications/fact/query/PhabricatorFactDatapointQuery.php
12256 views
1
<?php
2
3
final class PhabricatorFactDatapointQuery extends Phobject {
4
5
private $facts;
6
private $objectPHIDs;
7
private $limit;
8
9
private $needVectors;
10
11
private $keyMap = array();
12
private $dimensionMap = array();
13
14
public function withFacts(array $facts) {
15
$this->facts = $facts;
16
return $this;
17
}
18
19
public function withObjectPHIDs(array $object_phids) {
20
$this->objectPHIDs = $object_phids;
21
return $this;
22
}
23
24
public function setLimit($limit) {
25
$this->limit = $limit;
26
return $this;
27
}
28
29
public function needVectors($need) {
30
$this->needVectors = $need;
31
return $this;
32
}
33
34
public function execute() {
35
$facts = mpull($this->facts, null, 'getKey');
36
if (!$facts) {
37
throw new Exception(pht('Executing a fact query requires facts.'));
38
}
39
40
$table_map = array();
41
foreach ($facts as $fact) {
42
$datapoint = $fact->newDatapoint();
43
$table = $datapoint->getTableName();
44
45
if (!isset($table_map[$table])) {
46
$table_map[$table] = array(
47
'table' => $datapoint,
48
'facts' => array(),
49
);
50
}
51
52
$table_map[$table]['facts'][] = $fact;
53
}
54
55
$rows = array();
56
foreach ($table_map as $spec) {
57
$rows[] = $this->executeWithTable($spec);
58
}
59
$rows = array_mergev($rows);
60
61
$key_unmap = array_flip($this->keyMap);
62
$dimension_unmap = array_flip($this->dimensionMap);
63
64
$groups = array();
65
$need_phids = array();
66
foreach ($rows as $row) {
67
$groups[$row['keyID']][] = $row;
68
69
$object_id = $row['objectID'];
70
if (!isset($dimension_unmap[$object_id])) {
71
$need_phids[$object_id] = $object_id;
72
}
73
74
$dimension_id = $row['dimensionID'];
75
if ($dimension_id && !isset($dimension_unmap[$dimension_id])) {
76
$need_phids[$dimension_id] = $dimension_id;
77
}
78
}
79
80
$dimension_unmap += id(new PhabricatorFactObjectDimension())
81
->newDimensionUnmap($need_phids);
82
83
$results = array();
84
foreach ($groups as $key_id => $rows) {
85
$key = $key_unmap[$key_id];
86
$fact = $facts[$key];
87
$datapoint = $fact->newDatapoint();
88
foreach ($rows as $row) {
89
$dimension_id = $row['dimensionID'];
90
if ($dimension_id) {
91
if (!isset($dimension_unmap[$dimension_id])) {
92
continue;
93
} else {
94
$dimension_phid = $dimension_unmap[$dimension_id];
95
}
96
} else {
97
$dimension_phid = null;
98
}
99
100
$object_id = $row['objectID'];
101
if (!isset($dimension_unmap[$object_id])) {
102
continue;
103
} else {
104
$object_phid = $dimension_unmap[$object_id];
105
}
106
107
$result = array(
108
'key' => $key,
109
'objectPHID' => $object_phid,
110
'dimensionPHID' => $dimension_phid,
111
'value' => (int)$row['value'],
112
'epoch' => $row['epoch'],
113
);
114
115
if ($this->needVectors) {
116
$result['vector'] = $datapoint->newRawVector($result);
117
}
118
119
$results[] = $result;
120
}
121
}
122
123
return $results;
124
}
125
126
private function executeWithTable(array $spec) {
127
$table = $spec['table'];
128
$facts = $spec['facts'];
129
$conn = $table->establishConnection('r');
130
131
$fact_keys = mpull($facts, 'getKey');
132
$this->keyMap = id(new PhabricatorFactKeyDimension())
133
->newDimensionMap($fact_keys);
134
135
if (!$this->keyMap) {
136
return array();
137
}
138
139
$where = array();
140
141
$where[] = qsprintf(
142
$conn,
143
'keyID IN (%Ld)',
144
$this->keyMap);
145
146
if ($this->objectPHIDs) {
147
$object_map = id(new PhabricatorFactObjectDimension())
148
->newDimensionMap($this->objectPHIDs);
149
if (!$object_map) {
150
return array();
151
}
152
153
$this->dimensionMap = $object_map;
154
155
$where[] = qsprintf(
156
$conn,
157
'objectID IN (%Ld)',
158
$this->dimensionMap);
159
}
160
161
$where = qsprintf($conn, '%LA', $where);
162
163
if ($this->limit) {
164
$limit = qsprintf(
165
$conn,
166
'LIMIT %d',
167
$this->limit);
168
} else {
169
$limit = qsprintf($conn, '');
170
}
171
172
return queryfx_all(
173
$conn,
174
'SELECT keyID, objectID, dimensionID, value, epoch
175
FROM %T WHERE %Q %Q',
176
$table->getTableName(),
177
$where,
178
$limit);
179
}
180
181
}
182
183