Completed
Push — master ( cc3868...bfc8bb )
by Marco
21s queued 15s
created

PDOStatement::fetch()   A

Complexity

Conditions 3
Paths 5

Size

Total Lines 12
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 3.2098

Importance

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

93
            $this->stmt->bindParam($param, $variable, $type, /** @scrutinizer ignore-type */ ...$extraParameters);
Loading history...
94
        } catch (\PDOException $exception) {
95
            throw new PDOException($exception);
96
        }
97 442
    }
98
99
    /**
100
     * {@inheritdoc}
101
     */
102 321
    public function closeCursor() : void
103
    {
104 321
        $this->stmt->closeCursor();
105 321
    }
106
107
    /**
108
     * {@inheritdoc}
109
     */
110 120
    public function columnCount() : int
111
    {
112 120
        return $this->stmt->columnCount();
113
    }
114
115
    /**
116
     * {@inheritdoc}
117
     */
118 3326
    public function execute(?array $params = null) : void
119
    {
120
        try {
121 3326
            $this->stmt->execute($params);
122 185
        } catch (\PDOException $exception) {
123 117
            throw new PDOException($exception);
124
        }
125 3221
    }
126
127
    /**
128
     * {@inheritdoc}
129
     */
130 1727
    public function rowCount() : int
131
    {
132 1727
        return $this->stmt->rowCount();
133
    }
134
135
    /**
136
     * {@inheritdoc}
137
     */
138 2098
    public function fetch(?int $fetchMode = null, ...$args)
139
    {
140
        try {
141 2098
            if ($fetchMode === null) {
142 136
                return $this->stmt->fetch();
143
            }
144
145 1962
            $fetchMode = $this->convertFetchMode($fetchMode);
146
147 1962
            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

147
            return $this->stmt->fetch($fetchMode, /** @scrutinizer ignore-type */ ...$args);
Loading history...
148
        } catch (\PDOException $exception) {
149
            throw new PDOException($exception);
150
        }
151
    }
152
153
    /**
154
     * {@inheritdoc}
155
     */
156 2327
    public function fetchAll(?int $fetchMode = null, ...$args) : array
157
    {
158
        try {
159 2327
            if ($fetchMode === null) {
160 1988
                $data = $this->stmt->fetchAll();
161
            } else {
162 576
                $data = $this->stmt->fetchAll(
163 576
                    $this->convertFetchMode($fetchMode),
164 2310
                    ...$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

164
                    /** @scrutinizer ignore-type */ ...$args
Loading history...
165
                );
166
            }
167 17
        } catch (\PDOException $exception) {
168
            throw new PDOException($exception);
169
        }
170
171 2310
        assert(is_array($data));
172
173 2310
        return $data;
174
    }
175
176
    /**
177
     * {@inheritdoc}
178
     */
179 3395
    public function fetchColumn(int $columnIndex = 0)
180
    {
181
        try {
182 3395
            $value = $this->stmt->fetchColumn($columnIndex);
183
184 3395
            if ($value === null) {
185 52
                $columnCount = $this->columnCount();
186
187 52
                if ($columnIndex < 0 || $columnIndex >= $columnCount) {
188
                    throw InvalidColumnIndex::new($columnIndex, $columnCount);
189
                }
190
            }
191
192 3395
            return $value;
193
        } catch (\PDOException $exception) {
194
            throw new PDOException($exception);
195
        }
196
    }
197
198
    /**
199
     * Converts DBAL parameter type to PDO parameter type
200
     *
201
     * @param int $type Parameter type
202
     */
203 1035
    private function convertParamType(int $type) : int
204
    {
205 1035
        if (! isset(self::PARAM_TYPE_MAP[$type])) {
206
            throw UnknownParamType::new($type);
207
        }
208
209 1035
        return self::PARAM_TYPE_MAP[$type];
210
    }
211
212
    /**
213
     * Converts DBAL fetch mode to PDO fetch mode
214
     *
215
     * @param int $fetchMode Fetch mode
216
     */
217 5724
    private function convertFetchMode(int $fetchMode) : int
218
    {
219 5724
        if (! isset(self::FETCH_MODE_MAP[$fetchMode])) {
220 17
            throw UnknownFetchMode::new($fetchMode);
221
        }
222
223 5724
        return self::FETCH_MODE_MAP[$fetchMode];
224
    }
225
226
    /**
227
     * {@inheritdoc}
228
     */
229 17
    public function getIterator()
230
    {
231 17
        yield from $this->stmt;
232 17
    }
233
}
234