Passed
Push — master ( b979f8...3829ec )
by Aleksandar
07:20 queued 11s
created

QueryResultBuilder   A

Complexity

Total Complexity 17

Size/Duplication

Total Lines 165
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 44
dl 0
loc 165
ccs 57
cts 57
cp 1
rs 10
c 1
b 0
f 0
wmc 17

14 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 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
     * @inheritDoc
45
     */
46 14
    public function useReader(ResultReader $reader): ResultBuilder
47
    {
48 14
        $this->reader = $reader;
49 14
        return $this;
50
    }
51
52
    /**
53
     * @inheritDoc
54
     */
55 1
    public function first()
56
    {
57 1
        $result = $this->reader->getNextRow();
58 1
        $this->reader->finalize();
59 1
        return $result;
60
    }
61
62
    /**
63
     * @inheritDoc
64
     */
65 1
    public function scalar($index = 0)
66
    {
67 1
        $result = $this->reader->getNextColumn($index);
68 1
        $this->reader->finalize();
69 1
        return $result;
70
    }
71
72
    /**
73
     * @inheritDoc
74
     */
75 1
    public function column($index = 0): array
76
    {
77 1
        $result = $this->reader->getAllColumns($index);
78 1
        $this->reader->finalize();
79 1
        return $result;
80
    }
81
82
    /**
83
     * @inheritDoc
84
     */
85 1
    public function exists(): bool
86
    {
87 1
        $result = $this->reader->getNextColumn();
88 1
        $this->reader->finalize();
89 1
        return $result !== null;
90
    }
91
92
    /**
93
     * @inheritDoc
94
     */
95 1
    public function clearPipeline(): ResultBuilder
96
    {
97 1
        $this->pipelines = [];
98 1
        return $this;
99
    }
100
101
    /**
102
     * @inheritDoc
103
     */
104 1
    public function pipeIndexBy(string $column): ResultBuilder
105
    {
106 1
        return $this->pipeReduce(function ($result, $row) use ($column) {
107 1
            $result[$row[$column]] = $row;
108 1
            return $result;
109 1
        });
110
    }
111
112
    /**
113
     * @inheritDoc
114
     */
115 5
    public function pipeReduce(callable $reducer, $initialValue = null): ResultBuilder
116
    {
117 5
        $this->pipelines[] = fn($results) => array_reduce($results, $reducer, $initialValue);
118 5
        return $this;
119
    }
120
121
    /**
122
     * @inheritDoc
123
     */
124 1
    public function pipeSort(callable $sorter): ResultBuilder
125
    {
126 1
        $this->pipelines[] = function ($results) use ($sorter) {
127 1
            usort($results, $sorter);
128 1
            return $results;
129
        };
130
131 1
        return $this;
132
    }
133
134
    /**
135
     * @inheritDoc
136
     */
137 1
    public function pipeMap(callable $mapper): ResultBuilder
138
    {
139 1
        $this->pipelines[] = fn($results) => array_map($mapper, $results);
140 1
        return $this;
141
    }
142
143
    /**
144
     * @inheritDoc
145
     */
146 1
    public function pipeFilter(callable $filter): ResultBuilder
147
    {
148 1
        $this->pipelines[] = fn($results) => array_values(array_filter($results, $filter));
149 1
        return $this;
150
    }
151
152
    /**
153
     * @inheritDoc
154
     */
155 9
    public function result()
156
    {
157 9
        $result = $this->all();
158
159 9
        foreach ($this->pipelines as $pipelineMethod) {
160 7
            $result = $pipelineMethod($result, $this);
161
        }
162
163 8
        return $result;
164
    }
165
166
    /**
167
     * @inheritDoc
168
     */
169 10
    public function all(): array
170
    {
171 10
        $result = $this->reader->getAllRows();
172 10
        $this->reader->finalize();
173 10
        return $result;
174
    }
175
176
    /**
177
     * @inheritDoc
178
     */
179 2
    public function pipeListBy(string $keyColumn, string $valueColumn): ResultBuilder
180
    {
181 2
        return $this->pipeReduce(function ($previous, $row) use ($keyColumn, $valueColumn) {
182
183 2
            if (!array_key_exists($keyColumn, $row) || !array_key_exists($valueColumn, $row)) {
184 1
                throw new \Exception('$keyColumn and $valueColumn must exist in the result.');
185
            }
186
187 1
            $previous[$row[$keyColumn]] = $row[$valueColumn];
188
189 1
            return $previous;
190 2
        }, []);
191
    }
192
}