Issues (52)

src/Queries/SelectQuery.php (2 issues)

1
<?php
2
declare(strict_types=1);
3
4
namespace Level23\Druid\Queries;
5
6
use InvalidArgumentException;
7
use Level23\Druid\Types\Granularity;
8
use Level23\Druid\Context\QueryContext;
9
use Level23\Druid\Filters\FilterInterface;
10
use Level23\Druid\Responses\SelectQueryResponse;
11
use Level23\Druid\Collections\IntervalCollection;
12
use Level23\Druid\Collections\DimensionCollection;
13
use Level23\Druid\DataSources\DataSourceInterface;
14
15
/**
16
 * Class SelectQuery
17
 *
18
 * We encourage you to use the Scan query type rather than Select whenever possible. In
19
 * situations involving larger numbers of segments, the Select query can have very high memory and performance
20
 * overhead. The Scan query does not have this issue. The major difference between the two is that the Scan query does
21
 * not support pagination. However, the Scan query type is able to return a virtually unlimited number of results even
22
 * without pagination, making it unnecessary in many cases.
23
 *
24
 * @see     https://druid.apache.org/docs/latest/querying/select-query.html
25
 * @package Level23\Druid\Queries
26
 */
27
class SelectQuery implements QueryInterface
28
{
29
    protected DataSourceInterface $dataSource;
30
31
    protected IntervalCollection $intervals;
32
33
    protected bool $descending = false;
34
35
    protected ?FilterInterface $filter = null;
36
37
    protected ?DimensionCollection $dimensions = null;
38
39
    protected Granularity $granularity = Granularity::ALL;
40
41
    /**
42
     * @var array|string[]
43
     */
44
    protected array $metrics;
45
46
    protected ?QueryContext $context = null;
47
48
    protected int $threshold;
49
50
    /** @var array<string,int>|null */
51
    protected ?array $pagingIdentifier = null;
52
53
    /**
54
     * SelectQuery constructor.
55
     *
56
     * @param DataSourceInterface      $dataSource A DataSourceInterface defining the data source to query, very similar
57
     *                                             to a table in a relational database.
58
     * @param IntervalCollection       $intervals  This defines the time ranges to run the query over.
59
     * @param int                      $threshold  The threshold determines how many hits are returned, with each hit
60
     *                                             indexed by an offset. When descending is true, the offset will be
61
     *                                             negative value.
62
     * @param DimensionCollection|null $dimensions A list of dimensions to select. If left empty, all dimensions are
63
     *                                             returned.
64
     * @param array|string[]           $metrics    A String array of metrics to select. If left empty, all metrics are
65
     *                                             returned.
66
     * @param bool                     $descending Whether to make descending ordered result. Default is
67
     *                                             false(ascending). When this is true, page identifier and offsets
68
     *                                             will be negative value.
69
     */
70 4
    public function __construct(
71
        DataSourceInterface $dataSource,
72
        IntervalCollection $intervals,
73
        int $threshold,
74
        ?DimensionCollection $dimensions = null,
75
        array $metrics = [],
76
        bool $descending = false
77
    ) {
78 4
        $this->dataSource = $dataSource;
79 4
        $this->intervals  = $intervals;
80 4
        $this->descending = $descending;
81 4
        $this->dimensions = $dimensions;
82 4
        $this->metrics    = $metrics;
83 4
        $this->threshold  = $threshold;
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>|bool>
90
     */
91 2
    public function toArray(): array
92
    {
93 2
        $result = [
94 2
            'queryType'   => 'select',
95 2
            'dataSource'  => $this->dataSource->toArray(),
96 2
            'intervals'   => $this->intervals->toArray(),
97 2
            'descending'  => $this->descending,
98 2
            'dimensions'  => $this->dimensions ? $this->dimensions->toArray() : [],
99 2
            'metrics'     => $this->metrics,
100 2
            'granularity' => $this->granularity->value,
101 2
            'pagingSpec'  => [
102 2
                'pagingIdentifiers' => $this->pagingIdentifier,
103 2
                'threshold'         => $this->threshold,
104 2
            ],
105 2
        ];
106
107 2
        if (isset($this->context)) {
108 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 ignore-call  annotation

108
            /** @scrutinizer ignore-call */ 
109
            $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...
109 2
            if (sizeof($context) > 0) {
110 2
                $result['context'] = $context;
111
            }
112
        }
113
114 2
        if ($this->filter) {
115 2
            $result['filter'] = $this->filter->toArray();
116
        }
117
118 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...
119
    }
120
121
    /**
122
     * Parse the response into something we can return to the user.
123
     *
124
     * @param array<string|int,string|int|array<mixed>> $response
125
     *
126
     * @return SelectQueryResponse
127
     */
128 2
    public function parseResponse(array $response): SelectQueryResponse
129
    {
130 2
        return new SelectQueryResponse($response);
131
    }
132
133
    /**
134
     * @param \Level23\Druid\Filters\FilterInterface $filter
135
     */
136 2
    public function setFilter(FilterInterface $filter): void
137
    {
138 2
        $this->filter = $filter;
139
    }
140
141
    /**
142
     * Defines the granularity of the query. Default is Granularity.ALL.
143
     *
144
     * @param string|Granularity $granularity
145
     *
146
     * @throws InvalidArgumentException
147
     */
148 2
    public function setGranularity(string|Granularity $granularity): void
149
    {
150 2
        $this->granularity = is_string($granularity) ? Granularity::from(strtolower($granularity)) : $granularity;
151
    }
152
153
    /**
154
     * @param \Level23\Druid\Context\QueryContext $context
155
     */
156 2
    public function setContext(QueryContext $context): void
157
    {
158 2
        $this->context = $context;
159
    }
160
161
    /**
162
     *
163
     * @param array<string,int> $pagingIdentifier
164
     */
165 2
    public function setPagingIdentifier(array $pagingIdentifier): void
166
    {
167 2
        $this->pagingIdentifier = $pagingIdentifier;
168
    }
169
}