Failed Conditions
Pull Request — master (#3260)
by Michael
61:30
created

PDOStatement::fetchAll()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 18
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 3.1825

Importance

Changes 0
Metric Value
eloc 11
dl 0
loc 18
ccs 8
cts 11
cp 0.7272
rs 9.9
c 0
b 0
f 0
cc 3
nc 4
nop 2
crap 3.1825
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Doctrine\DBAL\Driver;
6
7
use Doctrine\DBAL\DBALException;
8
use Doctrine\DBAL\FetchMode;
9
use Doctrine\DBAL\ParameterType;
10
use IteratorAggregate;
11
use PDO;
12
use const E_USER_DEPRECATED;
13
use function array_slice;
14
use function assert;
15
use function count;
16
use function func_get_args;
17
use function is_array;
18
use function sprintf;
19
use function trigger_error;
20
21
/**
22
 * The PDO implementation of the Statement interface.
23
 * Used by all PDO-based drivers.
24
 */
25
class PDOStatement implements IteratorAggregate, Statement
26
{
27
    private const PARAM_TYPE_MAP = [
28
        ParameterType::NULL         => PDO::PARAM_NULL,
29
        ParameterType::INTEGER      => PDO::PARAM_INT,
30
        ParameterType::STRING       => PDO::PARAM_STR,
31
        ParameterType::BINARY       => PDO::PARAM_LOB,
32
        ParameterType::LARGE_OBJECT => PDO::PARAM_LOB,
33
        ParameterType::BOOLEAN      => PDO::PARAM_BOOL,
34
    ];
35
36
    private const FETCH_MODE_MAP = [
37
        FetchMode::ASSOCIATIVE     => PDO::FETCH_ASSOC,
38
        FetchMode::NUMERIC         => PDO::FETCH_NUM,
39
        FetchMode::MIXED           => PDO::FETCH_BOTH,
40
        FetchMode::STANDARD_OBJECT => PDO::FETCH_OBJ,
41
        FetchMode::COLUMN          => PDO::FETCH_COLUMN,
42
        FetchMode::CUSTOM_OBJECT   => PDO::FETCH_CLASS,
43 4809
    ];
44
45 4809
    /** @var \PDOStatement */
46
    private $stmt;
47
48
    public function __construct(\PDOStatement $stmt)
49
    {
50 4777
        $this->stmt = $stmt;
51
    }
52 4777
53
    /**
54
     * {@inheritdoc}
55
     */
56
    public function setFetchMode($fetchMode, ...$args) : void
57
    {
58
        $fetchMode = $this->convertFetchMode($fetchMode);
59 4777
60 4777
        try {
61
            $this->stmt->setFetchMode($fetchMode, ...$args);
62
        } catch (\PDOException $exception) {
63 3323
            throw new PDOException($exception);
64 3323
        }
65
    }
66
67
    /**
68
     * {@inheritdoc}
69
     */
70
    public function bindValue($param, $value, $type = ParameterType::STRING) : void
71
    {
72
        $type = $this->convertParamType($type);
73
74
        try {
75
            $this->stmt->bindValue($param, $value, $type);
76 4322
        } catch (\PDOException $exception) {
77
            throw new PDOException($exception);
78 4322
        }
79
    }
80
81 4322
    /**
82
     * {@inheritdoc}
83
     */
84
    public function bindParam($column, &$variable, $type = ParameterType::STRING, $length = null, $driverOptions = null) : void
85
    {
86
        $type            = $this->convertParamType($type);
87
        $extraParameters = array_slice(func_get_args(), 3);
88
89
        if (count($extraParameters) !== 0) {
90 4455
            $extraParameters[0] = $extraParameters[0] ?? 0;
91
        }
92 4455
93
        try {
94
            $this->stmt->bindParam($column, $variable, $type, ...$extraParameters);
0 ignored issues
show
Bug introduced by
$extraParameters is expanded, but the parameter $length of PDOStatement::bindParam() does not expect variable arguments. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

94
            $this->stmt->bindParam($column, $variable, $type, /** @scrutinizer ignore-type */ ...$extraParameters);
Loading history...
95 4455
        } catch (\PDOException $exception) {
96
            throw new PDOException($exception);
97
        }
98
    }
99
100
    /**
101
     * {@inheritdoc}
102
     */
103
    public function closeCursor() : void
104 2508
    {
105
        $this->stmt->closeCursor();
106
    }
107 2508
108
    /**
109
     * {@inheritdoc}
110
     */
111
    public function columnCount()
112
    {
113
        return $this->stmt->columnCount();
114
    }
115
116
    /**
117
     * {@inheritdoc}
118 4682
     */
119
    public function execute($params = null) : void
120
    {
121 4682
        try {
122 4216
            $this->stmt->execute($params);
123 3217
        } catch (\PDOException $exception) {
124
            throw new PDOException($exception);
125
        }
126
    }
127
128
    /**
129
     * {@inheritdoc}
130 4428
     */
131
    public function rowCount() : int
132 4428
    {
133
        return $this->stmt->rowCount();
134 4428
    }
135 4419
136
    /**
137
     * {@inheritdoc}
138
     */
139 4428
    public function fetch($fetchMode = null, ...$args)
140
    {
141
        try {
142
            if ($fetchMode === null) {
143
                return $this->stmt->fetch();
144
            }
145
146
            $fetchMode = $this->convertFetchMode($fetchMode);
147
148 4655
            return $this->stmt->fetch($fetchMode, ...$args);
0 ignored issues
show
Bug introduced by
$args is expanded, but the parameter $cursor_orientation of PDOStatement::fetch() does not expect variable arguments. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

148
            return $this->stmt->fetch($fetchMode, /** @scrutinizer ignore-type */ ...$args);
Loading history...
149
        } catch (\PDOException $exception) {
150 4655
            throw new PDOException($exception);
151
        }
152 4655
    }
153 4566
154
    /**
155
     * {@inheritdoc}
156 4655
     */
157 4370
    public function fetchAll($fetchMode = null, ...$args)
158 4566
    {
159 4565
        try {
160 3356
            if ($fetchMode === null) {
161 3356
                $data = $this->stmt->fetchAll();
162
            } else {
163
                $data = $this->stmt->fetchAll(
164
                    $this->convertFetchMode($fetchMode),
165
                    ...$args
0 ignored issues
show
Bug introduced by
$args is expanded, but the parameter $fetch_argument of PDOStatement::fetchAll() does not expect variable arguments. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

165
                    /** @scrutinizer ignore-type */ ...$args
Loading history...
166
                );
167 4655
            }
168 4655
        } catch (\PDOException $exception) {
169
            throw new PDOException($exception);
170 4655
        }
171
172
        assert(is_array($data));
173
174
        return $data;
175
    }
176
177
    /**
178
     * {@inheritdoc}
179 4386
     */
180
    public function fetchColumn($columnIndex = 0)
181
    {
182 4386
        try {
183
            $value = $this->stmt->fetchColumn($columnIndex);
184
185
            if ($value === null) {
186
                $columnCount = $this->columnCount();
187
188
                if ($columnIndex < 0 || $columnIndex >= $columnCount) {
189
                    throw DBALException::invalidColumnIndex($columnIndex, $columnCount);
190
                }
191
            }
192
193 4564
            return $value;
194
        } catch (\PDOException $exception) {
195 4564
            throw new PDOException($exception);
196
        }
197
    }
198
199
    /**
200
     * Converts DBAL parameter type to PDO parameter type
201
     *
202
     * @param int $type Parameter type
203
     */
204
    private function convertParamType(int $type) : int
205 4564
    {
206
        if (! isset(self::PARAM_TYPE_MAP[$type])) {
207
            // TODO: next major: throw an exception
208
            @trigger_error(sprintf(
209
                'Using a PDO parameter type (%d given) is deprecated and will cause an error in Doctrine 3.0',
210
                $type
211
            ), E_USER_DEPRECATED);
212
213 4777
            return $type;
214
        }
215 4777
216
        return self::PARAM_TYPE_MAP[$type];
217 2652
    }
218
219 1
    /**
220 2652
     * Converts DBAL fetch mode to PDO fetch mode
221 2652
     *
222
     * @param int $fetchMode Fetch mode
223 2652
     */
224
    private function convertFetchMode(int $fetchMode) : int
225
    {
226 4777
        if (! isset(self::FETCH_MODE_MAP[$fetchMode])) {
227
            // TODO: next major: throw an exception
228
            @trigger_error(sprintf(
229
                'Using a PDO fetch mode or their combination (%d given)' .
230
                ' is deprecated and will cause an error in Doctrine 3.0',
231
                $fetchMode
232
            ), E_USER_DEPRECATED);
233
234
            return $fetchMode;
235
        }
236
237
        return self::FETCH_MODE_MAP[$fetchMode];
238
    }
239
240
    /**
241
     * {@inheritdoc}
242
     */
243
    public function getIterator()
244
    {
245
        yield from $this->stmt;
246
    }
247
}
248