1 | <?php |
||||||
2 | declare(strict_types=1); |
||||||
3 | |||||||
4 | namespace Level23\Druid\Queries; |
||||||
5 | |||||||
6 | use Level23\Druid\Context\QueryContext; |
||||||
7 | use Level23\Druid\Types\OrderByDirection; |
||||||
8 | use Level23\Druid\Filters\FilterInterface; |
||||||
9 | use Level23\Druid\Types\ScanQueryResultFormat; |
||||||
10 | use Level23\Druid\Responses\ScanQueryResponse; |
||||||
11 | use Level23\Druid\Collections\IntervalCollection; |
||||||
12 | use Level23\Druid\DataSources\DataSourceInterface; |
||||||
13 | use Level23\Druid\Collections\VirtualColumnCollection; |
||||||
14 | |||||||
15 | /** |
||||||
16 | * Class ScanQuery |
||||||
17 | * |
||||||
18 | * @see https://druid.apache.org/docs/latest/querying/scan-query.html |
||||||
19 | * @package Level23\Druid\Queries |
||||||
20 | */ |
||||||
21 | class ScanQuery implements QueryInterface |
||||||
22 | { |
||||||
23 | protected DataSourceInterface $dataSource; |
||||||
24 | |||||||
25 | protected IntervalCollection $intervals; |
||||||
26 | |||||||
27 | protected ScanQueryResultFormat $resultFormat = ScanQueryResultFormat::NORMAL_LIST; |
||||||
28 | |||||||
29 | /** |
||||||
30 | * How many rows buffered before return to client. Default is 20480 |
||||||
31 | * |
||||||
32 | * @var int |
||||||
33 | */ |
||||||
34 | protected int $batchSize; |
||||||
35 | |||||||
36 | /** |
||||||
37 | * Return results consistent with the legacy "scan-query" contrib extension. Defaults to the value set by |
||||||
38 | * druid.query.scan.legacy, which in turn defaults to false. See Legacy mode for details. |
||||||
39 | * |
||||||
40 | * @var bool |
||||||
41 | */ |
||||||
42 | protected bool $legacy; |
||||||
43 | |||||||
44 | /** |
||||||
45 | * The ordering of returned rows based on timestamp. "ascending", "descending" are supported. When not supplied, |
||||||
46 | * "none" is used. Currently, "ascending" and "descending" are only supported for queries where the __time column |
||||||
47 | * is included in the columns field and the requirements outlined in the time ordering section are met. |
||||||
48 | * |
||||||
49 | * @var OrderByDirection |
||||||
50 | */ |
||||||
51 | protected OrderByDirection $order; |
||||||
52 | |||||||
53 | /** |
||||||
54 | * How many rows to return. If not specified, all rows will be returned. |
||||||
55 | * |
||||||
56 | * @var int |
||||||
57 | */ |
||||||
58 | protected int $limit; |
||||||
59 | |||||||
60 | /** |
||||||
61 | * Skip this many rows when returning results. |
||||||
62 | * |
||||||
63 | * @var int |
||||||
64 | */ |
||||||
65 | protected int $offset; |
||||||
66 | |||||||
67 | protected ?QueryContext $context; |
||||||
68 | |||||||
69 | protected ?FilterInterface $filter; |
||||||
70 | |||||||
71 | /** |
||||||
72 | * A String array of dimensions and metrics to scan. If left empty, all dimensions and metrics are returned. |
||||||
73 | * |
||||||
74 | * @var array|string[] |
||||||
75 | */ |
||||||
76 | protected array $columns = []; |
||||||
77 | |||||||
78 | protected ?VirtualColumnCollection $virtualColumns; |
||||||
79 | |||||||
80 | 9 | public function __construct(DataSourceInterface $dataSource, IntervalCollection $intervals) |
|||||
81 | { |
||||||
82 | 9 | $this->dataSource = $dataSource; |
|||||
83 | 9 | $this->intervals = $intervals; |
|||||
84 | } |
||||||
85 | |||||||
86 | /** |
||||||
87 | * Return the query in array format, so we can fire it to druid. |
||||||
88 | * |
||||||
89 | * @return array<string,string|array<mixed>|int|bool> |
||||||
90 | */ |
||||||
91 | 5 | public function toArray(): array |
|||||
92 | { |
||||||
93 | 5 | $result = [ |
|||||
94 | 5 | 'queryType' => 'scan', |
|||||
95 | 5 | 'dataSource' => $this->dataSource->toArray(), |
|||||
96 | 5 | 'intervals' => $this->intervals->toArray(), |
|||||
97 | 5 | 'resultFormat' => $this->resultFormat->value, |
|||||
98 | 5 | 'columns' => $this->columns, |
|||||
99 | 5 | ]; |
|||||
100 | |||||||
101 | 5 | if (isset($this->virtualColumns)) { |
|||||
102 | 2 | $result['virtualColumns'] = $this->virtualColumns->toArray(); |
|||||
0 ignored issues
–
show
|
|||||||
103 | } |
||||||
104 | |||||||
105 | 5 | if (isset($this->filter)) { |
|||||
106 | 4 | $result['filter'] = $this->filter->toArray(); |
|||||
0 ignored issues
–
show
The method
toArray() does not exist on null .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces. This is most likely a typographical error or the method has been renamed. ![]() |
|||||||
107 | } |
||||||
108 | |||||||
109 | 5 | if (isset($this->batchSize)) { |
|||||
110 | 2 | $result['batchSize'] = $this->batchSize; |
|||||
111 | } |
||||||
112 | |||||||
113 | 5 | if (isset($this->limit)) { |
|||||
114 | 2 | $result['limit'] = $this->limit; |
|||||
115 | } |
||||||
116 | |||||||
117 | 5 | if (isset($this->offset)) { |
|||||
118 | 2 | $result['offset'] = $this->offset; |
|||||
119 | } |
||||||
120 | |||||||
121 | 5 | if (isset($this->legacy)) { |
|||||
122 | 5 | $result['legacy'] = $this->legacy; |
|||||
123 | } |
||||||
124 | |||||||
125 | 5 | if (isset($this->context)) { |
|||||
126 | 2 | $context = $this->context->toArray(); |
|||||
0 ignored issues
–
show
The method
toArray() does not exist on null .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces. This is most likely a typographical error or the method has been renamed. ![]() |
|||||||
127 | 2 | if (sizeof($context) > 0) { |
|||||
128 | 2 | $result['context'] = $context; |
|||||
129 | } |
||||||
130 | } |
||||||
131 | |||||||
132 | 5 | if (isset($this->order)) { |
|||||
133 | 2 | $result['order'] = $this->order->value; |
|||||
134 | } |
||||||
135 | |||||||
136 | 5 | return $result; |
|||||
137 | } |
||||||
138 | |||||||
139 | /** |
||||||
140 | * Parse the response into something we can return to the user. |
||||||
141 | * |
||||||
142 | * @param array<string|int,string|int|array<mixed>> $response |
||||||
143 | * |
||||||
144 | * @return ScanQueryResponse |
||||||
145 | */ |
||||||
146 | 2 | public function parseResponse(array $response): ScanQueryResponse |
|||||
147 | { |
||||||
148 | 2 | return new ScanQueryResponse($response); |
|||||
149 | } |
||||||
150 | |||||||
151 | /** |
||||||
152 | * How the results are represented. Use one of the ScanQueryResultFormat constants |
||||||
153 | * |
||||||
154 | * @param string|ScanQueryResultFormat $resultFormat |
||||||
155 | */ |
||||||
156 | 6 | public function setResultFormat(string|ScanQueryResultFormat $resultFormat): void |
|||||
157 | { |
||||||
158 | 6 | $this->resultFormat = is_string($resultFormat) ? ScanQueryResultFormat::from(strtolower($resultFormat)) : $resultFormat; |
|||||
159 | } |
||||||
160 | |||||||
161 | /** |
||||||
162 | * How many rows buffered before return to client. Default is 20480 |
||||||
163 | * |
||||||
164 | * @param int $batchSize |
||||||
165 | */ |
||||||
166 | 2 | public function setBatchSize(int $batchSize): void |
|||||
167 | { |
||||||
168 | 2 | $this->batchSize = $batchSize; |
|||||
169 | } |
||||||
170 | |||||||
171 | /** |
||||||
172 | * How many rows to return. If not specified, all rows will be returned. |
||||||
173 | * |
||||||
174 | * @param int $limit |
||||||
175 | */ |
||||||
176 | 2 | public function setLimit(int $limit): void |
|||||
177 | { |
||||||
178 | 2 | $this->limit = $limit; |
|||||
179 | } |
||||||
180 | |||||||
181 | /** |
||||||
182 | * Skip this many rows when returning results. Skipped rows will still need to be generated internally and then |
||||||
183 | * discarded, meaning that raising offsets to high values can cause queries to use additional resources. |
||||||
184 | * |
||||||
185 | * Together, "limit" and "offset" can be used to implement pagination. However, note that if the underlying |
||||||
186 | * datasource is modified in between page fetches in ways that affect overall query results, then the |
||||||
187 | * different pages will not necessarily align with each other. |
||||||
188 | * |
||||||
189 | * @param int $offset |
||||||
190 | */ |
||||||
191 | 2 | public function setOffset(int $offset): void |
|||||
192 | { |
||||||
193 | 2 | $this->offset = $offset; |
|||||
194 | } |
||||||
195 | |||||||
196 | /** |
||||||
197 | * @param bool $legacy |
||||||
198 | */ |
||||||
199 | 5 | public function setLegacy(bool $legacy): void |
|||||
200 | { |
||||||
201 | 5 | $this->legacy = $legacy; |
|||||
202 | } |
||||||
203 | |||||||
204 | /** |
||||||
205 | * @param \Level23\Druid\Context\QueryContext $context |
||||||
206 | */ |
||||||
207 | 2 | public function setContext(QueryContext $context): void |
|||||
208 | { |
||||||
209 | 2 | $this->context = $context; |
|||||
210 | } |
||||||
211 | |||||||
212 | /** |
||||||
213 | * @param \Level23\Druid\Collections\VirtualColumnCollection $virtualColumns |
||||||
214 | */ |
||||||
215 | 2 | public function setVirtualColumns(VirtualColumnCollection $virtualColumns): void |
|||||
216 | { |
||||||
217 | 2 | $this->virtualColumns = $virtualColumns; |
|||||
218 | } |
||||||
219 | |||||||
220 | /** |
||||||
221 | * @param \Level23\Druid\Filters\FilterInterface $filter |
||||||
222 | */ |
||||||
223 | 4 | public function setFilter(FilterInterface $filter): void |
|||||
224 | { |
||||||
225 | 4 | $this->filter = $filter; |
|||||
226 | } |
||||||
227 | |||||||
228 | /** |
||||||
229 | * The ordering of returned rows based on timestamp. "ascending", "descending", and "none" (default) are supported. |
||||||
230 | * Currently, "ascending" and "descending" are only supported for queries where the __time column is included in |
||||||
231 | * the columns field and the requirements outlined in the time ordering section are met. |
||||||
232 | * |
||||||
233 | * @param string|OrderByDirection $order |
||||||
234 | */ |
||||||
235 | 2 | public function setOrder(string|OrderByDirection $order): void |
|||||
236 | { |
||||||
237 | 2 | $this->order = is_string($order) ? OrderByDirection::make($order) : $order; |
|||||
238 | } |
||||||
239 | |||||||
240 | /** |
||||||
241 | * A String array of dimensions and metrics to scan. If left empty, all dimensions and metrics are returned. |
||||||
242 | * |
||||||
243 | * @param array|string[] $columns |
||||||
244 | */ |
||||||
245 | 2 | public function setColumns(array $columns): void |
|||||
246 | { |
||||||
247 | 2 | $this->columns = $columns; |
|||||
248 | } |
||||||
249 | } |
This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.
This is most likely a typographical error or the method has been renamed.