Passed
Push — master ( 3829ec...650305 )
by Aleksandar
03:24 queued 15s
created

QueryResultBuilder   A

Complexity

Total Complexity 19

Size/Duplication

Total Lines 181
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 48
c 1
b 0
f 0
dl 0
loc 181
ccs 62
cts 62
cp 1
rs 10
wmc 19

15 Methods

Rating   Name   Duplication   Size   Complexity  
A pipeFilter() 0 4 1
A pipeIndexBy() 0 5 1
A first() 0 5 1
A scalar() 0 5 1
A create() 0 9 2
A pipeListBy() 0 12 3
A clearPipeline() 0 4 1
A exists() 0 5 1
A result() 0 9 2
A pipeSort() 0 8 1
A all() 0 5 1
A pipeReduce() 0 4 1
A column() 0 5 1
A useReader() 0 4 1
A pipeMap() 0 4 1
1
<?php
2
/**
3
 * Copyright 2021 Aleksandar Panic
4
 *
5
 * Licensed under the Apache License, Version 2.0 (the "License");
6
 * you may not use this file except in compliance with the License.
7
 * You may obtain a copy of the License at
8
 *
9
 *   http://www.apache.org/licenses/LICENSE-2.0
10
 *
11
 * Unless required by applicable law or agreed to in writing, software
12
 * distributed under the License is distributed on an "AS IS" BASIS,
13
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
 * See the License for the specific language governing permissions and
15
 * limitations under the License.
16
 */
17
18
namespace ArekX\PQL;
19
20
use ArekX\PQL\Contracts\ResultBuilder;
21
use ArekX\PQL\Contracts\ResultReader;
22
23
/**
24
 * Result builder for query.
25
 */
26
class QueryResultBuilder implements ResultBuilder
27
{
28
    /**
29
     * Result reader which is used to read all results from.
30
     *
31
     * @var ResultReader
32
     */
33
    protected ResultReader $reader;
34
35
    /**
36
     * List of pipeline methods to apply when calling result()
37
     *
38
     * @see QueryResultBuilder::result()
39
     * @var array
40
     */
41
    protected $pipelines = [];
42
43
    /**
44
     * Create new instance query result builder.
45
     * @param ResultReader|null $reader Reader to be used
46
     * @return static
47
     */
48 13
    public static function create(ResultReader $reader = null)
49
    {
50 13
        $instance = new static();
51
52 13
        if ($reader) {
53 13
            $instance->useReader($reader);
54
        }
55
56 13
        return $instance;
57
    }
58
59
    /**
60
     * @inheritDoc
61
     */
62 14
    public function useReader(ResultReader $reader): ResultBuilder
63
    {
64 14
        $this->reader = $reader;
65 14
        return $this;
66
    }
67
68
    /**
69
     * @inheritDoc
70
     */
71 1
    public function first()
72
    {
73 1
        $result = $this->reader->getNextRow();
74 1
        $this->reader->finalize();
75 1
        return $result;
76
    }
77
78
    /**
79
     * @inheritDoc
80
     */
81 1
    public function scalar($index = 0)
82
    {
83 1
        $result = $this->reader->getNextColumn($index);
84 1
        $this->reader->finalize();
85 1
        return $result;
86
    }
87
88
    /**
89
     * @inheritDoc
90
     */
91 1
    public function column($index = 0): array
92
    {
93 1
        $result = $this->reader->getAllColumns($index);
94 1
        $this->reader->finalize();
95 1
        return $result;
96
    }
97
98
    /**
99
     * @inheritDoc
100
     */
101 1
    public function exists(): bool
102
    {
103 1
        $result = $this->reader->getNextColumn();
104 1
        $this->reader->finalize();
105 1
        return $result !== null;
106
    }
107
108
    /**
109
     * @inheritDoc
110
     */
111 1
    public function clearPipeline(): ResultBuilder
112
    {
113 1
        $this->pipelines = [];
114 1
        return $this;
115
    }
116
117
    /**
118
     * @inheritDoc
119
     */
120 1
    public function pipeIndexBy(string $column): ResultBuilder
121
    {
122 1
        return $this->pipeReduce(function ($result, $row) use ($column) {
123 1
            $result[$row[$column]] = $row;
124 1
            return $result;
125 1
        });
126
    }
127
128
    /**
129
     * @inheritDoc
130
     */
131 5
    public function pipeReduce(callable $reducer, $initialValue = null): ResultBuilder
132
    {
133 5
        $this->pipelines[] = fn($results) => array_reduce($results, $reducer, $initialValue);
134 5
        return $this;
135
    }
136
137
    /**
138
     * @inheritDoc
139
     */
140 1
    public function pipeSort(callable $sorter): ResultBuilder
141
    {
142 1
        $this->pipelines[] = function ($results) use ($sorter) {
143 1
            usort($results, $sorter);
144 1
            return $results;
145
        };
146
147 1
        return $this;
148
    }
149
150
    /**
151
     * @inheritDoc
152
     */
153 1
    public function pipeMap(callable $mapper): ResultBuilder
154
    {
155 1
        $this->pipelines[] = fn($results) => array_map($mapper, $results);
156 1
        return $this;
157
    }
158
159
    /**
160
     * @inheritDoc
161
     */
162 1
    public function pipeFilter(callable $filter): ResultBuilder
163
    {
164 1
        $this->pipelines[] = fn($results) => array_values(array_filter($results, $filter));
165 1
        return $this;
166
    }
167
168
    /**
169
     * @inheritDoc
170
     */
171 9
    public function result()
172
    {
173 9
        $result = $this->all();
174
175 9
        foreach ($this->pipelines as $pipelineMethod) {
176 7
            $result = $pipelineMethod($result, $this);
177
        }
178
179 8
        return $result;
180
    }
181
182
    /**
183
     * @inheritDoc
184
     */
185 10
    public function all(): array
186
    {
187 10
        $result = $this->reader->getAllRows();
188 10
        $this->reader->finalize();
189 10
        return $result;
190
    }
191
192
    /**
193
     * @inheritDoc
194
     */
195 2
    public function pipeListBy(string $keyColumn, string $valueColumn): ResultBuilder
196
    {
197 2
        return $this->pipeReduce(function ($previous, $row) use ($keyColumn, $valueColumn) {
198
199 2
            if (!array_key_exists($keyColumn, $row) || !array_key_exists($valueColumn, $row)) {
200 1
                throw new \Exception('$keyColumn and $valueColumn must exist in the result.');
201
            }
202
203 1
            $previous[$row[$keyColumn]] = $row[$valueColumn];
204
205 1
            return $previous;
206 2
        }, []);
207
    }
208
}