Failed Conditions
Pull Request — master (#4007)
by Sergei
62:58
created

Statement::fixResultSet()   B

Complexity

Conditions 10
Paths 27

Size

Total Lines 26
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 110

Importance

Changes 0
Metric Value
cc 10
eloc 13
nc 27
nop 3
dl 0
loc 26
ccs 0
cts 0
cp 0
crap 110
rs 7.6666
c 0
b 0
f 0

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
declare(strict_types=1);
4
5
namespace Doctrine\DBAL\Portability;
6
7
use Doctrine\DBAL\Driver\DriverException;
8
use Doctrine\DBAL\Driver\FetchUtils;
9
use Doctrine\DBAL\Driver\ResultStatement;
10
use Doctrine\DBAL\Driver\Statement as DriverStatement;
11
use Doctrine\DBAL\ParameterType;
12
use Traversable;
13
use function array_change_key_case;
14
use function assert;
15
use function is_string;
16
use function rtrim;
17
18
/**
19
 * Portability wrapper for a Statement.
20
 */
21
final class Statement implements DriverStatement
22
{
23
    /** @var int */
24
    private $portability;
25
26
    /** @var DriverStatement|ResultStatement */
27
    private $stmt;
28
29
    /** @var int|null */
30
    private $case;
31
32
    /**
33
     * Wraps <tt>Statement</tt> and applies portability measures.
34
     *
35
     * @param DriverStatement|ResultStatement $stmt
36
     */
37
    public function __construct($stmt, Connection $conn)
38
    {
39
        $this->stmt        = $stmt;
40 264
        $this->portability = $conn->getPortability();
41
        $this->case        = $conn->getFetchCase();
42 264
    }
43 264
44 264
    /**
45 264
     * {@inheritdoc}
46
     */
47
    public function bindParam($param, &$variable, int $type = ParameterType::STRING, ?int $length = null) : void
48
    {
49
        assert($this->stmt instanceof DriverStatement);
50 22
51
        $this->stmt->bindParam($param, $variable, $type, $length);
52 22
    }
53
54 22
    /**
55 22
     * {@inheritdoc}
56
     */
57
    public function bindValue($param, $value, int $type = ParameterType::STRING) : void
58
    {
59
        assert($this->stmt instanceof DriverStatement);
60 22
61
        $this->stmt->bindValue($param, $value, $type);
62 22
    }
63
64 22
    public function closeCursor() : void
65 22
    {
66
        $this->stmt->closeCursor();
67 22
    }
68
69 22
    public function columnCount() : int
70 22
    {
71
        return $this->stmt->columnCount();
72 22
    }
73
74 22
    /**
75
     * {@inheritdoc}
76
     */
77
    public function execute(?array $params = null) : void
78
    {
79
        assert($this->stmt instanceof DriverStatement);
80 66
81
        $this->stmt->execute($params);
82 66
    }
83
84 66
    /**
85 66
     * {@inheritdoc}
86
     */
87 110
    public function fetchNumeric()
88
    {
89 110
        return $this->fixResult(
90
            $this->stmt->fetchAssociative(),
91 110
            false
92 110
        );
93
    }
94
95
    /**
96
     * {@inheritdoc}
97 66
     */
98
    public function fetchAssociative()
99 66
    {
100
        return $this->fixResult(
101
            $this->stmt->fetchAssociative(),
102
            true
103
        );
104
    }
105 66
106
    /**
107 66
     * {@inheritdoc}
108
     */
109 66
    public function fetchOne()
110
    {
111 66
        $value = $this->stmt->fetchOne();
112 66
113 66
        if (($this->portability & Connection::PORTABILITY_EMPTY_TO_NULL) !== 0 && $value === '') {
114 66
            $value = null;
115
        } elseif (($this->portability & Connection::PORTABILITY_RTRIM) !== 0 && is_string($value)) {
116 66
            $value = rtrim($value);
117
        }
118 66
119
        return $value;
120
    }
121
122
    /**
123
     * {@inheritdoc}
124 110
     */
125
    public function fetchAllNumeric() : array
126 110
    {
127
        return $this->fixResultSet(
128 110
            $this->stmt->fetchAllNumeric(),
129
            false,
130 110
            true
131 110
        );
132 110
    }
133 110
134
    /**
135 110
     * {@inheritdoc}
136
     */
137
    public function fetchAllAssociative() : array
138
    {
139 110
        return $this->fixResultSet(
140 66
            $this->stmt->fetchAllAssociative(),
141 66
            true,
142
            true
143
        );
144
    }
145 110
146 110
    /**
147
     * {@inheritdoc}
148
     */
149 110
    public function fetchColumn() : array
150 66
    {
151 66
        return $this->fixResultSet(
152
            $this->stmt->fetchColumn(),
153
            true,
154
            false
155 110
        );
156
    }
157
158
    /**
159
     * @return Traversable<int,array<int,mixed>>
160
     *
161
     * @throws DriverException
162
     */
163
    public function iterateNumeric() : Traversable
164
    {
165
        return FetchUtils::iterateNumeric($this);
166
    }
167
168
    /**
169
     * @return Traversable<int,array<string,mixed>>
170
     *
171
     * @throws DriverException
172
     */
173
    public function iterateAssociative() : Traversable
174 22
    {
175
        return FetchUtils::iterateAssociative($this);
176 22
    }
177
178 22
    /**
179
     * @return Traversable<int,mixed>
180
     *
181
     * @throws DriverException
182
     */
183
    public function iterateColumn() : Traversable
184
    {
185
        return FetchUtils::iterateColumn($this);
186 132
    }
187
188 132
    public function rowCount() : int
189 66
    {
190
        assert($this->stmt instanceof DriverStatement);
191
192 132
        return $this->stmt->rowCount();
193 18
    }
194 18
195
    /**
196
     * @param mixed $result
197 132
     *
198 110
     * @return mixed
199 110
     */
200 63
    private function fixResult($result, bool $fixCase)
201 110
    {
202 33
        $iterateRow = ($this->portability & (Connection::PORTABILITY_EMPTY_TO_NULL|Connection::PORTABILITY_RTRIM)) !== 0;
203
        $fixCase    = $fixCase && $this->case !== null && ($this->portability & Connection::PORTABILITY_FIX_CASE) !== 0;
204
205
        return $this->fixRow($result, $iterateRow, $fixCase);
206
    }
207 132
208
    /**
209
     * @param array<int,mixed> $resultSet
210
     *
211
     * @return array<int,mixed>
212
     */
213
    private function fixResultSet(array $resultSet, bool $fixCase, bool $isArray) : array
214
    {
215
        $iterateRow = ($this->portability & (Connection::PORTABILITY_EMPTY_TO_NULL|Connection::PORTABILITY_RTRIM)) !== 0;
216
        $fixCase    = $fixCase && $this->case !== null && ($this->portability & Connection::PORTABILITY_FIX_CASE) !== 0;
217
218
        if (! $iterateRow && ! $fixCase) {
219
            return $resultSet;
220
        }
221
222
        if (! $isArray) {
223
            foreach ($resultSet as $num => $value) {
224
                $resultSet[$num] = [$value];
225
            }
226
        }
227
228
        foreach ($resultSet as $num => $row) {
229
            $resultSet[$num] = $this->fixRow($row, $iterateRow, $fixCase);
230
        }
231
232
        if (! $isArray) {
233
            foreach ($resultSet as $num => $row) {
234
                $resultSet[$num] = $row[0];
235
            }
236
        }
237
238
        return $resultSet;
239
    }
240
241
    /**
242
     * @param mixed $row
243
     *
244
     * @return mixed
245
     */
246
    private function fixRow($row, bool $iterateRow, bool $fixCase)
247
    {
248
        if ($row === false) {
249
            return $row;
250
        }
251
252
        if ($fixCase) {
253
            assert($this->case !== null);
254
            $row = array_change_key_case($row, $this->case);
255
        }
256
257
        if ($iterateRow) {
258
            foreach ($row as $k => $v) {
259
                if (($this->portability & Connection::PORTABILITY_EMPTY_TO_NULL) !== 0 && $v === '') {
260
                    $row[$k] = null;
261
                } elseif (($this->portability & Connection::PORTABILITY_RTRIM) !== 0 && is_string($v)) {
262
                    $row[$k] = rtrim($v);
263
                }
264
            }
265
        }
266
267
        return $row;
268
    }
269
}
270