Failed Conditions
Push — master ( 01c22b...e42c1f )
by Marco
79:13 queued 10s
created

Statement   A

Complexity

Total Complexity 41

Size/Duplication

Total Lines 200
Duplicated Lines 0 %

Test Coverage

Coverage 97.14%

Importance

Changes 0
Metric Value
wmc 41
eloc 63
dl 0
loc 200
ccs 68
cts 70
cp 0.9714
rs 9.1199
c 0
b 0
f 0

13 Methods

Rating   Name   Duplication   Size   Complexity  
A bindValue() 0 5 1
A columnCount() 0 3 1
A __construct() 0 5 1
A setFetchMode() 0 5 1
A execute() 0 5 1
C fetchAll() 0 32 12
A fetchColumn() 0 13 6
A closeCursor() 0 3 1
A fetch() 0 14 5
A getIterator() 0 3 1
A bindParam() 0 5 1
B fixRow() 0 21 9
A rowCount() 0 5 1

How to fix   Complexity   

Complex Class

Complex classes like Statement often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Statement, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
declare(strict_types=1);
4
5
namespace Doctrine\DBAL\Portability;
6
7
use Doctrine\DBAL\Driver\ResultStatement;
8
use Doctrine\DBAL\Driver\Statement as DriverStatement;
9
use Doctrine\DBAL\Driver\StatementIterator;
10
use Doctrine\DBAL\FetchMode;
11
use Doctrine\DBAL\ParameterType;
12
use IteratorAggregate;
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
class Statement implements IteratorAggregate, DriverStatement
22
{
23
    /** @var int */
24
    private $portability;
25
26
    /** @var DriverStatement|ResultStatement */
27
    private $stmt;
28
29
    /** @var int */
30
    private $case;
31
32
    /** @var int */
33
    private $defaultFetchMode = FetchMode::MIXED;
34
35
    /**
36
     * Wraps <tt>Statement</tt> and applies portability measures.
37
     *
38
     * @param DriverStatement|ResultStatement $stmt
39 346
     */
40
    public function __construct($stmt, Connection $conn)
41 346
    {
42 346
        $this->stmt        = $stmt;
43 346
        $this->portability = $conn->getPortability();
44 346
        $this->case        = $conn->getFetchCase();
45
    }
46
47
    /**
48
     * {@inheritdoc}
49 202
     */
50
    public function bindParam($param, &$variable, int $type = ParameterType::STRING, ?int $length = null) : void
51 202
    {
52
        assert($this->stmt instanceof DriverStatement);
53 202
54
        $this->stmt->bindParam($param, $variable, $type, $length);
55
    }
56
57
    /**
58
     * {@inheritdoc}
59 177
     */
60
    public function bindValue($param, $value, int $type = ParameterType::STRING) : void
61 177
    {
62
        assert($this->stmt instanceof DriverStatement);
63 177
64
        $this->stmt->bindValue($param, $value, $type);
65
    }
66
67
    /**
68
     * {@inheritdoc}
69 152
     */
70
    public function closeCursor() : void
71 152
    {
72
        $this->stmt->closeCursor();
73
    }
74
75
    /**
76
     * {@inheritdoc}
77 2
     */
78
    public function columnCount() : int
79 2
    {
80
        return $this->stmt->columnCount();
81
    }
82
83
    /**
84
     * {@inheritdoc}
85 127
     */
86
    public function execute(?array $params = null) : void
87 127
    {
88
        assert($this->stmt instanceof DriverStatement);
89 127
90
        $this->stmt->execute($params);
91
    }
92
93
    /**
94
     * {@inheritdoc}
95 2
     */
96
    public function setFetchMode(int $fetchMode, ...$args) : void
97 2
    {
98
        $this->defaultFetchMode = $fetchMode;
99 2
100
        $this->stmt->setFetchMode($fetchMode, ...$args);
101
    }
102
103
    /**
104
     * {@inheritdoc}
105 322
     */
106
    public function getIterator()
107 322
    {
108
        return new StatementIterator($this);
109 322
    }
110
111
    /**
112
     * {@inheritdoc}
113
     */
114
    public function fetch(?int $fetchMode = null, ...$args)
115 328
    {
116
        $fetchMode = $fetchMode ?: $this->defaultFetchMode;
117 328
118
        $row = $this->stmt->fetch($fetchMode, ...$args);
119 328
120
        $iterateRow = ($this->portability & (Connection::PORTABILITY_EMPTY_TO_NULL|Connection::PORTABILITY_RTRIM)) !== 0;
121
        $fixCase    = $this->case !== null
122
            && ($fetchMode === FetchMode::ASSOCIATIVE || $fetchMode === FetchMode::MIXED)
123
            && ($this->portability & Connection::PORTABILITY_FIX_CASE);
124
125 350
        $row = $this->fixRow($row, $iterateRow, $fixCase);
126
127 350
        return $row;
128
    }
129
130
    /**
131
     * {@inheritdoc}
132
     */
133 322
    public function fetchAll(?int $fetchMode = null, ...$args) : array
134
    {
135 322
        $fetchMode = $fetchMode ?: $this->defaultFetchMode;
136
137 322
        $rows = $this->stmt->fetchAll($fetchMode, ...$args);
138
139 322
        $iterateRow = ($this->portability & (Connection::PORTABILITY_EMPTY_TO_NULL|Connection::PORTABILITY_RTRIM)) !== 0;
140 322
        $fixCase    = $this->case !== null
141 322
            && ($fetchMode === FetchMode::ASSOCIATIVE || $fetchMode === FetchMode::MIXED)
142 322
            && ($this->portability & Connection::PORTABILITY_FIX_CASE);
143
144 322
        if (! $iterateRow && ! $fixCase) {
145
            return $rows;
146 322
        }
147
148
        if ($fetchMode === FetchMode::COLUMN) {
149
            foreach ($rows as $num => $row) {
150
                $rows[$num] = [$row];
151
            }
152 326
        }
153
154 326
        foreach ($rows as $num => $row) {
155
            $rows[$num] = $this->fixRow($row, $iterateRow, $fixCase);
156 326
        }
157
158
        if ($fetchMode === FetchMode::COLUMN) {
159 326
            foreach ($rows as $num => $row) {
160
                $rows[$num] = $row[0];
161
            }
162 326
        }
163 326
164 326
        return $rows;
165 326
    }
166
167 326
    /**
168
     * @param mixed $row
169
     *
170
     * @return mixed
171 326
     */
172 272
    protected function fixRow($row, bool $iterateRow, bool $fixCase)
173 272
    {
174
        if (! $row) {
175
            return $row;
176
        }
177 326
178 326
        if ($fixCase) {
179
            $row = array_change_key_case($row, $this->case);
180
        }
181 326
182 272
        if ($iterateRow) {
183 272
            foreach ($row as $k => $v) {
184
                if (($this->portability & Connection::PORTABILITY_EMPTY_TO_NULL) && $v === '') {
185
                    $row[$k] = null;
186
                } elseif (($this->portability & Connection::PORTABILITY_RTRIM) && is_string($v)) {
187 326
                    $row[$k] = rtrim($v);
188
                }
189
            }
190
        }
191
192
        return $row;
193
    }
194
195
    /**
196
     * {@inheritdoc}
197 328
     */
198
    public function fetchColumn(int $columnIndex = 0)
199 328
    {
200 322
        $value = $this->stmt->fetchColumn($columnIndex);
201
202
        if ($this->portability & (Connection::PORTABILITY_EMPTY_TO_NULL|Connection::PORTABILITY_RTRIM)) {
203 328
            if (($this->portability & Connection::PORTABILITY_EMPTY_TO_NULL) && $value === '') {
204 113
                $value = null;
205
            } elseif (($this->portability & Connection::PORTABILITY_RTRIM) && is_string($value)) {
206
                $value = rtrim($value);
207 328
            }
208 326
        }
209 326
210 316
        return $value;
211 326
    }
212 152
213
    /**
214
     * {@inheritdoc}
215
     */
216
    public function rowCount() : int
217 328
    {
218
        assert($this->stmt instanceof DriverStatement);
219
220
        return $this->stmt->rowCount();
221
    }
222
}
223