Failed Conditions
Pull Request — master (#2718)
by Ian
05:36
created

testIteratorCanBeIteratedMultipleTimes()   B

Complexity

Conditions 3
Paths 4

Size

Total Lines 42
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
dl 0
loc 42
rs 8.8571
c 1
b 0
f 0
cc 3
eloc 20
nc 4
nop 0
1
<?php
2
3
namespace Doctrine\Tests\DBAL\Functional;
4
5
use Doctrine\DBAL\Connection;
6
use Doctrine\DBAL\Platforms\AbstractPlatform;
7
use Doctrine\DBAL\Types\Type;
8
use PDO;
9
10
class DataAccessTest extends \Doctrine\Tests\DbalFunctionalTestCase
11
{
12
    static private $generated = false;
13
14
    protected function setUp()
15
    {
16
        parent::setUp();
17
18
        if (self::$generated === false) {
19
            /* @var $sm \Doctrine\DBAL\Schema\AbstractSchemaManager */
20
            $table = new \Doctrine\DBAL\Schema\Table("fetch_table");
21
            $table->addColumn('test_int', 'integer');
22
            $table->addColumn('test_string', 'string');
23
            $table->addColumn('test_datetime', 'datetime', array('notnull' => false));
24
            $table->setPrimaryKey(array('test_int'));
25
26
            $sm = $this->_conn->getSchemaManager();
27
            $sm->createTable($table);
28
29
            $this->_conn->insert('fetch_table', array('test_int' => 1, 'test_string' => 'foo', 'test_datetime' => '2010-01-01 10:10:10'));
30
            self::$generated = true;
31
        }
32
    }
33
34
    public function testPrepareWithBindValue()
35
    {
36
        $sql = "SELECT test_int, test_string FROM fetch_table WHERE test_int = ? AND test_string = ?";
37
        $stmt = $this->_conn->prepare($sql);
38
        $this->assertInstanceOf('Doctrine\DBAL\Statement', $stmt);
39
40
        $stmt->bindValue(1, 1);
41
        $stmt->bindValue(2, 'foo');
42
        $stmt->execute();
43
44
        $row = $stmt->fetch(\PDO::FETCH_ASSOC);
45
        $row = array_change_key_case($row, \CASE_LOWER);
46
        $this->assertEquals(array('test_int' => 1, 'test_string' => 'foo'), $row);
47
    }
48
49
    public function testPrepareWithBindParam()
50
    {
51
        $paramInt = 1;
52
        $paramStr = 'foo';
53
54
        $sql = "SELECT test_int, test_string FROM fetch_table WHERE test_int = ? AND test_string = ?";
55
        $stmt = $this->_conn->prepare($sql);
56
        $this->assertInstanceOf('Doctrine\DBAL\Statement', $stmt);
57
58
        $stmt->bindParam(1, $paramInt);
59
        $stmt->bindParam(2, $paramStr);
60
        $stmt->execute();
61
62
        $row = $stmt->fetch(\PDO::FETCH_ASSOC);
63
        $row = array_change_key_case($row, \CASE_LOWER);
64
        $this->assertEquals(array('test_int' => 1, 'test_string' => 'foo'), $row);
65
    }
66
67
    public function testPrepareWithFetchAll()
68
    {
69
        $paramInt = 1;
70
        $paramStr = 'foo';
71
72
        $sql = "SELECT test_int, test_string FROM fetch_table WHERE test_int = ? AND test_string = ?";
73
        $stmt = $this->_conn->prepare($sql);
74
        $this->assertInstanceOf('Doctrine\DBAL\Statement', $stmt);
75
76
        $stmt->bindParam(1, $paramInt);
77
        $stmt->bindParam(2, $paramStr);
78
        $stmt->execute();
79
80
        $rows = $stmt->fetchAll(\PDO::FETCH_ASSOC);
81
        $rows[0] = array_change_key_case($rows[0], \CASE_LOWER);
82
        $this->assertEquals(array('test_int' => 1, 'test_string' => 'foo'), $rows[0]);
83
    }
84
85
    /**
86
     * @group DBAL-228
87
     */
88
    public function testPrepareWithFetchAllBoth()
89
    {
90
        $paramInt = 1;
91
        $paramStr = 'foo';
92
93
        $sql = "SELECT test_int, test_string FROM fetch_table WHERE test_int = ? AND test_string = ?";
94
        $stmt = $this->_conn->prepare($sql);
95
        $this->assertInstanceOf('Doctrine\DBAL\Statement', $stmt);
96
97
        $stmt->bindParam(1, $paramInt);
98
        $stmt->bindParam(2, $paramStr);
99
        $stmt->execute();
100
101
        $rows = $stmt->fetchAll(\PDO::FETCH_BOTH);
102
        $rows[0] = array_change_key_case($rows[0], \CASE_LOWER);
103
        $this->assertEquals(array('test_int' => 1, 'test_string' => 'foo', 0 => 1, 1 => 'foo'), $rows[0]);
104
    }
105
106
    public function testPrepareWithFetchColumn()
107
    {
108
        $paramInt = 1;
109
        $paramStr = 'foo';
110
111
        $sql = "SELECT test_int FROM fetch_table WHERE test_int = ? AND test_string = ?";
112
        $stmt = $this->_conn->prepare($sql);
113
        $this->assertInstanceOf('Doctrine\DBAL\Statement', $stmt);
114
115
        $stmt->bindParam(1, $paramInt);
116
        $stmt->bindParam(2, $paramStr);
117
        $stmt->execute();
118
119
        $column = $stmt->fetchColumn();
120
        $this->assertEquals(1, $column);
121
    }
122
123
    public function testPrepareWithIterator()
124
    {
125
        $paramInt = 1;
126
        $paramStr = 'foo';
127
128
        $sql = "SELECT test_int, test_string FROM fetch_table WHERE test_int = ? AND test_string = ?";
129
        $stmt = $this->_conn->prepare($sql);
130
        $this->assertInstanceOf('Doctrine\DBAL\Statement', $stmt);
131
132
        $stmt->bindParam(1, $paramInt);
133
        $stmt->bindParam(2, $paramStr);
134
        $stmt->execute();
135
136
        $rows = array();
137
        $stmt->setFetchMode(\PDO::FETCH_ASSOC);
138
        foreach ($stmt as $row) {
139
            $rows[] = array_change_key_case($row, \CASE_LOWER);
140
        }
141
142
        $this->assertEquals(array('test_int' => 1, 'test_string' => 'foo'), $rows[0]);
143
    }
144
145
    public function testPrepareWithQuoted()
146
    {
147
        $table = 'fetch_table';
148
        $paramInt = 1;
149
        $paramStr = 'foo';
150
151
        $sql = "SELECT test_int, test_string FROM " . $this->_conn->quoteIdentifier($table) . " ".
152
               "WHERE test_int = " . $this->_conn->quote($paramInt) . " AND test_string = " . $this->_conn->quote($paramStr);
153
        $stmt = $this->_conn->prepare($sql);
154
        $this->assertInstanceOf('Doctrine\DBAL\Statement', $stmt);
155
    }
156
157
    public function testPrepareWithExecuteParams()
158
    {
159
        $paramInt = 1;
160
        $paramStr = 'foo';
161
162
        $sql = "SELECT test_int, test_string FROM fetch_table WHERE test_int = ? AND test_string = ?";
163
        $stmt = $this->_conn->prepare($sql);
164
        $this->assertInstanceOf('Doctrine\DBAL\Statement', $stmt);
165
        $stmt->execute(array($paramInt, $paramStr));
166
167
        $row = $stmt->fetch(\PDO::FETCH_ASSOC);
168
        $this->assertTrue($row !== false);
169
        $row = array_change_key_case($row, \CASE_LOWER);
170
        $this->assertEquals(array('test_int' => 1, 'test_string' => 'foo'), $row);
171
    }
172
173
    public function testFetchAll()
174
    {
175
        $sql = "SELECT test_int, test_string FROM fetch_table WHERE test_int = ? AND test_string = ?";
176
        $data = $this->_conn->fetchAll($sql, array(1, 'foo'));
177
178
        $this->assertEquals(1, count($data));
179
180
        $row = $data[0];
181
        $this->assertEquals(2, count($row));
182
183
        $row = array_change_key_case($row, \CASE_LOWER);
184
        $this->assertEquals(1, $row['test_int']);
185
        $this->assertEquals('foo', $row['test_string']);
186
    }
187
188
    /**
189
     * @group DBAL-209
190
     */
191
    public function testFetchAllWithTypes()
192
    {
193
        $datetimeString = '2010-01-01 10:10:10';
194
        $datetime = new \DateTime($datetimeString);
195
        $sql = "SELECT test_int, test_datetime FROM fetch_table WHERE test_int = ? AND test_datetime = ?";
196
        $data = $this->_conn->fetchAll($sql, array(1, $datetime), array(PDO::PARAM_STR, Type::DATETIME));
197
198
        $this->assertEquals(1, count($data));
199
200
        $row = $data[0];
201
        $this->assertEquals(2, count($row));
202
203
        $row = array_change_key_case($row, \CASE_LOWER);
204
        $this->assertEquals(1, $row['test_int']);
205
        $this->assertStringStartsWith($datetimeString, $row['test_datetime']);
206
    }
207
208
    /**
209
     * @group DBAL-209
210
     * @expectedException \Doctrine\DBAL\DBALException
211
     */
212 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...
213
    {
214
        if ($this->_conn->getDriver() instanceof \Doctrine\DBAL\Driver\Mysqli\Driver ||
215
            $this->_conn->getDriver() instanceof \Doctrine\DBAL\Driver\SQLSrv\Driver) {
216
            $this->markTestSkipped('mysqli and sqlsrv actually supports this');
217
        }
218
219
        $datetimeString = '2010-01-01 10:10:10';
220
        $datetime = new \DateTime($datetimeString);
221
        $sql = "SELECT test_int, test_datetime FROM fetch_table WHERE test_int = ? AND test_datetime = ?";
222
        $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...
223
    }
224
225
    public function testFetchBoth()
226
    {
227
        $sql = "SELECT test_int, test_string FROM fetch_table WHERE test_int = ? AND test_string = ?";
228
        $row = $this->_conn->executeQuery($sql, array(1, 'foo'))->fetch(\PDO::FETCH_BOTH);
229
230
        $this->assertTrue($row !== false);
231
232
        $row = array_change_key_case($row, \CASE_LOWER);
233
234
        $this->assertEquals(1, $row['test_int']);
235
        $this->assertEquals('foo', $row['test_string']);
236
        $this->assertEquals(1, $row[0]);
237
        $this->assertEquals('foo', $row[1]);
238
    }
239
240
    public function testFetchNoResult()
241
    {
242
        self::assertFalse(
243
            $this->_conn->executeQuery('SELECT test_int FROM fetch_table WHERE test_int = ?', [-1])->fetch()
244
        );
245
    }
246
247
    public function testFetchAssoc()
248
    {
249
        $sql = "SELECT test_int, test_string FROM fetch_table WHERE test_int = ? AND test_string = ?";
250
        $row = $this->_conn->fetchAssoc($sql, array(1, 'foo'));
251
252
        $this->assertTrue($row !== false);
253
254
        $row = array_change_key_case($row, \CASE_LOWER);
255
256
        $this->assertEquals(1, $row['test_int']);
257
        $this->assertEquals('foo', $row['test_string']);
258
    }
259
260 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...
261
    {
262
        $datetimeString = '2010-01-01 10:10:10';
263
        $datetime = new \DateTime($datetimeString);
264
        $sql = "SELECT test_int, test_datetime FROM fetch_table WHERE test_int = ? AND test_datetime = ?";
265
        $row = $this->_conn->fetchAssoc($sql, array(1, $datetime), array(PDO::PARAM_STR, Type::DATETIME));
266
267
        $this->assertTrue($row !== false);
268
269
        $row = array_change_key_case($row, \CASE_LOWER);
270
271
        $this->assertEquals(1, $row['test_int']);
272
        $this->assertStringStartsWith($datetimeString, $row['test_datetime']);
273
    }
274
275
    /**
276
     * @expectedException \Doctrine\DBAL\DBALException
277
     */
278 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...
279
    {
280
        if ($this->_conn->getDriver() instanceof \Doctrine\DBAL\Driver\Mysqli\Driver ||
281
            $this->_conn->getDriver() instanceof \Doctrine\DBAL\Driver\SQLSrv\Driver) {
282
            $this->markTestSkipped('mysqli and sqlsrv actually supports this');
283
        }
284
285
        $datetimeString = '2010-01-01 10:10:10';
286
        $datetime = new \DateTime($datetimeString);
287
        $sql = "SELECT test_int, test_datetime FROM fetch_table WHERE test_int = ? AND test_datetime = ?";
288
        $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...
289
    }
290
291
    public function testFetchArray()
292
    {
293
        $sql = "SELECT test_int, test_string FROM fetch_table WHERE test_int = ? AND test_string = ?";
294
        $row = $this->_conn->fetchArray($sql, array(1, 'foo'));
295
296
        $this->assertEquals(1, $row[0]);
297
        $this->assertEquals('foo', $row[1]);
298
    }
299
300 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...
301
    {
302
        $datetimeString = '2010-01-01 10:10:10';
303
        $datetime = new \DateTime($datetimeString);
304
        $sql = "SELECT test_int, test_datetime FROM fetch_table WHERE test_int = ? AND test_datetime = ?";
305
        $row = $this->_conn->fetchArray($sql, array(1, $datetime), array(PDO::PARAM_STR, Type::DATETIME));
306
307
        $this->assertTrue($row !== false);
308
309
        $row = array_change_key_case($row, \CASE_LOWER);
310
311
        $this->assertEquals(1, $row[0]);
312
        $this->assertStringStartsWith($datetimeString, $row[1]);
313
    }
314
315
    /**
316
     * @expectedException \Doctrine\DBAL\DBALException
317
     */
318 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...
319
    {
320
        if ($this->_conn->getDriver() instanceof \Doctrine\DBAL\Driver\Mysqli\Driver ||
321
            $this->_conn->getDriver() instanceof \Doctrine\DBAL\Driver\SQLSrv\Driver) {
322
            $this->markTestSkipped('mysqli and sqlsrv actually supports this');
323
        }
324
325
        $datetimeString = '2010-01-01 10:10:10';
326
        $datetime = new \DateTime($datetimeString);
327
        $sql = "SELECT test_int, test_datetime FROM fetch_table WHERE test_int = ? AND test_datetime = ?";
328
        $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...
329
    }
330
331
    public function testFetchColumn()
332
    {
333
        $sql = "SELECT test_int, test_string FROM fetch_table WHERE test_int = ? AND test_string = ?";
334
        $testInt = $this->_conn->fetchColumn($sql, array(1, 'foo'), 0);
335
336
        $this->assertEquals(1, $testInt);
337
338
        $sql = "SELECT test_int, test_string FROM fetch_table WHERE test_int = ? AND test_string = ?";
339
        $testString = $this->_conn->fetchColumn($sql, array(1, 'foo'), 1);
340
341
        $this->assertEquals('foo', $testString);
342
    }
343
344
    public function testFetchColumnWithTypes()
345
    {
346
        $datetimeString = '2010-01-01 10:10:10';
347
        $datetime = new \DateTime($datetimeString);
348
        $sql = "SELECT test_int, test_datetime FROM fetch_table WHERE test_int = ? AND test_datetime = ?";
349
        $column = $this->_conn->fetchColumn($sql, array(1, $datetime), 1, array(PDO::PARAM_STR, Type::DATETIME));
350
351
        $this->assertTrue($column !== false);
352
353
        $this->assertStringStartsWith($datetimeString, $column);
354
    }
355
356
    /**
357
     * @expectedException \Doctrine\DBAL\DBALException
358
     */
359 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...
360
    {
361
        if ($this->_conn->getDriver() instanceof \Doctrine\DBAL\Driver\Mysqli\Driver ||
362
            $this->_conn->getDriver() instanceof \Doctrine\DBAL\Driver\SQLSrv\Driver) {
363
            $this->markTestSkipped('mysqli and sqlsrv actually supports this');
364
        }
365
366
        $datetimeString = '2010-01-01 10:10:10';
367
        $datetime = new \DateTime($datetimeString);
368
        $sql = "SELECT test_int, test_datetime FROM fetch_table WHERE test_int = ? AND test_datetime = ?";
369
        $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...
370
    }
371
372
    /**
373
     * @group DDC-697
374
     */
375
    public function testExecuteQueryBindDateTimeType()
376
    {
377
        $sql = 'SELECT count(*) AS c FROM fetch_table WHERE test_datetime = ?';
378
        $stmt = $this->_conn->executeQuery($sql,
379
            array(1 => new \DateTime('2010-01-01 10:10:10')),
380
            array(1 => Type::DATETIME)
381
        );
382
383
        $this->assertEquals(1, $stmt->fetchColumn());
384
    }
385
386
    /**
387
     * @group DDC-697
388
     */
389
    public function testExecuteUpdateBindDateTimeType()
390
    {
391
        $datetime = new \DateTime('2010-02-02 20:20:20');
392
393
        $sql = 'INSERT INTO fetch_table (test_int, test_string, test_datetime) VALUES (?, ?, ?)';
394
        $affectedRows = $this->_conn->executeUpdate($sql,
395
            array(1 => 50,              2 => 'foo',             3 => $datetime),
396
            array(1 => PDO::PARAM_INT,  2 => PDO::PARAM_STR,    3 => Type::DATETIME)
397
        );
398
399
        $this->assertEquals(1, $affectedRows);
400
        $this->assertEquals(1, $this->_conn->executeQuery(
401
            'SELECT count(*) AS c FROM fetch_table WHERE test_datetime = ?',
402
            array(1 => $datetime),
403
            array(1 => Type::DATETIME)
404
        )->fetchColumn());
405
    }
406
407
    /**
408
     * @group DDC-697
409
     */
410
    public function testPrepareQueryBindValueDateTimeType()
411
    {
412
        $sql = 'SELECT count(*) AS c FROM fetch_table WHERE test_datetime = ?';
413
        $stmt = $this->_conn->prepare($sql);
414
        $stmt->bindValue(1, new \DateTime('2010-01-01 10:10:10'), Type::DATETIME);
415
        $stmt->execute();
416
417
        $this->assertEquals(1, $stmt->fetchColumn());
418
    }
419
420
    /**
421
     * @group DBAL-78
422
     */
423
    public function testNativeArrayListSupport()
424
    {
425
        for ($i = 100; $i < 110; $i++) {
426
            $this->_conn->insert('fetch_table', array('test_int' => $i, 'test_string' => 'foo' . $i, 'test_datetime' => '2010-01-01 10:10:10'));
427
        }
428
429
        $stmt = $this->_conn->executeQuery('SELECT test_int FROM fetch_table WHERE test_int IN (?)',
430
            array(array(100, 101, 102, 103, 104)), array(Connection::PARAM_INT_ARRAY));
431
432
        $data = $stmt->fetchAll(PDO::FETCH_NUM);
433
        $this->assertEquals(5, count($data));
434
        $this->assertEquals(array(array(100), array(101), array(102), array(103), array(104)), $data);
435
436
        $stmt = $this->_conn->executeQuery('SELECT test_int FROM fetch_table WHERE test_string IN (?)',
437
            array(array('foo100', 'foo101', 'foo102', 'foo103', 'foo104')), array(Connection::PARAM_STR_ARRAY));
438
439
        $data = $stmt->fetchAll(PDO::FETCH_NUM);
440
        $this->assertEquals(5, count($data));
441
        $this->assertEquals(array(array(100), array(101), array(102), array(103), array(104)), $data);
442
    }
443
444
    /**
445
     * @dataProvider getTrimExpressionData
446
     */
447
    public function testTrimExpression($value, $position, $char, $expectedResult)
448
    {
449
        $sql = 'SELECT ' .
450
            $this->_conn->getDatabasePlatform()->getTrimExpression($value, $position, $char) . ' AS trimmed ' .
451
            'FROM fetch_table';
452
453
        $row = $this->_conn->fetchAssoc($sql);
454
        $row = array_change_key_case($row, CASE_LOWER);
455
456
        $this->assertEquals($expectedResult, $row['trimmed']);
457
    }
458
459
    public function getTrimExpressionData()
460
    {
461
        return array(
462
            array('test_string', AbstractPlatform::TRIM_UNSPECIFIED, false, 'foo'),
463
            array('test_string', AbstractPlatform::TRIM_LEADING, false, 'foo'),
464
            array('test_string', AbstractPlatform::TRIM_TRAILING, false, 'foo'),
465
            array('test_string', AbstractPlatform::TRIM_BOTH, false, 'foo'),
466
            array('test_string', AbstractPlatform::TRIM_UNSPECIFIED, "'f'", 'oo'),
467
            array('test_string', AbstractPlatform::TRIM_UNSPECIFIED, "'o'", 'f'),
468
            array('test_string', AbstractPlatform::TRIM_UNSPECIFIED, "'.'", 'foo'),
469
            array('test_string', AbstractPlatform::TRIM_LEADING, "'f'", 'oo'),
470
            array('test_string', AbstractPlatform::TRIM_LEADING, "'o'", 'foo'),
471
            array('test_string', AbstractPlatform::TRIM_LEADING, "'.'", 'foo'),
472
            array('test_string', AbstractPlatform::TRIM_TRAILING, "'f'", 'foo'),
473
            array('test_string', AbstractPlatform::TRIM_TRAILING, "'o'", 'f'),
474
            array('test_string', AbstractPlatform::TRIM_TRAILING, "'.'", 'foo'),
475
            array('test_string', AbstractPlatform::TRIM_BOTH, "'f'", 'oo'),
476
            array('test_string', AbstractPlatform::TRIM_BOTH, "'o'", 'f'),
477
            array('test_string', AbstractPlatform::TRIM_BOTH, "'.'", 'foo'),
478
            array("' foo '", AbstractPlatform::TRIM_UNSPECIFIED, false, 'foo'),
479
            array("' foo '", AbstractPlatform::TRIM_LEADING, false, 'foo '),
480
            array("' foo '", AbstractPlatform::TRIM_TRAILING, false, ' foo'),
481
            array("' foo '", AbstractPlatform::TRIM_BOTH, false, 'foo'),
482
            array("' foo '", AbstractPlatform::TRIM_UNSPECIFIED, "'f'", ' foo '),
483
            array("' foo '", AbstractPlatform::TRIM_UNSPECIFIED, "'o'", ' foo '),
484
            array("' foo '", AbstractPlatform::TRIM_UNSPECIFIED, "'.'", ' foo '),
485
            array("' foo '", AbstractPlatform::TRIM_UNSPECIFIED, "' '", 'foo'),
486
            array("' foo '", AbstractPlatform::TRIM_LEADING, "'f'", ' foo '),
487
            array("' foo '", AbstractPlatform::TRIM_LEADING, "'o'", ' foo '),
488
            array("' foo '", AbstractPlatform::TRIM_LEADING, "'.'", ' foo '),
489
            array("' foo '", AbstractPlatform::TRIM_LEADING, "' '", 'foo '),
490
            array("' foo '", AbstractPlatform::TRIM_TRAILING, "'f'", ' foo '),
491
            array("' foo '", AbstractPlatform::TRIM_TRAILING, "'o'", ' foo '),
492
            array("' foo '", AbstractPlatform::TRIM_TRAILING, "'.'", ' foo '),
493
            array("' foo '", AbstractPlatform::TRIM_TRAILING, "' '", ' foo'),
494
            array("' foo '", AbstractPlatform::TRIM_BOTH, "'f'", ' foo '),
495
            array("' foo '", AbstractPlatform::TRIM_BOTH, "'o'", ' foo '),
496
            array("' foo '", AbstractPlatform::TRIM_BOTH, "'.'", ' foo '),
497
            array("' foo '", AbstractPlatform::TRIM_BOTH, "' '", 'foo'),
498
        );
499
    }
500
501
    /**
502
     * @group DDC-1014
503
     */
504
    public function testDateArithmetics()
505
    {
506
        $p = $this->_conn->getDatabasePlatform();
507
        $sql = 'SELECT ';
508
        $sql .= $p->getDateDiffExpression('test_datetime', $p->getCurrentTimestampSQL()) .' AS diff, ';
509
        $sql .= $p->getDateAddSecondsExpression('test_datetime', 1) .' AS add_seconds, ';
510
        $sql .= $p->getDateSubSecondsExpression('test_datetime', 1) .' AS sub_seconds, ';
511
        $sql .= $p->getDateAddMinutesExpression('test_datetime', 5) .' AS add_minutes, ';
512
        $sql .= $p->getDateSubMinutesExpression('test_datetime', 5) .' AS sub_minutes, ';
513
        $sql .= $p->getDateAddHourExpression('test_datetime', 3) .' AS add_hour, ';
514
        $sql .= $p->getDateSubHourExpression('test_datetime', 3) .' AS sub_hour, ';
515
        $sql .= $p->getDateAddDaysExpression('test_datetime', 10) .' AS add_days, ';
516
        $sql .= $p->getDateSubDaysExpression('test_datetime', 10) .' AS sub_days, ';
517
        $sql .= $p->getDateAddWeeksExpression('test_datetime', 1) .' AS add_weeks, ';
518
        $sql .= $p->getDateSubWeeksExpression('test_datetime', 1) .' AS sub_weeks, ';
519
        $sql .= $p->getDateAddMonthExpression('test_datetime', 2) .' AS add_month, ';
520
        $sql .= $p->getDateSubMonthExpression('test_datetime', 2) .' AS sub_month, ';
521
        $sql .= $p->getDateAddQuartersExpression('test_datetime', 3) .' AS add_quarters, ';
522
        $sql .= $p->getDateSubQuartersExpression('test_datetime', 3) .' AS sub_quarters, ';
523
        $sql .= $p->getDateAddYearsExpression('test_datetime', 6) .' AS add_years, ';
524
        $sql .= $p->getDateSubYearsExpression('test_datetime', 6) .' AS sub_years ';
525
        $sql .= 'FROM fetch_table';
526
527
        $row = $this->_conn->fetchAssoc($sql);
528
        $row = array_change_key_case($row, CASE_LOWER);
529
530
        $diff = (strtotime('2010-01-01') - strtotime(date('Y-m-d'))) / 3600 / 24;
531
        $this->assertEquals($diff, $row['diff'], "Date difference should be approx. ".$diff." days.", 1);
532
        $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");
533
        $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");
534
        $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");
535
        $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");
536
        $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");
537
        $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");
538
        $this->assertEquals('2010-01-11', date('Y-m-d', strtotime($row['add_days'])), "Adding date should end up on 2010-01-11");
539
        $this->assertEquals('2009-12-22', date('Y-m-d', strtotime($row['sub_days'])), "Subtracting date should end up on 2009-12-22");
540
        $this->assertEquals('2010-01-08', date('Y-m-d', strtotime($row['add_weeks'])), "Adding week should end up on 2010-01-08");
541
        $this->assertEquals('2009-12-25', date('Y-m-d', strtotime($row['sub_weeks'])), "Subtracting week should end up on 2009-12-25");
542
        $this->assertEquals('2010-03-01', date('Y-m-d', strtotime($row['add_month'])), "Adding month should end up on 2010-03-01");
543
        $this->assertEquals('2009-11-01', date('Y-m-d', strtotime($row['sub_month'])), "Subtracting month should end up on 2009-11-01");
544
        $this->assertEquals('2010-10-01', date('Y-m-d', strtotime($row['add_quarters'])), "Adding quarters should end up on 2010-04-01");
545
        $this->assertEquals('2009-04-01', date('Y-m-d', strtotime($row['sub_quarters'])), "Subtracting quarters should end up on 2009-10-01");
546
        $this->assertEquals('2016-01-01', date('Y-m-d', strtotime($row['add_years'])), "Adding years should end up on 2016-01-01");
547
        $this->assertEquals('2004-01-01', date('Y-m-d', strtotime($row['sub_years'])), "Subtracting years should end up on 2004-01-01");
548
    }
549
550
    public function testLocateExpression()
551
    {
552
        $platform = $this->_conn->getDatabasePlatform();
553
554
        $sql = 'SELECT ';
555
        $sql .= $platform->getLocateExpression('test_string', "'oo'") .' AS locate1, ';
556
        $sql .= $platform->getLocateExpression('test_string', "'foo'") .' AS locate2, ';
557
        $sql .= $platform->getLocateExpression('test_string', "'bar'") .' AS locate3, ';
558
        $sql .= $platform->getLocateExpression('test_string', 'test_string') .' AS locate4, ';
559
        $sql .= $platform->getLocateExpression("'foo'", 'test_string') .' AS locate5, ';
560
        $sql .= $platform->getLocateExpression("'barfoobaz'", 'test_string') .' AS locate6, ';
561
        $sql .= $platform->getLocateExpression("'bar'", 'test_string') .' AS locate7, ';
562
        $sql .= $platform->getLocateExpression('test_string', "'oo'", 2) .' AS locate8, ';
563
        $sql .= $platform->getLocateExpression('test_string', "'oo'", 3) .' AS locate9 ';
564
        $sql .= 'FROM fetch_table';
565
566
        $row = $this->_conn->fetchAssoc($sql);
567
        $row = array_change_key_case($row, CASE_LOWER);
568
569
        $this->assertEquals(2, $row['locate1']);
570
        $this->assertEquals(1, $row['locate2']);
571
        $this->assertEquals(0, $row['locate3']);
572
        $this->assertEquals(1, $row['locate4']);
573
        $this->assertEquals(1, $row['locate5']);
574
        $this->assertEquals(4, $row['locate6']);
575
        $this->assertEquals(0, $row['locate7']);
576
        $this->assertEquals(2, $row['locate8']);
577
        $this->assertEquals(0, $row['locate9']);
578
    }
579
580 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...
581
    {
582
        $sql = "SELECT * FROM fetch_table WHERE test_string = " . $this->_conn->quote("bar' OR '1'='1");
583
        $rows = $this->_conn->fetchAll($sql);
584
585
        $this->assertEquals(0, count($rows), "no result should be returned, otherwise SQL injection is possible");
586
    }
587
588
    /**
589
     * @group DDC-1213
590
     */
591
    public function testBitComparisonExpressionSupport()
592
    {
593
        $this->_conn->exec('DELETE FROM fetch_table');
594
        $platform = $this->_conn->getDatabasePlatform();
595
        $bitmap   = array();
596
597
        for ($i = 2; $i < 9; $i = $i + 2) {
598
            $bitmap[$i] = array(
599
                'bit_or'    => ($i | 2),
600
                'bit_and'   => ($i & 2)
601
            );
602
            $this->_conn->insert('fetch_table', array(
603
                'test_int'      => $i,
604
                'test_string'   => json_encode($bitmap[$i]),
605
                'test_datetime' => '2010-01-01 10:10:10'
606
            ));
607
        }
608
609
        $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...
610
        $sql[]  = 'test_int, ';
611
        $sql[]  = 'test_string, ';
612
        $sql[]  = $platform->getBitOrComparisonExpression('test_int', 2) . ' AS bit_or, ';
613
        $sql[]  = $platform->getBitAndComparisonExpression('test_int', 2) . ' AS bit_and ';
614
        $sql[]  = 'FROM fetch_table';
615
616
        $stmt   = $this->_conn->executeQuery(implode(PHP_EOL, $sql));
617
        $data   = $stmt->fetchAll(PDO::FETCH_ASSOC);
618
619
620
        $this->assertEquals(4, count($data));
621
        $this->assertEquals(count($bitmap), count($data));
622
        foreach ($data as $row) {
623
            $row = array_change_key_case($row, CASE_LOWER);
624
625
            $this->assertArrayHasKey('test_int', $row);
626
627
            $id = $row['test_int'];
628
629
            $this->assertArrayHasKey($id, $bitmap);
630
            $this->assertArrayHasKey($id, $bitmap);
631
632
            $this->assertArrayHasKey('bit_or', $row);
633
            $this->assertArrayHasKey('bit_and', $row);
634
635
            $this->assertEquals($row['bit_or'], $bitmap[$id]['bit_or']);
636
            $this->assertEquals($row['bit_and'], $bitmap[$id]['bit_and']);
637
        }
638
    }
639
640
    public function testSetDefaultFetchMode()
641
    {
642
        $stmt = $this->_conn->query("SELECT * FROM fetch_table");
643
        $stmt->setFetchMode(\PDO::FETCH_NUM);
644
645
        $row = array_keys($stmt->fetch());
646
        $this->assertEquals(0, count( array_filter($row, function($v) { return ! is_numeric($v); })), "should be no non-numerical elements in the result.");
647
    }
648
649
    /**
650
     * @group DBAL-1091
651
     */
652
    public function testFetchAllStyleObject()
653
    {
654
        $this->setupFixture();
655
656
        $sql = 'SELECT test_int, test_string, test_datetime FROM fetch_table';
657
        $stmt = $this->_conn->prepare($sql);
658
659
        $stmt->execute();
660
661
        $results = $stmt->fetchAll(\PDO::FETCH_OBJ);
662
663
        $this->assertCount(1, $results);
664
        $this->assertInstanceOf('stdClass', $results[0]);
665
666
        $this->assertEquals(
667
            1,
668
            property_exists($results[0], 'test_int') ? $results[0]->test_int : $results[0]->TEST_INT
669
        );
670
        $this->assertEquals(
671
            'foo',
672
            property_exists($results[0], 'test_string') ? $results[0]->test_string : $results[0]->TEST_STRING
673
        );
674
        $this->assertStringStartsWith(
675
            '2010-01-01 10:10:10',
676
            property_exists($results[0], 'test_datetime') ? $results[0]->test_datetime : $results[0]->TEST_DATETIME
677
        );
678
    }
679
680
    /**
681
     * @group DBAL-196
682
     */
683 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...
684
    {
685
        $this->skipOci8AndMysqli();
686
        $this->setupFixture();
687
688
        $sql    = "SELECT test_int, test_string, test_datetime FROM fetch_table";
689
        $stmt   = $this->_conn->prepare($sql);
690
        $stmt->execute();
691
692
        $results = $stmt->fetchAll(
693
            \PDO::FETCH_CLASS,
694
            __NAMESPACE__.'\\MyFetchClass'
695
        );
696
697
        $this->assertEquals(1, count($results));
698
        $this->assertInstanceOf(__NAMESPACE__.'\\MyFetchClass', $results[0]);
699
700
        $this->assertEquals(1, $results[0]->test_int);
701
        $this->assertEquals('foo', $results[0]->test_string);
702
        $this->assertStringStartsWith('2010-01-01 10:10:10', $results[0]->test_datetime);
703
    }
704
705
    /**
706
     * @group DBAL-241
707
     */
708
    public function testFetchAllStyleColumn()
709
    {
710
        $sql = "DELETE FROM fetch_table";
711
        $this->_conn->executeUpdate($sql);
712
713
        $this->_conn->insert('fetch_table', array('test_int' => 1, 'test_string' => 'foo'));
714
        $this->_conn->insert('fetch_table', array('test_int' => 10, 'test_string' => 'foo'));
715
716
        $sql = "SELECT test_int FROM fetch_table";
717
        $rows = $this->_conn->query($sql)->fetchAll(\PDO::FETCH_COLUMN);
718
719
        $this->assertEquals(array(1, 10), $rows);
720
    }
721
722
    /**
723
     * @group DBAL-214
724
     */
725 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...
726
    {
727
        $this->skipOci8AndMysqli();
728
        $this->setupFixture();
729
730
        $sql = "SELECT * FROM fetch_table";
731
        $stmt = $this->_conn->query($sql);
732
        $stmt->setFetchMode(\PDO::FETCH_CLASS, __NAMESPACE__ . '\\MyFetchClass');
733
734
        $results = $stmt->fetchAll();
735
736
        $this->assertEquals(1, count($results));
737
        $this->assertInstanceOf(__NAMESPACE__.'\\MyFetchClass', $results[0]);
738
739
        $this->assertEquals(1, $results[0]->test_int);
740
        $this->assertEquals('foo', $results[0]->test_string);
741
        $this->assertStringStartsWith('2010-01-01 10:10:10', $results[0]->test_datetime);
742
    }
743
744
    /**
745
     * @group DBAL-214
746
     */
747
    public function testSetFetchModeClassFetch()
748
    {
749
        $this->skipOci8AndMysqli();
750
        $this->setupFixture();
751
752
        $sql = "SELECT * FROM fetch_table";
753
        $stmt = $this->_conn->query($sql);
754
        $stmt->setFetchMode(\PDO::FETCH_CLASS, __NAMESPACE__ . '\\MyFetchClass');
755
756
        $results = array();
757
        while ($row = $stmt->fetch()) {
758
            $results[] = $row;
759
        }
760
761
        $this->assertEquals(1, count($results));
762
        $this->assertInstanceOf(__NAMESPACE__.'\\MyFetchClass', $results[0]);
763
764
        $this->assertEquals(1, $results[0]->test_int);
765
        $this->assertEquals('foo', $results[0]->test_string);
766
        $this->assertStringStartsWith('2010-01-01 10:10:10', $results[0]->test_datetime);
767
    }
768
769
    /**
770
     * @group DBAL-257
771
     */
772
    public function testEmptyFetchColumnReturnsFalse()
773
    {
774
        $this->_conn->exec('DELETE FROM fetch_table');
775
        $this->assertFalse($this->_conn->fetchColumn('SELECT test_int FROM fetch_table'));
776
        $this->assertFalse($this->_conn->query('SELECT test_int FROM fetch_table')->fetchColumn());
777
    }
778
779
    /**
780
     * @group DBAL-339
781
     */
782
    public function testSetFetchModeOnDbalStatement()
783
    {
784
        $sql = "SELECT test_int, test_string FROM fetch_table WHERE test_int = ? AND test_string = ?";
785
        $stmt = $this->_conn->executeQuery($sql, array(1, "foo"));
786
        $stmt->setFetchMode(\PDO::FETCH_NUM);
787
788
        while ($row = $stmt->fetch()) {
789
            $this->assertTrue(isset($row[0]));
790
            $this->assertTrue(isset($row[1]));
791
        }
792
    }
793
794
    /**
795
     * @group DBAL-435
796
     */
797
    public function testEmptyParameters()
798
    {
799
        $sql = "SELECT * FROM fetch_table WHERE test_int IN (?)";
800
        $stmt = $this->_conn->executeQuery($sql, array(array()), array(\Doctrine\DBAL\Connection::PARAM_INT_ARRAY));
801
        $rows = $stmt->fetchAll();
802
803
        $this->assertEquals(array(), $rows);
804
    }
805
806
    /**
807
     * @group DBAL-1028
808
     */
809
    public function testFetchColumnNullValue()
810
    {
811
        $this->_conn->executeUpdate(
812
            'INSERT INTO fetch_table (test_int, test_string) VALUES (?, ?)',
813
            array(1, 'foo')
814
        );
815
816
        $this->assertNull(
817
            $this->_conn->fetchColumn('SELECT test_datetime FROM fetch_table WHERE test_int = ?', array(1))
818
        );
819
    }
820
821
    /**
822
     * @group DBAL-1028
823
     */
824
    public function testFetchColumnNonExistingIndex()
825
    {
826
        if ($this->_conn->getDriver()->getName() === 'pdo_sqlsrv') {
827
            $this->markTestSkipped(
828
                'Test does not work for pdo_sqlsrv driver as it throws a fatal error for a non-existing column index.'
829
            );
830
        }
831
832
        $this->assertNull(
833
            $this->_conn->fetchColumn('SELECT test_int FROM fetch_table WHERE test_int = ?', array(1), 1)
834
        );
835
    }
836
837
    /**
838
     * @group DBAL-1028
839
     */
840
    public function testFetchColumnNoResult()
841
    {
842
        $this->assertFalse(
843
            $this->_conn->fetchColumn('SELECT test_int FROM fetch_table WHERE test_int = ?', array(-1))
844
        );
845
    }
846
847
    private function setupFixture()
848
    {
849
        $this->_conn->exec('DELETE FROM fetch_table');
850
        $this->_conn->insert('fetch_table', array(
851
            'test_int'      => 1,
852
            'test_string'   => 'foo',
853
            'test_datetime' => '2010-01-01 10:10:10'
854
        ));
855
    }
856
857
    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...
858
    {
859
        if (isset($GLOBALS['db_type']) && $GLOBALS['db_type'] == "oci8")  {
860
            $this->markTestSkipped("Not supported by OCI8");
861
        }
862
        if ('mysqli' == $this->_conn->getDriver()->getName()) {
863
            $this->markTestSkipped('Mysqli driver dont support this feature.');
864
        }
865
    }
866
867
    public function testIteratorCanBeIteratedMultipleTimes()
868
    {
869
        $skippedMessage = <<<'MSG'
870
Iterators are not rewindable for either PDO or Non PDO drivers. This is because PDO by default is not rewindable and 
871
to be consistent we have not implemented rewindable iterators for non PDO drivers. Should PDO ever become rewindable by
872
default we should wrap the legacy drivers in Doctrine\DBAL\RewindableGenerator for example on the Mysqli driver you 
873
would do something like the following:
874
875
return new RewindableGenerator(function() {
876
    $this->_stmt->data_seek(0);
877
    while ($row = $this->fetch()) {
878
        yield $row;
879
    }
880
});
881
882
If this has been done you can include this test. 
883
MSG;
884
885
        $this->markTestSkipped($skippedMessage);
886
887
        $sql = 'SELECT CURTIME(6) AS time_started, test_int, test_string FROM fetch_table';
888
        $stmt = $this->_conn->query($sql);
889
        $stmt->setFetchMode(\PDO::FETCH_ASSOC);
890
891
        $timeStartedMsFirstLoop = null;
892
        $timeStartedMsSecondLoop = null;
893
894
        $i = 0;
895
        foreach ($stmt as $row) {
896
            $timeStartedMsFirstLoop = $row['time_started'];
897
            $i++;
898
        }
899
900
        $j = 0;
901
        foreach ($stmt as $row2) {
902
            $timeStartedMsSecondLoop = $row2['time_started'];
903
            $j++;
904
        }
905
906
        $this->assertEquals($i, $j);
907
        $this->assertEquals($timeStartedMsFirstLoop, $timeStartedMsSecondLoop);
908
    }
909
}
910
911
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...
912
{
913
    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...
914
}
915