Failed Conditions
Pull Request — master (#2718)
by Ian
06:09
created

StatementSpy::getIterator()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 7
rs 9.4285
cc 2
eloc 4
nc 2
nop 0
1
<?php
2
3
namespace Doctrine\Tests\DBAL\Functional;
4
5
use Doctrine\DBAL\Connection;
6
use Doctrine\DBAL\Driver\Statement;
7
use Doctrine\DBAL\Platforms\AbstractPlatform;
8
use Doctrine\DBAL\Types\Type;
9
use PDO;
10
11
class DataAccessTest extends \Doctrine\Tests\DbalFunctionalTestCase
12
{
13
    static private $generated = false;
14
15
    protected function setUp()
16
    {
17
        parent::setUp();
18
19
        if (self::$generated === false) {
20
            /* @var $sm \Doctrine\DBAL\Schema\AbstractSchemaManager */
21
            $table = new \Doctrine\DBAL\Schema\Table("fetch_table");
22
            $table->addColumn('test_int', 'integer');
23
            $table->addColumn('test_string', 'string');
24
            $table->addColumn('test_datetime', 'datetime', array('notnull' => false));
25
            $table->setPrimaryKey(array('test_int'));
26
27
            $sm = $this->_conn->getSchemaManager();
28
            $sm->createTable($table);
29
30
            $this->_conn->insert('fetch_table', array('test_int' => 1, 'test_string' => 'foo', 'test_datetime' => '2010-01-01 10:10:10'));
31
            self::$generated = true;
32
        }
33
    }
34
35
    public function testPrepareWithBindValue()
36
    {
37
        $sql = "SELECT test_int, test_string FROM fetch_table WHERE test_int = ? AND test_string = ?";
38
        $stmt = $this->_conn->prepare($sql);
39
        $this->assertInstanceOf('Doctrine\DBAL\Statement', $stmt);
40
41
        $stmt->bindValue(1, 1);
42
        $stmt->bindValue(2, 'foo');
43
        $stmt->execute();
44
45
        $row = $stmt->fetch(\PDO::FETCH_ASSOC);
46
        $row = array_change_key_case($row, \CASE_LOWER);
47
        $this->assertEquals(array('test_int' => 1, 'test_string' => 'foo'), $row);
48
    }
49
50
    public function testPrepareWithBindParam()
51
    {
52
        $paramInt = 1;
53
        $paramStr = 'foo';
54
55
        $sql = "SELECT test_int, test_string FROM fetch_table WHERE test_int = ? AND test_string = ?";
56
        $stmt = $this->_conn->prepare($sql);
57
        $this->assertInstanceOf('Doctrine\DBAL\Statement', $stmt);
58
59
        $stmt->bindParam(1, $paramInt);
60
        $stmt->bindParam(2, $paramStr);
61
        $stmt->execute();
62
63
        $row = $stmt->fetch(\PDO::FETCH_ASSOC);
64
        $row = array_change_key_case($row, \CASE_LOWER);
65
        $this->assertEquals(array('test_int' => 1, 'test_string' => 'foo'), $row);
66
    }
67
68
    public function testPrepareWithFetchAll()
69
    {
70
        $paramInt = 1;
71
        $paramStr = 'foo';
72
73
        $sql = "SELECT test_int, test_string FROM fetch_table WHERE test_int = ? AND test_string = ?";
74
        $stmt = $this->_conn->prepare($sql);
75
        $this->assertInstanceOf('Doctrine\DBAL\Statement', $stmt);
76
77
        $stmt->bindParam(1, $paramInt);
78
        $stmt->bindParam(2, $paramStr);
79
        $stmt->execute();
80
81
        $rows = $stmt->fetchAll(\PDO::FETCH_ASSOC);
82
        $rows[0] = array_change_key_case($rows[0], \CASE_LOWER);
83
        $this->assertEquals(array('test_int' => 1, 'test_string' => 'foo'), $rows[0]);
84
    }
85
86
    /**
87
     * @group DBAL-228
88
     */
89
    public function testPrepareWithFetchAllBoth()
90
    {
91
        $paramInt = 1;
92
        $paramStr = 'foo';
93
94
        $sql = "SELECT test_int, test_string FROM fetch_table WHERE test_int = ? AND test_string = ?";
95
        $stmt = $this->_conn->prepare($sql);
96
        $this->assertInstanceOf('Doctrine\DBAL\Statement', $stmt);
97
98
        $stmt->bindParam(1, $paramInt);
99
        $stmt->bindParam(2, $paramStr);
100
        $stmt->execute();
101
102
        $rows = $stmt->fetchAll(\PDO::FETCH_BOTH);
103
        $rows[0] = array_change_key_case($rows[0], \CASE_LOWER);
104
        $this->assertEquals(array('test_int' => 1, 'test_string' => 'foo', 0 => 1, 1 => 'foo'), $rows[0]);
105
    }
106
107
    public function testPrepareWithFetchColumn()
108
    {
109
        $paramInt = 1;
110
        $paramStr = 'foo';
111
112
        $sql = "SELECT test_int FROM fetch_table WHERE test_int = ? AND test_string = ?";
113
        $stmt = $this->_conn->prepare($sql);
114
        $this->assertInstanceOf('Doctrine\DBAL\Statement', $stmt);
115
116
        $stmt->bindParam(1, $paramInt);
117
        $stmt->bindParam(2, $paramStr);
118
        $stmt->execute();
119
120
        $column = $stmt->fetchColumn();
121
        $this->assertEquals(1, $column);
122
    }
123
124
    public function testPrepareWithIterator()
125
    {
126
        $paramInt = 1;
127
        $paramStr = 'foo';
128
129
        $sql = "SELECT test_int, test_string FROM fetch_table WHERE test_int = ? AND test_string = ?";
130
        $stmt = $this->_conn->prepare($sql);
131
        $this->assertInstanceOf('Doctrine\DBAL\Statement', $stmt);
132
133
        $stmt->bindParam(1, $paramInt);
134
        $stmt->bindParam(2, $paramStr);
135
        $stmt->execute();
136
137
        $rows = array();
138
        $stmt->setFetchMode(\PDO::FETCH_ASSOC);
139
        foreach ($stmt as $row) {
140
            $rows[] = array_change_key_case($row, \CASE_LOWER);
141
        }
142
143
        $this->assertEquals(array('test_int' => 1, 'test_string' => 'foo'), $rows[0]);
144
    }
145
146
    public function testPrepareWithQuoted()
147
    {
148
        $table = 'fetch_table';
149
        $paramInt = 1;
150
        $paramStr = 'foo';
151
152
        $sql = "SELECT test_int, test_string FROM " . $this->_conn->quoteIdentifier($table) . " ".
153
               "WHERE test_int = " . $this->_conn->quote($paramInt) . " AND test_string = " . $this->_conn->quote($paramStr);
154
        $stmt = $this->_conn->prepare($sql);
155
        $this->assertInstanceOf('Doctrine\DBAL\Statement', $stmt);
156
    }
157
158
    public function testPrepareWithExecuteParams()
159
    {
160
        $paramInt = 1;
161
        $paramStr = 'foo';
162
163
        $sql = "SELECT test_int, test_string FROM fetch_table WHERE test_int = ? AND test_string = ?";
164
        $stmt = $this->_conn->prepare($sql);
165
        $this->assertInstanceOf('Doctrine\DBAL\Statement', $stmt);
166
        $stmt->execute(array($paramInt, $paramStr));
167
168
        $row = $stmt->fetch(\PDO::FETCH_ASSOC);
169
        $this->assertTrue($row !== false);
170
        $row = array_change_key_case($row, \CASE_LOWER);
171
        $this->assertEquals(array('test_int' => 1, 'test_string' => 'foo'), $row);
172
    }
173
174
    public function testFetchAll()
175
    {
176
        $sql = "SELECT test_int, test_string FROM fetch_table WHERE test_int = ? AND test_string = ?";
177
        $data = $this->_conn->fetchAll($sql, array(1, 'foo'));
178
179
        $this->assertEquals(1, count($data));
180
181
        $row = $data[0];
182
        $this->assertEquals(2, count($row));
183
184
        $row = array_change_key_case($row, \CASE_LOWER);
185
        $this->assertEquals(1, $row['test_int']);
186
        $this->assertEquals('foo', $row['test_string']);
187
    }
188
189
    /**
190
     * @group DBAL-209
191
     */
192
    public function testFetchAllWithTypes()
193
    {
194
        $datetimeString = '2010-01-01 10:10:10';
195
        $datetime = new \DateTime($datetimeString);
196
        $sql = "SELECT test_int, test_datetime FROM fetch_table WHERE test_int = ? AND test_datetime = ?";
197
        $data = $this->_conn->fetchAll($sql, array(1, $datetime), array(PDO::PARAM_STR, Type::DATETIME));
198
199
        $this->assertEquals(1, count($data));
200
201
        $row = $data[0];
202
        $this->assertEquals(2, count($row));
203
204
        $row = array_change_key_case($row, \CASE_LOWER);
205
        $this->assertEquals(1, $row['test_int']);
206
        $this->assertStringStartsWith($datetimeString, $row['test_datetime']);
207
    }
208
209
    /**
210
     * @group DBAL-209
211
     * @expectedException \Doctrine\DBAL\DBALException
212
     */
213 View Code Duplication
    public function testFetchAllWithMissingTypes()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
214
    {
215
        if ($this->_conn->getDriver() instanceof \Doctrine\DBAL\Driver\Mysqli\Driver ||
216
            $this->_conn->getDriver() instanceof \Doctrine\DBAL\Driver\SQLSrv\Driver) {
217
            $this->markTestSkipped('mysqli and sqlsrv actually supports this');
218
        }
219
220
        $datetimeString = '2010-01-01 10:10:10';
221
        $datetime = new \DateTime($datetimeString);
222
        $sql = "SELECT test_int, test_datetime FROM fetch_table WHERE test_int = ? AND test_datetime = ?";
223
        $data = $this->_conn->fetchAll($sql, array(1, $datetime));
0 ignored issues
show
Unused Code introduced by
$data is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
224
    }
225
226
    public function testFetchBoth()
227
    {
228
        $sql = "SELECT test_int, test_string FROM fetch_table WHERE test_int = ? AND test_string = ?";
229
        $row = $this->_conn->executeQuery($sql, array(1, 'foo'))->fetch(\PDO::FETCH_BOTH);
230
231
        $this->assertTrue($row !== false);
232
233
        $row = array_change_key_case($row, \CASE_LOWER);
234
235
        $this->assertEquals(1, $row['test_int']);
236
        $this->assertEquals('foo', $row['test_string']);
237
        $this->assertEquals(1, $row[0]);
238
        $this->assertEquals('foo', $row[1]);
239
    }
240
241
    public function testFetchNoResult()
242
    {
243
        self::assertFalse(
244
            $this->_conn->executeQuery('SELECT test_int FROM fetch_table WHERE test_int = ?', [-1])->fetch()
245
        );
246
    }
247
248
    public function testFetchAssoc()
249
    {
250
        $sql = "SELECT test_int, test_string FROM fetch_table WHERE test_int = ? AND test_string = ?";
251
        $row = $this->_conn->fetchAssoc($sql, array(1, 'foo'));
252
253
        $this->assertTrue($row !== false);
254
255
        $row = array_change_key_case($row, \CASE_LOWER);
256
257
        $this->assertEquals(1, $row['test_int']);
258
        $this->assertEquals('foo', $row['test_string']);
259
    }
260
261 View Code Duplication
    public function testFetchAssocWithTypes()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
262
    {
263
        $datetimeString = '2010-01-01 10:10:10';
264
        $datetime = new \DateTime($datetimeString);
265
        $sql = "SELECT test_int, test_datetime FROM fetch_table WHERE test_int = ? AND test_datetime = ?";
266
        $row = $this->_conn->fetchAssoc($sql, array(1, $datetime), array(PDO::PARAM_STR, Type::DATETIME));
267
268
        $this->assertTrue($row !== false);
269
270
        $row = array_change_key_case($row, \CASE_LOWER);
271
272
        $this->assertEquals(1, $row['test_int']);
273
        $this->assertStringStartsWith($datetimeString, $row['test_datetime']);
274
    }
275
276
    /**
277
     * @expectedException \Doctrine\DBAL\DBALException
278
     */
279 View Code Duplication
    public function testFetchAssocWithMissingTypes()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
280
    {
281
        if ($this->_conn->getDriver() instanceof \Doctrine\DBAL\Driver\Mysqli\Driver ||
282
            $this->_conn->getDriver() instanceof \Doctrine\DBAL\Driver\SQLSrv\Driver) {
283
            $this->markTestSkipped('mysqli and sqlsrv actually supports this');
284
        }
285
286
        $datetimeString = '2010-01-01 10:10:10';
287
        $datetime = new \DateTime($datetimeString);
288
        $sql = "SELECT test_int, test_datetime FROM fetch_table WHERE test_int = ? AND test_datetime = ?";
289
        $row = $this->_conn->fetchAssoc($sql, array(1, $datetime));
0 ignored issues
show
Unused Code introduced by
$row is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
290
    }
291
292
    public function testFetchArray()
293
    {
294
        $sql = "SELECT test_int, test_string FROM fetch_table WHERE test_int = ? AND test_string = ?";
295
        $row = $this->_conn->fetchArray($sql, array(1, 'foo'));
296
297
        $this->assertEquals(1, $row[0]);
298
        $this->assertEquals('foo', $row[1]);
299
    }
300
301 View Code Duplication
    public function testFetchArrayWithTypes()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
302
    {
303
        $datetimeString = '2010-01-01 10:10:10';
304
        $datetime = new \DateTime($datetimeString);
305
        $sql = "SELECT test_int, test_datetime FROM fetch_table WHERE test_int = ? AND test_datetime = ?";
306
        $row = $this->_conn->fetchArray($sql, array(1, $datetime), array(PDO::PARAM_STR, Type::DATETIME));
307
308
        $this->assertTrue($row !== false);
309
310
        $row = array_change_key_case($row, \CASE_LOWER);
311
312
        $this->assertEquals(1, $row[0]);
313
        $this->assertStringStartsWith($datetimeString, $row[1]);
314
    }
315
316
    /**
317
     * @expectedException \Doctrine\DBAL\DBALException
318
     */
319 View Code Duplication
    public function testFetchArrayWithMissingTypes()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
320
    {
321
        if ($this->_conn->getDriver() instanceof \Doctrine\DBAL\Driver\Mysqli\Driver ||
322
            $this->_conn->getDriver() instanceof \Doctrine\DBAL\Driver\SQLSrv\Driver) {
323
            $this->markTestSkipped('mysqli and sqlsrv actually supports this');
324
        }
325
326
        $datetimeString = '2010-01-01 10:10:10';
327
        $datetime = new \DateTime($datetimeString);
328
        $sql = "SELECT test_int, test_datetime FROM fetch_table WHERE test_int = ? AND test_datetime = ?";
329
        $row = $this->_conn->fetchArray($sql, array(1, $datetime));
0 ignored issues
show
Unused Code introduced by
$row is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
330
    }
331
332
    public function testFetchColumn()
333
    {
334
        $sql = "SELECT test_int, test_string FROM fetch_table WHERE test_int = ? AND test_string = ?";
335
        $testInt = $this->_conn->fetchColumn($sql, array(1, 'foo'), 0);
336
337
        $this->assertEquals(1, $testInt);
338
339
        $sql = "SELECT test_int, test_string FROM fetch_table WHERE test_int = ? AND test_string = ?";
340
        $testString = $this->_conn->fetchColumn($sql, array(1, 'foo'), 1);
341
342
        $this->assertEquals('foo', $testString);
343
    }
344
345
    public function testFetchColumnWithTypes()
346
    {
347
        $datetimeString = '2010-01-01 10:10:10';
348
        $datetime = new \DateTime($datetimeString);
349
        $sql = "SELECT test_int, test_datetime FROM fetch_table WHERE test_int = ? AND test_datetime = ?";
350
        $column = $this->_conn->fetchColumn($sql, array(1, $datetime), 1, array(PDO::PARAM_STR, Type::DATETIME));
351
352
        $this->assertTrue($column !== false);
353
354
        $this->assertStringStartsWith($datetimeString, $column);
355
    }
356
357
    /**
358
     * @expectedException \Doctrine\DBAL\DBALException
359
     */
360 View Code Duplication
    public function testFetchColumnWithMissingTypes()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
361
    {
362
        if ($this->_conn->getDriver() instanceof \Doctrine\DBAL\Driver\Mysqli\Driver ||
363
            $this->_conn->getDriver() instanceof \Doctrine\DBAL\Driver\SQLSrv\Driver) {
364
            $this->markTestSkipped('mysqli and sqlsrv actually supports this');
365
        }
366
367
        $datetimeString = '2010-01-01 10:10:10';
368
        $datetime = new \DateTime($datetimeString);
369
        $sql = "SELECT test_int, test_datetime FROM fetch_table WHERE test_int = ? AND test_datetime = ?";
370
        $column = $this->_conn->fetchColumn($sql, array(1, $datetime), 1);
0 ignored issues
show
Unused Code introduced by
$column is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
371
    }
372
373
    /**
374
     * @group DDC-697
375
     */
376
    public function testExecuteQueryBindDateTimeType()
377
    {
378
        $sql = 'SELECT count(*) AS c FROM fetch_table WHERE test_datetime = ?';
379
        $stmt = $this->_conn->executeQuery($sql,
380
            array(1 => new \DateTime('2010-01-01 10:10:10')),
381
            array(1 => Type::DATETIME)
382
        );
383
384
        $this->assertEquals(1, $stmt->fetchColumn());
385
    }
386
387
    /**
388
     * @group DDC-697
389
     */
390
    public function testExecuteUpdateBindDateTimeType()
391
    {
392
        $datetime = new \DateTime('2010-02-02 20:20:20');
393
394
        $sql = 'INSERT INTO fetch_table (test_int, test_string, test_datetime) VALUES (?, ?, ?)';
395
        $affectedRows = $this->_conn->executeUpdate($sql,
396
            array(1 => 50,              2 => 'foo',             3 => $datetime),
397
            array(1 => PDO::PARAM_INT,  2 => PDO::PARAM_STR,    3 => Type::DATETIME)
398
        );
399
400
        $this->assertEquals(1, $affectedRows);
401
        $this->assertEquals(1, $this->_conn->executeQuery(
402
            'SELECT count(*) AS c FROM fetch_table WHERE test_datetime = ?',
403
            array(1 => $datetime),
404
            array(1 => Type::DATETIME)
405
        )->fetchColumn());
406
    }
407
408
    /**
409
     * @group DDC-697
410
     */
411
    public function testPrepareQueryBindValueDateTimeType()
412
    {
413
        $sql = 'SELECT count(*) AS c FROM fetch_table WHERE test_datetime = ?';
414
        $stmt = $this->_conn->prepare($sql);
415
        $stmt->bindValue(1, new \DateTime('2010-01-01 10:10:10'), Type::DATETIME);
416
        $stmt->execute();
417
418
        $this->assertEquals(1, $stmt->fetchColumn());
419
    }
420
421
    /**
422
     * @group DBAL-78
423
     */
424
    public function testNativeArrayListSupport()
425
    {
426
        for ($i = 100; $i < 110; $i++) {
427
            $this->_conn->insert('fetch_table', array('test_int' => $i, 'test_string' => 'foo' . $i, 'test_datetime' => '2010-01-01 10:10:10'));
428
        }
429
430
        $stmt = $this->_conn->executeQuery('SELECT test_int FROM fetch_table WHERE test_int IN (?)',
431
            array(array(100, 101, 102, 103, 104)), array(Connection::PARAM_INT_ARRAY));
432
433
        $data = $stmt->fetchAll(PDO::FETCH_NUM);
434
        $this->assertEquals(5, count($data));
435
        $this->assertEquals(array(array(100), array(101), array(102), array(103), array(104)), $data);
436
437
        $stmt = $this->_conn->executeQuery('SELECT test_int FROM fetch_table WHERE test_string IN (?)',
438
            array(array('foo100', 'foo101', 'foo102', 'foo103', 'foo104')), array(Connection::PARAM_STR_ARRAY));
439
440
        $data = $stmt->fetchAll(PDO::FETCH_NUM);
441
        $this->assertEquals(5, count($data));
442
        $this->assertEquals(array(array(100), array(101), array(102), array(103), array(104)), $data);
443
    }
444
445
    /**
446
     * @dataProvider getTrimExpressionData
447
     */
448
    public function testTrimExpression($value, $position, $char, $expectedResult)
449
    {
450
        $sql = 'SELECT ' .
451
            $this->_conn->getDatabasePlatform()->getTrimExpression($value, $position, $char) . ' AS trimmed ' .
452
            'FROM fetch_table';
453
454
        $row = $this->_conn->fetchAssoc($sql);
455
        $row = array_change_key_case($row, CASE_LOWER);
456
457
        $this->assertEquals($expectedResult, $row['trimmed']);
458
    }
459
460
    public function getTrimExpressionData()
461
    {
462
        return array(
463
            array('test_string', AbstractPlatform::TRIM_UNSPECIFIED, false, 'foo'),
464
            array('test_string', AbstractPlatform::TRIM_LEADING, false, 'foo'),
465
            array('test_string', AbstractPlatform::TRIM_TRAILING, false, 'foo'),
466
            array('test_string', AbstractPlatform::TRIM_BOTH, false, 'foo'),
467
            array('test_string', AbstractPlatform::TRIM_UNSPECIFIED, "'f'", 'oo'),
468
            array('test_string', AbstractPlatform::TRIM_UNSPECIFIED, "'o'", 'f'),
469
            array('test_string', AbstractPlatform::TRIM_UNSPECIFIED, "'.'", 'foo'),
470
            array('test_string', AbstractPlatform::TRIM_LEADING, "'f'", 'oo'),
471
            array('test_string', AbstractPlatform::TRIM_LEADING, "'o'", 'foo'),
472
            array('test_string', AbstractPlatform::TRIM_LEADING, "'.'", 'foo'),
473
            array('test_string', AbstractPlatform::TRIM_TRAILING, "'f'", 'foo'),
474
            array('test_string', AbstractPlatform::TRIM_TRAILING, "'o'", 'f'),
475
            array('test_string', AbstractPlatform::TRIM_TRAILING, "'.'", 'foo'),
476
            array('test_string', AbstractPlatform::TRIM_BOTH, "'f'", 'oo'),
477
            array('test_string', AbstractPlatform::TRIM_BOTH, "'o'", 'f'),
478
            array('test_string', AbstractPlatform::TRIM_BOTH, "'.'", 'foo'),
479
            array("' foo '", AbstractPlatform::TRIM_UNSPECIFIED, false, 'foo'),
480
            array("' foo '", AbstractPlatform::TRIM_LEADING, false, 'foo '),
481
            array("' foo '", AbstractPlatform::TRIM_TRAILING, false, ' foo'),
482
            array("' foo '", AbstractPlatform::TRIM_BOTH, false, 'foo'),
483
            array("' foo '", AbstractPlatform::TRIM_UNSPECIFIED, "'f'", ' foo '),
484
            array("' foo '", AbstractPlatform::TRIM_UNSPECIFIED, "'o'", ' foo '),
485
            array("' foo '", AbstractPlatform::TRIM_UNSPECIFIED, "'.'", ' foo '),
486
            array("' foo '", AbstractPlatform::TRIM_UNSPECIFIED, "' '", 'foo'),
487
            array("' foo '", AbstractPlatform::TRIM_LEADING, "'f'", ' foo '),
488
            array("' foo '", AbstractPlatform::TRIM_LEADING, "'o'", ' foo '),
489
            array("' foo '", AbstractPlatform::TRIM_LEADING, "'.'", ' foo '),
490
            array("' foo '", AbstractPlatform::TRIM_LEADING, "' '", 'foo '),
491
            array("' foo '", AbstractPlatform::TRIM_TRAILING, "'f'", ' foo '),
492
            array("' foo '", AbstractPlatform::TRIM_TRAILING, "'o'", ' foo '),
493
            array("' foo '", AbstractPlatform::TRIM_TRAILING, "'.'", ' foo '),
494
            array("' foo '", AbstractPlatform::TRIM_TRAILING, "' '", ' foo'),
495
            array("' foo '", AbstractPlatform::TRIM_BOTH, "'f'", ' foo '),
496
            array("' foo '", AbstractPlatform::TRIM_BOTH, "'o'", ' foo '),
497
            array("' foo '", AbstractPlatform::TRIM_BOTH, "'.'", ' foo '),
498
            array("' foo '", AbstractPlatform::TRIM_BOTH, "' '", 'foo'),
499
        );
500
    }
501
502
    /**
503
     * @group DDC-1014
504
     */
505
    public function testDateArithmetics()
506
    {
507
        $p = $this->_conn->getDatabasePlatform();
508
        $sql = 'SELECT ';
509
        $sql .= $p->getDateDiffExpression('test_datetime', $p->getCurrentTimestampSQL()) .' AS diff, ';
510
        $sql .= $p->getDateAddSecondsExpression('test_datetime', 1) .' AS add_seconds, ';
511
        $sql .= $p->getDateSubSecondsExpression('test_datetime', 1) .' AS sub_seconds, ';
512
        $sql .= $p->getDateAddMinutesExpression('test_datetime', 5) .' AS add_minutes, ';
513
        $sql .= $p->getDateSubMinutesExpression('test_datetime', 5) .' AS sub_minutes, ';
514
        $sql .= $p->getDateAddHourExpression('test_datetime', 3) .' AS add_hour, ';
515
        $sql .= $p->getDateSubHourExpression('test_datetime', 3) .' AS sub_hour, ';
516
        $sql .= $p->getDateAddDaysExpression('test_datetime', 10) .' AS add_days, ';
517
        $sql .= $p->getDateSubDaysExpression('test_datetime', 10) .' AS sub_days, ';
518
        $sql .= $p->getDateAddWeeksExpression('test_datetime', 1) .' AS add_weeks, ';
519
        $sql .= $p->getDateSubWeeksExpression('test_datetime', 1) .' AS sub_weeks, ';
520
        $sql .= $p->getDateAddMonthExpression('test_datetime', 2) .' AS add_month, ';
521
        $sql .= $p->getDateSubMonthExpression('test_datetime', 2) .' AS sub_month, ';
522
        $sql .= $p->getDateAddQuartersExpression('test_datetime', 3) .' AS add_quarters, ';
523
        $sql .= $p->getDateSubQuartersExpression('test_datetime', 3) .' AS sub_quarters, ';
524
        $sql .= $p->getDateAddYearsExpression('test_datetime', 6) .' AS add_years, ';
525
        $sql .= $p->getDateSubYearsExpression('test_datetime', 6) .' AS sub_years ';
526
        $sql .= 'FROM fetch_table';
527
528
        $row = $this->_conn->fetchAssoc($sql);
529
        $row = array_change_key_case($row, CASE_LOWER);
530
531
        $diff = (strtotime('2010-01-01') - strtotime(date('Y-m-d'))) / 3600 / 24;
532
        $this->assertEquals($diff, $row['diff'], "Date difference should be approx. ".$diff." days.", 1);
533
        $this->assertEquals('2010-01-01 10:10:11', date('Y-m-d H:i:s', strtotime($row['add_seconds'])), "Adding second should end up on 2010-01-01 10:10:11");
534
        $this->assertEquals('2010-01-01 10:10:09', date('Y-m-d H:i:s', strtotime($row['sub_seconds'])), "Subtracting second should end up on 2010-01-01 10:10:09");
535
        $this->assertEquals('2010-01-01 10:15:10', date('Y-m-d H:i:s', strtotime($row['add_minutes'])), "Adding minutes should end up on 2010-01-01 10:15:10");
536
        $this->assertEquals('2010-01-01 10:05:10', date('Y-m-d H:i:s', strtotime($row['sub_minutes'])), "Subtracting minutes should end up on 2010-01-01 10:05:10");
537
        $this->assertEquals('2010-01-01 13:10', date('Y-m-d H:i', strtotime($row['add_hour'])), "Adding date should end up on 2010-01-01 13:10");
538
        $this->assertEquals('2010-01-01 07:10', date('Y-m-d H:i', strtotime($row['sub_hour'])), "Subtracting date should end up on 2010-01-01 07:10");
539
        $this->assertEquals('2010-01-11', date('Y-m-d', strtotime($row['add_days'])), "Adding date should end up on 2010-01-11");
540
        $this->assertEquals('2009-12-22', date('Y-m-d', strtotime($row['sub_days'])), "Subtracting date should end up on 2009-12-22");
541
        $this->assertEquals('2010-01-08', date('Y-m-d', strtotime($row['add_weeks'])), "Adding week should end up on 2010-01-08");
542
        $this->assertEquals('2009-12-25', date('Y-m-d', strtotime($row['sub_weeks'])), "Subtracting week should end up on 2009-12-25");
543
        $this->assertEquals('2010-03-01', date('Y-m-d', strtotime($row['add_month'])), "Adding month should end up on 2010-03-01");
544
        $this->assertEquals('2009-11-01', date('Y-m-d', strtotime($row['sub_month'])), "Subtracting month should end up on 2009-11-01");
545
        $this->assertEquals('2010-10-01', date('Y-m-d', strtotime($row['add_quarters'])), "Adding quarters should end up on 2010-04-01");
546
        $this->assertEquals('2009-04-01', date('Y-m-d', strtotime($row['sub_quarters'])), "Subtracting quarters should end up on 2009-10-01");
547
        $this->assertEquals('2016-01-01', date('Y-m-d', strtotime($row['add_years'])), "Adding years should end up on 2016-01-01");
548
        $this->assertEquals('2004-01-01', date('Y-m-d', strtotime($row['sub_years'])), "Subtracting years should end up on 2004-01-01");
549
    }
550
551
    public function testLocateExpression()
552
    {
553
        $platform = $this->_conn->getDatabasePlatform();
554
555
        $sql = 'SELECT ';
556
        $sql .= $platform->getLocateExpression('test_string', "'oo'") .' AS locate1, ';
557
        $sql .= $platform->getLocateExpression('test_string', "'foo'") .' AS locate2, ';
558
        $sql .= $platform->getLocateExpression('test_string', "'bar'") .' AS locate3, ';
559
        $sql .= $platform->getLocateExpression('test_string', 'test_string') .' AS locate4, ';
560
        $sql .= $platform->getLocateExpression("'foo'", 'test_string') .' AS locate5, ';
561
        $sql .= $platform->getLocateExpression("'barfoobaz'", 'test_string') .' AS locate6, ';
562
        $sql .= $platform->getLocateExpression("'bar'", 'test_string') .' AS locate7, ';
563
        $sql .= $platform->getLocateExpression('test_string', "'oo'", 2) .' AS locate8, ';
564
        $sql .= $platform->getLocateExpression('test_string', "'oo'", 3) .' AS locate9 ';
565
        $sql .= 'FROM fetch_table';
566
567
        $row = $this->_conn->fetchAssoc($sql);
568
        $row = array_change_key_case($row, CASE_LOWER);
569
570
        $this->assertEquals(2, $row['locate1']);
571
        $this->assertEquals(1, $row['locate2']);
572
        $this->assertEquals(0, $row['locate3']);
573
        $this->assertEquals(1, $row['locate4']);
574
        $this->assertEquals(1, $row['locate5']);
575
        $this->assertEquals(4, $row['locate6']);
576
        $this->assertEquals(0, $row['locate7']);
577
        $this->assertEquals(2, $row['locate8']);
578
        $this->assertEquals(0, $row['locate9']);
579
    }
580
581 View Code Duplication
    public function testQuoteSQLInjection()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
582
    {
583
        $sql = "SELECT * FROM fetch_table WHERE test_string = " . $this->_conn->quote("bar' OR '1'='1");
584
        $rows = $this->_conn->fetchAll($sql);
585
586
        $this->assertEquals(0, count($rows), "no result should be returned, otherwise SQL injection is possible");
587
    }
588
589
    /**
590
     * @group DDC-1213
591
     */
592
    public function testBitComparisonExpressionSupport()
593
    {
594
        $this->_conn->exec('DELETE FROM fetch_table');
595
        $platform = $this->_conn->getDatabasePlatform();
596
        $bitmap   = array();
597
598
        for ($i = 2; $i < 9; $i = $i + 2) {
599
            $bitmap[$i] = array(
600
                'bit_or'    => ($i | 2),
601
                'bit_and'   => ($i & 2)
602
            );
603
            $this->_conn->insert('fetch_table', array(
604
                'test_int'      => $i,
605
                'test_string'   => json_encode($bitmap[$i]),
606
                'test_datetime' => '2010-01-01 10:10:10'
607
            ));
608
        }
609
610
        $sql[]  = 'SELECT ';
0 ignored issues
show
Coding Style Comprehensibility introduced by
$sql was never initialized. Although not strictly required by PHP, it is generally a good practice to add $sql = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
611
        $sql[]  = 'test_int, ';
612
        $sql[]  = 'test_string, ';
613
        $sql[]  = $platform->getBitOrComparisonExpression('test_int', 2) . ' AS bit_or, ';
614
        $sql[]  = $platform->getBitAndComparisonExpression('test_int', 2) . ' AS bit_and ';
615
        $sql[]  = 'FROM fetch_table';
616
617
        $stmt   = $this->_conn->executeQuery(implode(PHP_EOL, $sql));
618
        $data   = $stmt->fetchAll(PDO::FETCH_ASSOC);
619
620
621
        $this->assertEquals(4, count($data));
622
        $this->assertEquals(count($bitmap), count($data));
623
        foreach ($data as $row) {
624
            $row = array_change_key_case($row, CASE_LOWER);
625
626
            $this->assertArrayHasKey('test_int', $row);
627
628
            $id = $row['test_int'];
629
630
            $this->assertArrayHasKey($id, $bitmap);
631
            $this->assertArrayHasKey($id, $bitmap);
632
633
            $this->assertArrayHasKey('bit_or', $row);
634
            $this->assertArrayHasKey('bit_and', $row);
635
636
            $this->assertEquals($row['bit_or'], $bitmap[$id]['bit_or']);
637
            $this->assertEquals($row['bit_and'], $bitmap[$id]['bit_and']);
638
        }
639
    }
640
641
    public function testSetDefaultFetchMode()
642
    {
643
        $stmt = $this->_conn->query("SELECT * FROM fetch_table");
644
        $stmt->setFetchMode(\PDO::FETCH_NUM);
645
646
        $row = array_keys($stmt->fetch());
647
        $this->assertEquals(0, count( array_filter($row, function($v) { return ! is_numeric($v); })), "should be no non-numerical elements in the result.");
648
    }
649
650
    /**
651
     * @group DBAL-1091
652
     */
653
    public function testFetchAllStyleObject()
654
    {
655
        $this->setupFixture();
656
657
        $sql = 'SELECT test_int, test_string, test_datetime FROM fetch_table';
658
        $stmt = $this->_conn->prepare($sql);
659
660
        $stmt->execute();
661
662
        $results = $stmt->fetchAll(\PDO::FETCH_OBJ);
663
664
        $this->assertCount(1, $results);
665
        $this->assertInstanceOf('stdClass', $results[0]);
666
667
        $this->assertEquals(
668
            1,
669
            property_exists($results[0], 'test_int') ? $results[0]->test_int : $results[0]->TEST_INT
670
        );
671
        $this->assertEquals(
672
            'foo',
673
            property_exists($results[0], 'test_string') ? $results[0]->test_string : $results[0]->TEST_STRING
674
        );
675
        $this->assertStringStartsWith(
676
            '2010-01-01 10:10:10',
677
            property_exists($results[0], 'test_datetime') ? $results[0]->test_datetime : $results[0]->TEST_DATETIME
678
        );
679
    }
680
681
    /**
682
     * @group DBAL-196
683
     */
684 View Code Duplication
    public function testFetchAllSupportFetchClass()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
685
    {
686
        $this->skipOci8AndMysqli();
687
        $this->setupFixture();
688
689
        $sql    = "SELECT test_int, test_string, test_datetime FROM fetch_table";
690
        $stmt   = $this->_conn->prepare($sql);
691
        $stmt->execute();
692
693
        $results = $stmt->fetchAll(
694
            \PDO::FETCH_CLASS,
695
            __NAMESPACE__.'\\MyFetchClass'
696
        );
697
698
        $this->assertEquals(1, count($results));
699
        $this->assertInstanceOf(__NAMESPACE__.'\\MyFetchClass', $results[0]);
700
701
        $this->assertEquals(1, $results[0]->test_int);
702
        $this->assertEquals('foo', $results[0]->test_string);
703
        $this->assertStringStartsWith('2010-01-01 10:10:10', $results[0]->test_datetime);
704
    }
705
706
    /**
707
     * @group DBAL-241
708
     */
709
    public function testFetchAllStyleColumn()
710
    {
711
        $sql = "DELETE FROM fetch_table";
712
        $this->_conn->executeUpdate($sql);
713
714
        $this->_conn->insert('fetch_table', array('test_int' => 1, 'test_string' => 'foo'));
715
        $this->_conn->insert('fetch_table', array('test_int' => 10, 'test_string' => 'foo'));
716
717
        $sql = "SELECT test_int FROM fetch_table";
718
        $rows = $this->_conn->query($sql)->fetchAll(\PDO::FETCH_COLUMN);
719
720
        $this->assertEquals(array(1, 10), $rows);
721
    }
722
723
    /**
724
     * @group DBAL-214
725
     */
726 View Code Duplication
    public function testSetFetchModeClassFetchAll()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
727
    {
728
        $this->skipOci8AndMysqli();
729
        $this->setupFixture();
730
731
        $sql = "SELECT * FROM fetch_table";
732
        $stmt = $this->_conn->query($sql);
733
        $stmt->setFetchMode(\PDO::FETCH_CLASS, __NAMESPACE__ . '\\MyFetchClass');
734
735
        $results = $stmt->fetchAll();
736
737
        $this->assertEquals(1, count($results));
738
        $this->assertInstanceOf(__NAMESPACE__.'\\MyFetchClass', $results[0]);
739
740
        $this->assertEquals(1, $results[0]->test_int);
741
        $this->assertEquals('foo', $results[0]->test_string);
742
        $this->assertStringStartsWith('2010-01-01 10:10:10', $results[0]->test_datetime);
743
    }
744
745
    /**
746
     * @group DBAL-214
747
     */
748
    public function testSetFetchModeClassFetch()
749
    {
750
        $this->skipOci8AndMysqli();
751
        $this->setupFixture();
752
753
        $sql = "SELECT * FROM fetch_table";
754
        $stmt = $this->_conn->query($sql);
755
        $stmt->setFetchMode(\PDO::FETCH_CLASS, __NAMESPACE__ . '\\MyFetchClass');
756
757
        $results = array();
758
        while ($row = $stmt->fetch()) {
759
            $results[] = $row;
760
        }
761
762
        $this->assertEquals(1, count($results));
763
        $this->assertInstanceOf(__NAMESPACE__.'\\MyFetchClass', $results[0]);
764
765
        $this->assertEquals(1, $results[0]->test_int);
766
        $this->assertEquals('foo', $results[0]->test_string);
767
        $this->assertStringStartsWith('2010-01-01 10:10:10', $results[0]->test_datetime);
768
    }
769
770
    /**
771
     * @group DBAL-257
772
     */
773
    public function testEmptyFetchColumnReturnsFalse()
774
    {
775
        $this->_conn->exec('DELETE FROM fetch_table');
776
        $this->assertFalse($this->_conn->fetchColumn('SELECT test_int FROM fetch_table'));
777
        $this->assertFalse($this->_conn->query('SELECT test_int FROM fetch_table')->fetchColumn());
778
    }
779
780
    /**
781
     * @group DBAL-339
782
     */
783
    public function testSetFetchModeOnDbalStatement()
784
    {
785
        $sql = "SELECT test_int, test_string FROM fetch_table WHERE test_int = ? AND test_string = ?";
786
        $stmt = $this->_conn->executeQuery($sql, array(1, "foo"));
787
        $stmt->setFetchMode(\PDO::FETCH_NUM);
788
789
        while ($row = $stmt->fetch()) {
790
            $this->assertTrue(isset($row[0]));
791
            $this->assertTrue(isset($row[1]));
792
        }
793
    }
794
795
    /**
796
     * @group DBAL-435
797
     */
798
    public function testEmptyParameters()
799
    {
800
        $sql = "SELECT * FROM fetch_table WHERE test_int IN (?)";
801
        $stmt = $this->_conn->executeQuery($sql, array(array()), array(\Doctrine\DBAL\Connection::PARAM_INT_ARRAY));
802
        $rows = $stmt->fetchAll();
803
804
        $this->assertEquals(array(), $rows);
805
    }
806
807
    /**
808
     * @group DBAL-1028
809
     */
810
    public function testFetchColumnNullValue()
811
    {
812
        $this->_conn->executeUpdate(
813
            'INSERT INTO fetch_table (test_int, test_string) VALUES (?, ?)',
814
            array(1, 'foo')
815
        );
816
817
        $this->assertNull(
818
            $this->_conn->fetchColumn('SELECT test_datetime FROM fetch_table WHERE test_int = ?', array(1))
819
        );
820
    }
821
822
    /**
823
     * @group DBAL-1028
824
     */
825
    public function testFetchColumnNonExistingIndex()
826
    {
827
        if ($this->_conn->getDriver()->getName() === 'pdo_sqlsrv') {
828
            $this->markTestSkipped(
829
                'Test does not work for pdo_sqlsrv driver as it throws a fatal error for a non-existing column index.'
830
            );
831
        }
832
833
        $this->assertNull(
834
            $this->_conn->fetchColumn('SELECT test_int FROM fetch_table WHERE test_int = ?', array(1), 1)
835
        );
836
    }
837
838
    /**
839
     * @group DBAL-1028
840
     */
841
    public function testFetchColumnNoResult()
842
    {
843
        $this->assertFalse(
844
            $this->_conn->fetchColumn('SELECT test_int FROM fetch_table WHERE test_int = ?', array(-1))
845
        );
846
    }
847
848
    private function setupFixture()
849
    {
850
        $this->_conn->exec('DELETE FROM fetch_table');
851
        $this->_conn->insert('fetch_table', array(
852
            'test_int'      => 1,
853
            'test_string'   => 'foo',
854
            'test_datetime' => '2010-01-01 10:10:10'
855
        ));
856
    }
857
858
    private function skipOci8AndMysqli()
0 ignored issues
show
Coding Style introduced by
skipOci8AndMysqli uses the super-global variable $GLOBALS which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
859
    {
860
        if (isset($GLOBALS['db_type']) && $GLOBALS['db_type'] == "oci8")  {
861
            $this->markTestSkipped("Not supported by OCI8");
862
        }
863
        if ('mysqli' == $this->_conn->getDriver()->getName()) {
864
            $this->markTestSkipped('Mysqli driver dont support this feature.');
865
        }
866
    }
867
868
    public function testIteratorCallsFetchTheExpectedNumberOfTimes()
869
    {
870
        $sql = 'SELECT test_int, test_string FROM fetch_table';
871
        $originalStmt = $this->_conn->prepare($sql);
872
873
        // Mock the connection
874
        $connectionMock = $this->getMockBuilder('Doctrine\\DBAL\\Driver\\Connection')
875
            ->setMethods(['prepare', 'query'])
876
            ->getMockForAbstractClass();
877
878
        $stmtSpy = new StatementSpy($originalStmt);
879
880
        // Return our mocked statement from the query
881
        $connectionMock->expects($this->any())
882
            ->method('prepare')
883
            ->will($this->returnValue($stmtSpy));
884
885
        $connectionMock->expects($this->any())
886
            ->method('query')
887
            ->will($this->returnCallback(function () use ($stmtSpy) {
888
                $stmtSpy->execute();
889
                return $stmtSpy;
890
            }));
891
892
        $stmt = $connectionMock->query($sql);
893
        $stmt->setFetchMode(\PDO::FETCH_ASSOC);
894
895
        // Assert no fetch calls thus far
896
        self::assertEquals(0, $stmtSpy->getFetchCalls());
897
898
        $i = 0;
899
        foreach ($stmt as $row) {
900
            $i++;
901
        }
902
903
        // Assert expected number of fetches
904
        $this->assertGreaterThan(0, $stmtSpy->getFetchCalls());
905
        $this->assertEquals($i, $stmtSpy->getFetchCalls());
906
    }
907
}
908
909
class StatementSpy implements \IteratorAggregate
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class should be in its own file to aid autoloaders.

Having each class in a dedicated file usually plays nice with PSR autoloaders and is therefore a well established practice. If you use other autoloaders, you might not want to follow this rule.

Loading history...
910
{
911
    /**
912
     * @var Statement|\Doctrine\DBAL\Statement
913
     */
914
    private $stmt;
915
916
    private $fetchCalls = 0;
917
918
    public function __construct(Statement $stmt)
919
    {
920
        $this->stmt = $stmt;
921
    }
922
923
    public function setFetchMode($fetchMode, $arg2 = null, $arg3 = null)
924
    {
925
        return $this->stmt->setFetchMode($fetchMode, $arg2, $arg3);
926
    }
927
928
    public function execute($params = null)
929
    {
930
        return $this->stmt->execute($params);
931
    }
932
933
    public function getIterator()
934
    {
935
        foreach ($this->stmt as $item) {
936
            $this->fetchCalls++;
937
            yield $item;
938
        }
939
    }
940
941
    public function getFetchCalls()
942
    {
943
        return $this->fetchCalls;
944
    }
945
}
946
947
class MyFetchClass
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class should be in its own file to aid autoloaders.

Having each class in a dedicated file usually plays nice with PSR autoloaders and is therefore a well established practice. If you use other autoloaders, you might not want to follow this rule.

Loading history...
948
{
949
    public $test_int, $test_string, $test_datetime;
0 ignored issues
show
Coding Style introduced by
It is generally advisable to only define one property per statement.

Only declaring a single property per statement allows you to later on add doc comments more easily.

It is also recommended by PSR2, so it is a common style that many people expect.

Loading history...
950
}
951