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\FetchMode; |
||
10 | use Doctrine\DBAL\ParameterType; |
||
11 | use IteratorAggregate; |
||
12 | use PDO; |
||
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 | |||
19 | /** |
||
20 | * The PDO implementation of the Statement interface. |
||
21 | * Used by all PDO-based drivers. |
||
22 | */ |
||
23 | class PDOStatement implements IteratorAggregate, Statement |
||
24 | { |
||
25 | private const PARAM_TYPE_MAP = [ |
||
26 | ParameterType::NULL => PDO::PARAM_NULL, |
||
27 | ParameterType::INTEGER => PDO::PARAM_INT, |
||
28 | ParameterType::STRING => PDO::PARAM_STR, |
||
29 | ParameterType::BINARY => PDO::PARAM_LOB, |
||
30 | ParameterType::LARGE_OBJECT => PDO::PARAM_LOB, |
||
31 | ParameterType::BOOLEAN => PDO::PARAM_BOOL, |
||
32 | ]; |
||
33 | |||
34 | private const FETCH_MODE_MAP = [ |
||
35 | FetchMode::ASSOCIATIVE => PDO::FETCH_ASSOC, |
||
36 | FetchMode::NUMERIC => PDO::FETCH_NUM, |
||
37 | FetchMode::MIXED => PDO::FETCH_BOTH, |
||
38 | FetchMode::COLUMN => PDO::FETCH_COLUMN, |
||
39 | ]; |
||
40 | |||
41 | /** @var \PDOStatement */ |
||
42 | private $stmt; |
||
43 | |||
44 | 4621 | public function __construct(\PDOStatement $stmt) |
|
45 | { |
||
46 | 4621 | $this->stmt = $stmt; |
|
47 | 4621 | } |
|
48 | |||
49 | 4384 | public function setFetchMode(int $fetchMode) : void |
|
50 | { |
||
51 | 4384 | $fetchMode = $this->convertFetchMode($fetchMode); |
|
52 | |||
53 | try { |
||
54 | 4384 | $this->stmt->setFetchMode($fetchMode); |
|
55 | } catch (\PDOException $exception) { |
||
56 | throw new PDOException($exception); |
||
57 | } |
||
58 | 4384 | } |
|
59 | |||
60 | /** |
||
61 | * {@inheritdoc} |
||
62 | */ |
||
63 | 1631 | public function bindValue($param, $value, int $type = ParameterType::STRING) : void |
|
64 | { |
||
65 | 1631 | $type = $this->convertParamType($type); |
|
66 | |||
67 | try { |
||
68 | 1631 | $this->stmt->bindValue($param, $value, $type); |
|
69 | 48 | } catch (\PDOException $exception) { |
|
70 | throw new PDOException($exception); |
||
71 | } |
||
72 | 1631 | } |
|
73 | |||
74 | /** |
||
75 | * @param mixed $param |
||
76 | * @param mixed $variable |
||
77 | * @param mixed $driverOptions |
||
78 | */ |
||
79 | 421 | public function bindParam($param, &$variable, int $type = ParameterType::STRING, ?int $length = null, $driverOptions = null) : void |
|
80 | { |
||
81 | 421 | $type = $this->convertParamType($type); |
|
82 | 421 | $extraParameters = array_slice(func_get_args(), 3); |
|
83 | |||
84 | 421 | if (count($extraParameters) !== 0) { |
|
85 | 421 | $extraParameters[0] = $extraParameters[0] ?? 0; |
|
86 | } |
||
87 | |||
88 | try { |
||
89 | 421 | $this->stmt->bindParam($param, $variable, $type, ...$extraParameters); |
|
0 ignored issues
–
show
Bug
introduced
by
Loading history...
|
|||
90 | 4 | } catch (\PDOException $exception) { |
|
91 | throw new PDOException($exception); |
||
92 | } |
||
93 | 421 | } |
|
94 | |||
95 | 247 | public function closeCursor() : void |
|
96 | { |
||
97 | 247 | $this->stmt->closeCursor(); |
|
98 | 247 | } |
|
99 | |||
100 | 52 | public function columnCount() : int |
|
101 | { |
||
102 | 52 | return $this->stmt->columnCount(); |
|
103 | } |
||
104 | |||
105 | /** |
||
106 | * {@inheritdoc} |
||
107 | */ |
||
108 | 2438 | public function execute(?array $params = null) : void |
|
109 | { |
||
110 | try { |
||
111 | 2438 | $this->stmt->execute($params); |
|
112 | 89 | } catch (\PDOException $exception) { |
|
113 | 89 | throw new PDOException($exception); |
|
114 | } |
||
115 | 2409 | } |
|
116 | |||
117 | 1244 | public function rowCount() : int |
|
118 | { |
||
119 | 1244 | return $this->stmt->rowCount(); |
|
120 | } |
||
121 | |||
122 | /** |
||
123 | * {@inheritdoc} |
||
124 | */ |
||
125 | 1695 | public function fetch(?int $fetchMode = null) |
|
126 | { |
||
127 | try { |
||
128 | 1695 | if ($fetchMode === null) { |
|
129 | 91 | return $this->stmt->fetch(); |
|
130 | } |
||
131 | |||
132 | 1604 | return $this->stmt->fetch( |
|
133 | 1604 | $this->convertFetchMode($fetchMode) |
|
134 | ); |
||
135 | } catch (\PDOException $exception) { |
||
136 | throw new PDOException($exception); |
||
137 | } |
||
138 | } |
||
139 | |||
140 | /** |
||
141 | * {@inheritdoc} |
||
142 | */ |
||
143 | 1815 | public function fetchAll(?int $fetchMode = null) : array |
|
144 | { |
||
145 | try { |
||
146 | 1815 | if ($fetchMode === null) { |
|
147 | 1589 | $data = $this->stmt->fetchAll(); |
|
148 | } else { |
||
149 | 437 | $data = $this->stmt->fetchAll( |
|
150 | 1815 | $this->convertFetchMode($fetchMode) |
|
151 | ); |
||
152 | } |
||
153 | } catch (\PDOException $exception) { |
||
154 | throw new PDOException($exception); |
||
155 | } |
||
156 | |||
157 | 1815 | assert(is_array($data)); |
|
158 | |||
159 | 1815 | return $data; |
|
160 | } |
||
161 | |||
162 | /** |
||
163 | * {@inheritdoc} |
||
164 | */ |
||
165 | 2674 | public function fetchColumn() |
|
166 | { |
||
167 | try { |
||
168 | 2674 | return $this->stmt->fetchColumn(); |
|
169 | } catch (\PDOException $exception) { |
||
170 | throw new PDOException($exception); |
||
171 | } |
||
172 | } |
||
173 | |||
174 | /** |
||
175 | * Converts DBAL parameter type to PDO parameter type |
||
176 | * |
||
177 | * @param int $type Parameter type |
||
178 | */ |
||
179 | 2028 | private function convertParamType(int $type) : int |
|
180 | { |
||
181 | 2028 | if (! isset(self::PARAM_TYPE_MAP[$type])) { |
|
182 | throw UnknownParamType::new($type); |
||
183 | } |
||
184 | |||
185 | 2028 | return self::PARAM_TYPE_MAP[$type]; |
|
186 | } |
||
187 | |||
188 | /** |
||
189 | * Converts DBAL fetch mode to PDO fetch mode |
||
190 | * |
||
191 | * @param int $fetchMode Fetch mode |
||
192 | */ |
||
193 | 4384 | private function convertFetchMode(int $fetchMode) : int |
|
194 | { |
||
195 | 4384 | if (! isset(self::FETCH_MODE_MAP[$fetchMode])) { |
|
196 | throw UnknownFetchMode::new($fetchMode); |
||
197 | } |
||
198 | |||
199 | 4384 | return self::FETCH_MODE_MAP[$fetchMode]; |
|
200 | } |
||
201 | |||
202 | /** |
||
203 | * {@inheritdoc} |
||
204 | */ |
||
205 | 13 | public function getIterator() |
|
206 | { |
||
207 | 13 | yield from $this->stmt; |
|
208 | 13 | } |
|
209 | } |
||
210 |