Issues (52)

src/Concerns/HasDimensions.php (3 issues)

Severity
1
<?php
2
declare(strict_types=1);
3
4
namespace Level23\Druid\Concerns;
5
6
use ArrayObject;
7
use Level23\Druid\Types\DataType;
8
use Level23\Druid\Dimensions\Dimension;
9
use Level23\Druid\Dimensions\LookupDimension;
10
use Level23\Druid\Dimensions\DimensionInterface;
11
use Level23\Druid\Dimensions\ListFilteredDimension;
12
use Level23\Druid\Dimensions\RegexFilteredDimension;
13
use Level23\Druid\Dimensions\PrefixFilteredDimension;
14
15
trait HasDimensions
16
{
17
    /**
18
     * @var array|DimensionInterface[]
19
     */
20
    protected array $dimensions = [];
21
22
    /**
23
     * @return array|DimensionInterface[]
24
     */
25 14
    public function getDimensions(): array
26
    {
27 14
        return $this->dimensions;
28
    }
29
30
    /**
31
     * Select a dimension from our statistics. Possible use a lookup function to find the
32
     * real data which we want to use.
33
     *
34
     * @param \ArrayObject<int|string,string>|string|DimensionInterface|array<int,string> $dimension
35
     * @param string                                                                      $as         When dimensions
36
     *                                                                                                is a string (the
37
     *                                                                                                dimension), you
38
     *                                                                                                can specify the
39
     *                                                                                                alias output name
40
     *                                                                                                here.
41
     * @param string|DataType                                                             $outputType This can either
42
     *                                                                                                be
43
     *                                                                                                "long",
44
     *                                                                                                "float" or
45
     *                                                                                                "string"
46
     *
47
     * @return self
48
     */
49 47
    public function select(
50
        array|ArrayObject|string|DimensionInterface $dimension,
51
        string $as = '',
52
        string|DataType $outputType = DataType::STRING
53
    ): self {
54 47
        if (is_string($dimension)) {
0 ignored issues
show
The condition is_string($dimension) is always false.
Loading history...
55 28
            $this->addDimension(new Dimension(
56 28
                $dimension,
57 28
                ($as ?: $dimension),
58 28
                is_string($outputType) ? DataType::from(strtolower($outputType)) : $outputType,
59 28
            ));
60
        } else {
61 20
            $this->addDimension($dimension);
62
        }
63
64 46
        return $this;
65
    }
66
67
    /**
68
     * Select a dimension and transform it using a lookup function.
69
     *
70
     * @param string      $lookupFunction      The name of the registered lookup function which you want to use
71
     * @param string      $dimension           The dimension which you want to transform using the lookup function.
72
     * @param string      $as                  The name as it will be used in the result set. If left empty, we will
73
     *                                         use the same name as the dimension.
74
     * @param bool|string $keepMissingValue    When true, we will keep values which are not known in the lookup
75
     *                                         function. The original value will be kept. If false, the missing items
76
     *                                         will not be kept in the result set. If this is a string, we will keep
77
     *                                         the missing values and replace them with the string value.
78
     *
79
     * @return self
80
     */
81 7
    public function lookup(
82
        string $lookupFunction,
83
        string $dimension,
84
        string $as = '',
85
        bool|string $keepMissingValue = false
86
    ): self {
87 7
        $this->addDimension(new LookupDimension(
88 7
            $dimension,
89 7
            $lookupFunction,
90 7
            ($as ?: $dimension),
91 7
            $keepMissingValue
92 7
        ));
93
94 7
        return $this;
95
    }
96
97
    /**
98
     * Select a dimension and transform it using the given lookup map.
99
     *
100
     * @param array<string,string> $map              A list with key = value items, where the dimension value will be
101
     *                                               looked up in the map, and be replaced by the value in the map.
102
     * @param string               $dimension        The dimension which you want to transform using the lookup
103
     *                                               function.
104
     * @param string               $as               The name as it will be used in the result set. If left empty, we
105
     *                                               will use the same name as the dimension.
106
     * @param bool|string          $keepMissingValue When true, we will keep values which are not known in the lookup
107
     *                                               function. The original value will be kept. If false, the missing
108
     *                                               items will not be kept in the result set. If this is a string, we
109
     *                                               will keep the missing values and replace them with the string
110
     *                                               value.
111
     * @param bool                 $isOneToOne       Set to true if the key/value items are unique in the given map.
112
     *
113
     * @return self
114
     */
115 1
    public function inlineLookup(
116
        array $map,
117
        string $dimension,
118
        string $as = '',
119
        bool|string $keepMissingValue = false,
120
        bool $isOneToOne = false
121
    ): self {
122 1
        $this->addDimension(new LookupDimension(
123 1
            $dimension,
124 1
            $map,
125 1
            ($as ?: $dimension),
126 1
            $keepMissingValue,
127 1
            $isOneToOne
128 1
        ));
129
130 1
        return $this;
131
    }
132
133
    /**
134
     * For a multi value field, you can filter which values should be returned based in the given list.
135
     *
136
     * @see: https://druid.apache.org/docs/latest/querying/multi-value-dimensions.html
137
     *
138
     * @param string          $dimension   The name of the multi-value dimension where you want to select data from
139
     * @param string[]        $values      A list of items which you want to select (whitelist) or not select
140
     *                                     (blacklist)
141
     * @param string          $as          The name as it will be used in the result set. If left empty, we will use
142
     *                                     the same name as the dimension.
143
     * @param string|DataType $outputType  This can either be "long", "float" or "string"
144
     * @param bool            $isWhitelist Whether the list is a whitelist (true) or a blacklist (false)
145
     *
146
     * @return self
147
     */
148 3
    public function multiValueListSelect(
149
        string $dimension,
150
        array $values,
151
        string $as = '',
152
        string|DataType $outputType = DataType::STRING,
153
        bool $isWhitelist = true
154
    ): self {
155 3
        $this->addDimension(new ListFilteredDimension(
156 3
            new Dimension(
157 3
                $dimension,
158 3
                $as ?: $dimension,
159 3
                $outputType
160 3
            ),
161 3
            $values,
162 3
            $isWhitelist
163 3
        ));
164
165 3
        return $this;
166
    }
167
168
    /**
169
     * For a multi value field, you can filter which values should be returned based on the given java regular
170
     * expression.
171
     *
172
     * @see: https://druid.apache.org/docs/latest/querying/multi-value-dimensions.html
173
     *
174
     * @param string          $dimension  The name of the multi-value dimension where you want to select data from
175
     * @param string          $regex      Only return the items in this dimension which match with the given java
176
     *                                    regex.
177
     * @param string          $as         The name as it will be used in the result set. If left empty, we will use the
178
     *                                    same name as the dimension.
179
     * @param string|DataType $outputType This can either be "long", "float" or "string"
180
     *
181
     * @return self
182
     */
183 3
    public function multiValueRegexSelect(
184
        string $dimension,
185
        string $regex,
186
        string $as = '',
187
        string|DataType $outputType = DataType::STRING
188
    ): self {
189 3
        $this->addDimension(new RegexFilteredDimension(
190 3
            new Dimension(
191 3
                $dimension,
192 3
                $as ?: $dimension,
193 3
                $outputType
194 3
            ),
195 3
            $regex
196 3
        ));
197
198 3
        return $this;
199
    }
200
201
    /**
202
     * For a multi value field, you can filter which values should be returned based on the given prefix.
203
     *
204
     * @see: https://druid.apache.org/docs/latest/querying/multi-value-dimensions.html
205
     *
206
     * @param string          $dimension  The name of the multi-value dimension where you want to select data from
207
     * @param string          $prefix     Only return the values which match with the given prefix.
208
     * @param string          $as         The name as it will be used in the result set. If left empty, we will use the
209
     *                                    same name as the dimension.
210
     * @param string|DataType $outputType This can either be "long", "float" or "string"
211
     *
212
     * @return self
213
     */
214 3
    public function multiValuePrefixSelect(
215
        string $dimension,
216
        string $prefix,
217
        string $as = '',
218
        string|DataType $outputType = DataType::STRING
219
    ): self {
220 3
        $this->addDimension(new PrefixFilteredDimension(
221 3
            new Dimension(
222 3
                $dimension,
223 3
                $as ?: $dimension,
224 3
                $outputType
225 3
            ),
226 3
            $prefix
227 3
        ));
228
229 3
        return $this;
230
    }
231
232
    /**
233
     * Add a dimension or a set of dimensions to our dimension list.
234
     *
235
     * @param ArrayObject<int|string,string>|string|DimensionInterface|array<int,string> $dimension
236
     */
237 57
    protected function addDimension(array|ArrayObject|string|DimensionInterface $dimension): void
238
    {
239 57
        if ($dimension instanceof DimensionInterface) {
0 ignored issues
show
$dimension is never a sub-type of Level23\Druid\Dimensions\DimensionInterface.
Loading history...
240 44
            $this->dimensions[] = $dimension;
241 16
        } elseif (is_string($dimension)) {
0 ignored issues
show
The condition is_string($dimension) is always false.
Loading history...
242 4
            $this->dimensions[] = new Dimension($dimension, $dimension);
243 16
        } elseif (is_iterable($dimension)) {
244 16
            foreach ($dimension as $key => $value) {
245 16
                if (is_string($key) && is_string($value)) {
246 13
                    $this->dimensions[] = new Dimension($key, $value);
247
                } else {
248 4
                    $this->addDimension($value);
249
                }
250
            }
251
        }
252
    }
253
}