Failed Conditions
Pull Request — master (#4007)
by Sergei
62:50
created

Statement::iterateColumn()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
cc 2
eloc 4
nc 2
nop 0
dl 0
loc 6
ccs 0
cts 0
cp 0
crap 6
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Doctrine\DBAL;
6
7
use Doctrine\DBAL\Driver\DriverException;
8
use Doctrine\DBAL\Driver\Statement as DriverStatement;
9
use Doctrine\DBAL\Platforms\AbstractPlatform;
10
use Doctrine\DBAL\Types\Type;
11
use Throwable;
12
use Traversable;
13
use function is_string;
14
15
/**
16
 * A thin wrapper around a Doctrine\DBAL\Driver\Statement that adds support
17
 * for logging, DBAL mapping types, etc.
18
 */
19
class Statement implements DriverStatement
20
{
21
    /**
22
     * The SQL statement.
23
     *
24
     * @var string
25
     */
26
    protected $sql;
27
28
    /**
29
     * The bound parameters.
30
     *
31
     * @var mixed[]
32
     */
33
    protected $params = [];
34
35
    /**
36
     * The parameter types.
37
     *
38
     * @var int[]|string[]|Type[]
39
     */
40
    protected $types = [];
41
42
    /**
43
     * The underlying driver statement.
44
     *
45
     * @var DriverStatement
46
     */
47
    protected $stmt;
48
49
    /**
50
     * The underlying database platform.
51
     *
52
     * @var AbstractPlatform
53
     */
54
    protected $platform;
55
56
    /**
57
     * The connection this statement is bound to and executed on.
58
     *
59
     * @var Connection
60
     */
61
    protected $conn;
62
63
    /**
64
     * Creates a new <tt>Statement</tt> for the given SQL and <tt>Connection</tt>.
65
     *
66
     * @param string     $sql  The SQL of the statement.
67
     * @param Connection $conn The connection on which the statement should be executed.
68
     */
69 1971
    public function __construct(string $sql, Connection $conn)
70
    {
71 1971
        $this->sql      = $sql;
72 1971
        $this->stmt     = $conn->getWrappedConnection()->prepare($sql);
73 1949
        $this->conn     = $conn;
74 1949
        $this->platform = $conn->getDatabasePlatform();
75 1949
    }
76
77
    /**
78
     * Binds a parameter value to the statement.
79
     *
80
     * The value can optionally be bound with a PDO binding type or a DBAL mapping type.
81
     * If bound with a DBAL mapping type, the binding type is derived from the mapping
82
     * type and the value undergoes the conversion routines of the mapping type before
83
     * being bound.
84
     *
85
     * @param string|int      $param Parameter identifier. For a prepared statement using named placeholders,
86
     *                               this will be a parameter name of the form :name. For a prepared statement
87
     *                               using question mark placeholders, this will be the 1-indexed position
88
     *                               of the parameter.
89
     * @param mixed           $value The value to bind to the parameter.
90
     * @param string|int|Type $type  Either one of the constants defined in {@link \Doctrine\DBAL\ParameterType}
91
     *                               or a DBAL mapping type name or instance.
92
     *
93
     * @throws DBALException
94
     * @throws DriverException
95
     */
96 211
    public function bindValue($param, $value, $type = ParameterType::STRING) : void
97
    {
98 211
        $this->params[$param] = $value;
99 211
        $this->types[$param]  = $type;
100
101 211
        if (is_string($type)) {
102 22
            $type = Type::getType($type);
103
        }
104
105 211
        if ($type instanceof Type) {
106 22
            $value       = $type->convertToDatabaseValue($value, $this->platform);
107 22
            $bindingType = $type->getBindingType();
108
        } else {
109 189
            $bindingType = $type;
110
        }
111
112 211
        $this->stmt->bindValue($param, $value, $bindingType);
113 211
    }
114
115
    /**
116
     * Binds a parameter to a value by reference.
117
     *
118
     * Binding a parameter by reference does not support DBAL mapping types.
119
     *
120
     * @param string|int $param    Parameter identifier. For a prepared statement using named placeholders,
121
     *                             this will be a parameter name of the form :name. For a prepared statement
122
     *                             using question mark placeholders, this will be the 1-indexed position
123
     *                             of the parameter.
124
     * @param mixed      $variable The variable to bind to the parameter.
125
     * @param int        $type     The PDO binding type.
126
     * @param int|null   $length   Must be specified when using an OUT bind
127
     *                             so that PHP allocates enough memory to hold the returned value.
128
     *
129
     * @throws DriverException
130
     */
131 549
    public function bindParam($param, &$variable, int $type = ParameterType::STRING, ?int $length = null) : void
132
    {
133 549
        $this->params[$param] = $variable;
134 549
        $this->types[$param]  = $type;
135
136 549
        $this->stmt->bindParam($param, $variable, $type, $length);
137 549
    }
138
139
    /**
140
     * {@inheritDoc}
141
     *
142
     * @throws DBALException
143
     */
144 1794
    public function execute(?array $params = null) : void
145
    {
146 1794
        if ($params !== null) {
147 108
            $this->params = $params;
148
        }
149
150 1794
        $logger = $this->conn->getConfiguration()->getSQLLogger();
151 1794
        $logger->startQuery($this->sql, $this->params, $this->types);
152
153
        try {
154 1794
            $this->stmt->execute($params);
155 35
        } catch (Throwable $ex) {
156 35
            throw DBALException::driverExceptionDuringQuery(
157 35
                $this->conn->getDriver(),
158 35
                $ex,
159 35
                $this->sql,
160 35
                $this->conn->resolveParams($this->params, $this->types)
161
            );
162 1759
        } finally {
163 1794
            $logger->stopQuery();
164
        }
165
166 1759
        $this->params = [];
167 1759
        $this->types  = [];
168 1759
    }
169
170 176
    public function closeCursor() : void
171
    {
172 176
        $this->stmt->closeCursor();
173 176
    }
174
175
    /**
176
     * Returns the number of columns in the result set.
177
     */
178
    public function columnCount() : int
179
    {
180
        return $this->stmt->columnCount();
181
    }
182
183 1861
    /**
184
     * {@inheritdoc}
185 1861
     *
186 1861
     * @throws DBALException
187
     */
188
    public function fetchNumeric()
189
    {
190
        try {
191
            return $this->stmt->fetchNumeric();
192
        } catch (DriverException $e) {
193 22
            throw DBALException::driverException($this->conn->getDriver(), $e);
194
        }
195 22
    }
196
197
    /**
198
     * {@inheritdoc}
199
     *
200
     * @throws DBALException
201 205
     */
202
    public function fetchAssociative()
203 205
    {
204
        try {
205
            return $this->stmt->fetchAssociative();
206
        } catch (DriverException $e) {
207
            throw DBALException::driverException($this->conn->getDriver(), $e);
208
        }
209 132
    }
210
211 132
    /**
212
     * {@inheritDoc}
213
     *
214
     * @throws DBALException
215
     */
216
    public function fetchColumn()
217 1342
    {
218
        try {
219 1342
            return $this->stmt->fetchColumn();
220
        } catch (DriverException $e) {
221
            throw DBALException::driverException($this->conn->getDriver(), $e);
222
        }
223
    }
224
225
    /**
226
     * {@inheritdoc}
227 88
     *
228
     * @throws DBALException
229 88
     */
230
    public function fetchAllNumeric() : array
231
    {
232
        try {
233
            return $this->stmt->fetchAllNumeric();
234
        } catch (DriverException $e) {
235 1
            throw DBALException::driverException($this->conn->getDriver(), $e);
236
        }
237 1
    }
238
239
    /**
240
     * {@inheritdoc}
241
     *
242
     * @throws DBALException
243
     */
244
    public function fetchAllAssociative() : array
245
    {
246
        try {
247
            return $this->stmt->fetchAllAssociative();
248
        } catch (DriverException $e) {
249
            throw DBALException::driverException($this->conn->getDriver(), $e);
250
        }
251
    }
252
253
    /**
254
     * {@inheritdoc}
255
     *
256
     * @throws DBALException
257
     */
258
    public function fetchAllColumn() : array
259
    {
260
        try {
261
            return $this->stmt->fetchAllColumn();
262
        } catch (DriverException $e) {
263
            throw DBALException::driverException($this->conn->getDriver(), $e);
264
        }
265
    }
266
267
    /**
268
     * {@inheritDoc}
269
     *
270
     * @return Traversable<int,array<int,mixed>>
271
     *
272
     * @throws DBALException
273
     */
274
    public function iterateNumeric() : Traversable
275
    {
276
        try {
277
            yield from $this->stmt->iterateNumeric();
278
        } catch (DriverException $e) {
279
            throw DBALException::driverException($this->conn->getDriver(), $e);
280
        }
281
    }
282
283
    /**
284
     * {@inheritDoc}
285
     *
286
     * @return Traversable<int,array<string,mixed>>
287
     *
288
     * @throws DBALException
289
     */
290
    public function iterateAssociative() : Traversable
291
    {
292
        try {
293
            yield from $this->stmt->iterateAssociative();
294
        } catch (DriverException $e) {
295
            throw DBALException::driverException($this->conn->getDriver(), $e);
296
        }
297
    }
298
299
    /**
300
     * {@inheritDoc}
301
     *
302
     * @return Traversable<int,mixed>
303
     *
304
     * @throws DBALException
305
     */
306
    public function iterateColumn() : Traversable
307
    {
308
        try {
309
            yield from $this->stmt->iterateColumn();
310
        } catch (DriverException $e) {
311
            throw DBALException::driverException($this->conn->getDriver(), $e);
312
        }
313
    }
314
315
    /**
316
     * Returns the number of rows affected by the last execution of this statement.
317
     *
318
     * @return int The number of affected rows.
319
     */
320
    public function rowCount() : int
321
    {
322
        return $this->stmt->rowCount();
323
    }
324
325
    /**
326
     * Gets the wrapped driver statement.
327
     */
328
    public function getWrappedStatement() : DriverStatement
329
    {
330
        return $this->stmt;
331
    }
332
}
333