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
Bug
introduced
by
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
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 |