level23 /
druid-client
| 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. Loading history...
|
|||||||
| 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. Loading history...
|
|||||||
| 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.