Issues (52)

src/Queries/TimeSeriesQuery.php (3 issues)

1
<?php
2
declare(strict_types=1);
3
4
namespace Level23\Druid\Queries;
5
6
use Level23\Druid\Types\Granularity;
7
use Level23\Druid\Filters\FilterInterface;
8
use Level23\Druid\Context\ContextInterface;
9
use Level23\Druid\Collections\IntervalCollection;
10
use Level23\Druid\DataSources\DataSourceInterface;
11
use Level23\Druid\Collections\AggregationCollection;
12
use Level23\Druid\Responses\TimeSeriesQueryResponse;
13
use Level23\Druid\Collections\VirtualColumnCollection;
14
use Level23\Druid\Collections\PostAggregationCollection;
15
16
class TimeSeriesQuery implements QueryInterface
17
{
18
    protected DataSourceInterface $dataSource;
19
20
    protected IntervalCollection $intervals;
21
22
    protected Granularity $granularity;
23
24
    protected ?FilterInterface $filter = null;
25
26
    protected ?VirtualColumnCollection $virtualColumns = null;
27
28
    protected ?AggregationCollection $aggregations = null;
29
30
    protected ?PostAggregationCollection $postAggregations = null;
31
32
    protected ?ContextInterface $context = null;
33
34
    protected bool $descending = false;
35
36
    protected string $timeOutputName = 'timestamp';
37
38
    /**
39
     * Not documented (yet), but supported since 0.13.0
40
     * It is revealed also in a query like:
41
     * `explain plan for select floor(__time to day), count(*) from "dataSource" group by 1 limit 2;`
42
     *
43
     * @see https://github.com/apache/incubator-druid/pull/5931
44
     * @var int|null
45
     */
46
    protected ?int $limit = null;
47
48
    /**
49
     * TimeSeriesQuery constructor.
50
     *
51
     * @param DataSourceInterface $dataSource
52
     * @param IntervalCollection  $intervals
53
     * @param string|Granularity  $granularity
54
     */
55 7
    public function __construct(
56
        DataSourceInterface $dataSource,
57
        IntervalCollection $intervals,
58
        string|Granularity $granularity = Granularity::ALL
59
    ) {
60 7
        $this->dataSource  = $dataSource;
61 7
        $this->intervals   = $intervals;
62 7
        $this->granularity = is_string($granularity) ? Granularity::from(strtolower($granularity)) : $granularity;
63
    }
64
65
    /**
66
     * Return the query in array format, so we can fire it to druid.
67
     *
68
     * @return array<string,string|array<mixed>|bool|int>
69
     */
70 2
    public function toArray(): array
71
    {
72 2
        $result = [
73 2
            'queryType'   => 'timeseries',
74 2
            'dataSource'  => $this->dataSource->toArray(),
75 2
            'descending'  => $this->descending,
76 2
            'intervals'   => $this->intervals->toArray(),
77 2
            'granularity' => $this->granularity->value,
78 2
        ];
79
80 2
        if ($this->filter) {
81 1
            $result['filter'] = $this->filter->toArray();
82
        }
83
84 2
        if ($this->virtualColumns) {
85 1
            $result['virtualColumns'] = $this->virtualColumns->toArray();
86
        }
87
88 2
        if ($this->aggregations) {
89 1
            $result['aggregations'] = $this->aggregations->toArray();
90
        }
91
92 2
        if ($this->postAggregations) {
93 1
            $result['postAggregations'] = $this->postAggregations->toArray();
94
        }
95
96 2
        if (isset($this->context)) {
97 1
            $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 ignore-call  annotation

97
            /** @scrutinizer ignore-call */ 
98
            $context = $this->context->toArray();

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...
98 1
            if (sizeof($context) > 0) {
99 1
                $result['context'] = $context;
100
            }
101
        }
102
103 2
        if ($this->limit) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->limit of type integer|null is loosely compared to true; this is ambiguous if the integer can be 0. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
104 1
            $result['limit'] = $this->limit;
105
        }
106
107 2
        return $result;
0 ignored issues
show
The expression return $result returns an array which contains values of type boolean which are incompatible with the return type array<mixed,mixed>|integer|string mandated by Level23\Druid\Queries\QueryInterface::toArray().
Loading history...
108
    }
109
110
    /**
111
     * @param \Level23\Druid\Filters\FilterInterface $filter
112
     */
113 1
    public function setFilter(FilterInterface $filter): void
114
    {
115 1
        $this->filter = $filter;
116
    }
117
118
    /**
119
     * @param \Level23\Druid\Collections\AggregationCollection $aggregations
120
     */
121 1
    public function setAggregations(AggregationCollection $aggregations): void
122
    {
123 1
        $this->aggregations = $aggregations;
124
    }
125
126
    /**
127
     * @param \Level23\Druid\Collections\PostAggregationCollection $postAggregations
128
     */
129 1
    public function setPostAggregations(PostAggregationCollection $postAggregations): void
130
    {
131 1
        $this->postAggregations = $postAggregations;
132
    }
133
134
    /**
135
     * @param \Level23\Druid\Context\ContextInterface $context
136
     */
137 1
    public function setContext(ContextInterface $context): void
138
    {
139 1
        $this->context = $context;
140
    }
141
142
    /**
143
     * @param bool $descending
144
     */
145 1
    public function setDescending(bool $descending): void
146
    {
147 1
        $this->descending = $descending;
148
    }
149
150
    /**
151
     * Parse the response into something we can return to the user.
152
     *
153
     * @param array<string|int,array<mixed>|int|string> $response
154
     *
155
     * @return TimeSeriesQueryResponse
156
     */
157 1
    public function parseResponse(array $response): TimeSeriesQueryResponse
158
    {
159 1
        return new TimeSeriesQueryResponse($response, $this->timeOutputName);
160
    }
161
162
    /**
163
     * Set the name which will be used in the result set to store the timestamp in.
164
     *
165
     * @param string $timeOutputName
166
     */
167 1
    public function setTimeOutputName(string $timeOutputName): void
168
    {
169 1
        $this->timeOutputName = $timeOutputName;
170
    }
171
172
    /**
173
     * @param \Level23\Druid\Collections\VirtualColumnCollection $virtualColumns
174
     */
175 1
    public function setVirtualColumns(VirtualColumnCollection $virtualColumns): void
176
    {
177 1
        $this->virtualColumns = $virtualColumns;
178
    }
179
180
    /**
181
     * @param int $limit
182
     */
183 1
    public function setLimit(int $limit): void
184
    {
185 1
        $this->limit = $limit;
186
    }
187
}