Completed
Push — master ( 1eba78...18908c )
by Sergei
62:05 queued 10s
created

src/Driver/PDOStatement.php (2 issues)

Labels
Severity
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
    public function __construct(\PDOStatement $stmt)
48
    {
49
        $this->stmt = $stmt;
50
    }
51
52
    /**
53
     * {@inheritdoc}
54
     */
55
    public function setFetchMode(int $fetchMode, ...$args) : void
56
    {
57
        $fetchMode = $this->convertFetchMode($fetchMode);
58
59
        try {
60
            $this->stmt->setFetchMode($fetchMode, ...$args);
61
        } catch (\PDOException $exception) {
62
            throw new PDOException($exception);
63
        }
64
    }
65
66
    /**
67
     * {@inheritdoc}
68
     */
69
    public function bindValue($param, $value, int $type = ParameterType::STRING) : void
70
    {
71
        $type = $this->convertParamType($type);
72
73
        try {
74
            $this->stmt->bindValue($param, $value, $type);
75
        } catch (\PDOException $exception) {
76
            throw new PDOException($exception);
77
        }
78
    }
79
80
    /**
81
     * @param mixed $param
82
     * @param mixed $variable
83
     * @param mixed $driverOptions
84
     */
85
    public function bindParam($param, &$variable, int $type = ParameterType::STRING, ?int $length = null, $driverOptions = null) : void
86
    {
87
        $type            = $this->convertParamType($type);
88
        $extraParameters = array_slice(func_get_args(), 3);
89
90
        if (count($extraParameters) !== 0) {
91
            $extraParameters[0] = $extraParameters[0] ?? 0;
92
        }
93
94
        try {
95
            $this->stmt->bindParam($param, $variable, $type, ...$extraParameters);
96
        } catch (\PDOException $exception) {
97
            throw new PDOException($exception);
98
        }
99
    }
100
101
    public function closeCursor() : void
102
    {
103
        $this->stmt->closeCursor();
104
    }
105
106
    public function columnCount() : int
107
    {
108
        return $this->stmt->columnCount();
109
    }
110
111
    /**
112
     * {@inheritdoc}
113
     */
114
    public function execute(?array $params = null) : void
115
    {
116
        try {
117
            $this->stmt->execute($params);
118
        } catch (\PDOException $exception) {
119
            throw new PDOException($exception);
120
        }
121
    }
122
123
    public function rowCount() : int
124
    {
125
        return $this->stmt->rowCount();
126
    }
127
128
    /**
129
     * {@inheritdoc}
130
     */
131
    public function fetch(?int $fetchMode = null, ...$args)
132
    {
133
        try {
134
            if ($fetchMode === null) {
135
                return $this->stmt->fetch();
136
            }
137
138
            $fetchMode = $this->convertFetchMode($fetchMode);
139
140
            return $this->stmt->fetch($fetchMode, ...$args);
0 ignored issues
show
$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

140
            return $this->stmt->fetch($fetchMode, /** @scrutinizer ignore-type */ ...$args);
Loading history...
141
        } catch (\PDOException $exception) {
142
            throw new PDOException($exception);
143
        }
144
    }
145
146
    /**
147
     * {@inheritdoc}
148
     */
149
    public function fetchAll(?int $fetchMode = null, ...$args) : array
150
    {
151
        try {
152
            if ($fetchMode === null) {
153
                $data = $this->stmt->fetchAll();
154
            } else {
155
                $data = $this->stmt->fetchAll(
156
                    $this->convertFetchMode($fetchMode),
157
                    ...$args
0 ignored issues
show
$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

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