Passed
Push — amo/scrutinizer-new-engine ( 927449 )
by Andreas
10:16
created

DataAccessTestCase   A

Complexity

Total Complexity 38

Size/Duplication

Total Lines 564
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 38
eloc 309
c 0
b 0
f 0
dl 0
loc 564
rs 9.36

30 Methods

Rating   Name   Duplication   Size   Complexity  
A tearDown() 0 5 2
A testExecuteUpdateBindDateTimeType() 0 17 1
A setupFixture() 0 7 1
A testFetchAllSupportFetchClass() 0 21 1
A testFetchAll() 0 13 1
A testDateArithmetics() 0 22 1
A testFetchBoth() 0 13 1
A testPrepareWithBindParam() 0 16 1
A testSetFetchModeClassFetch() 0 21 2
A testQuoteSQLInjection() 0 6 1
A testNativeArrayListSupport() 0 20 2
A testPrepareWithIterator() 0 20 2
A testPrepareWithFetchAllBoth() 0 16 1
A testPrepareQueryBindValueDateTimeType() 0 8 1
A testSetFetchModeClassFetchAll() 0 17 1
A testPrepareWithQuoted() 0 10 1
A testFetchColumn() 0 11 1
A testPrepareWithExecuteParams() 0 14 1
A testFetchArray() 0 7 1
A testPrepareWithFetchColumn() 0 15 1
A testPrepareWithBindValue() 0 13 1
A testFetchRow() 0 11 1
A testSetDefaultFetchMode() 0 7 1
A testExecuteQueryBindDateTimeType() 0 9 1
A testBitComparisonExpressionSupport() 0 48 3
A testFetchAllStyleColumn() 0 13 1
A testPrepareWithFetchAll() 0 29 1
A setUp() 0 35 2
A testSetFetchModeOnDbalStatement() 0 9 2
A testEmptyFetchColumnReturnsFalse() 0 6 1
1
<?php
2
/**
3
 * Licensed to CRATE Technology GmbH("Crate") under one or more contributor
4
 * license agreements.  See the NOTICE file distributed with this work for
5
 * additional information regarding copyright ownership.  Crate licenses
6
 * this file to you under the Apache License, Version 2.0 (the "License");
7
 * you may not use this file except in compliance with the License.  You may
8
 * obtain a copy of the License at
9
 *
10
 * http://www.apache.org/licenses/LICENSE-2.0
11
 *
12
 * Unless required by applicable law or agreed to in writing, software
13
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
14
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
15
 * License for the specific language governing permissions and limitations
16
 * under the License.
17
 *
18
 * However, if you have executed another commercial license agreement
19
 * with Crate these terms will supersede the license and you may use the
20
 * software solely pursuant to the terms of the relevant commercial agreement.
21
 */
22
23
namespace Crate\Test\DBAL\Functional;
24
25
use Crate\DBAL\Types\MapType;
26
use Crate\Test\DBAL\DBALFunctionalTestCase;
27
use Doctrine\DBAL\DBALException;
28
use Doctrine\DBAL\ParameterType;
29
use Doctrine\DBAL\Schema\Column;
30
use Doctrine\DBAL\Types\Type;
31
use Doctrine\DBAL\Connection;
32
use PDO;
33
34
35
class DataAccessTestCase extends DBALFunctionalTestCase
36
{
37
    static private $generated = false;
38
39
    public function setUp() : void
40
    {
41
        parent::setUp();
42
43
        if (self::$generated === false) {
44
            self::$generated = true;
45
            /* @var $sm \Doctrine\DBAL\Schema\AbstractSchemaManager */
46
            $sm = $this->_conn->getSchemaManager();
47
            $table = new \Doctrine\DBAL\Schema\Table("fetch_table");
48
            $table->addColumn('test_int', 'integer');
49
            $table->addColumn('test_string', 'string');
50
            $table->addColumn('test_datetime', 'timestamp', array('notnull' => false));
51
            $table->addColumn('test_array', 'array', array('columnDefinition'=>'ARRAY(STRING)'));
52
            $platformOptions = array(
53
                'type'   => MapType::STRICT,
54
                'fields' => array(
55
                    new Column('id',    Type::getType('integer'), array()),
56
                    new Column('name',  Type::getType('string'), array()),
57
                    new Column('value', Type::getType('float'), array()),
58
                ),
59
            );
60
            $table->addColumn('test_object', MapType::NAME,
61
                array('platformOptions'=>$platformOptions));
62
            $table->setPrimaryKey(array('test_int'));
63
64
            $sm->createTable($table);
65
66
            $this->_conn->insert('fetch_table', array(
67
                'test_int' => 1,
68
                'test_string' => 'foo',
69
                'test_datetime' => new \DateTime('2010-01-01 10:10:10'),
70
                'test_array' => array('foo','bar'),
71
                'test_object' => array('id'=>1, 'name'=>'foo', 'value'=>1.234,),
72
            ), array('integer','string','timestamp','array','map'));
73
            $this->refresh('fetch_table');
74
        }
75
    }
76
77
    public function tearDown() : void
78
    {
79
        if (self::$generated === true) {
80
            $this->_conn->getSchemaManager()->dropTable('fetch_table');
81
            self::$generated = false;
82
        }
83
    }
84
85
    public function testPrepareWithBindValue()
86
    {
87
        $sql = "SELECT test_int, test_string FROM fetch_table WHERE test_int = ? AND test_string = ?";
88
        $stmt = $this->_conn->prepare($sql);
89
        $this->assertInstanceOf('Doctrine\DBAL\Statement', $stmt);
90
91
        $stmt->bindValue(1, 1, PDO::PARAM_INT);
92
        $stmt->bindValue(2, 'foo', PDO::PARAM_STR);
93
        $stmt->execute();
94
95
        $row = $stmt->fetch(\PDO::FETCH_ASSOC);
96
        $row = array_change_key_case($row, \CASE_LOWER);
97
        $this->assertEquals(array('test_int' => 1, 'test_string' => 'foo'), $row);
98
    }
99
100
    public function testPrepareWithBindParam()
101
    {
102
        $paramInt = 1;
103
        $paramStr = 'foo';
104
105
        $sql = "SELECT test_int, test_string FROM fetch_table WHERE test_int = ? AND test_string = ?";
106
        $stmt = $this->_conn->prepare($sql);
107
        $this->assertInstanceOf('Doctrine\DBAL\Statement', $stmt);
108
109
        $stmt->bindParam(1, $paramInt, PDO::PARAM_INT);
110
        $stmt->bindParam(2, $paramStr, PDO::PARAM_STR);
111
        $stmt->execute();
112
113
        $row = $stmt->fetch(\PDO::FETCH_ASSOC);
114
        $row = array_change_key_case($row, \CASE_LOWER);
115
        $this->assertEquals(array('test_int' => 1, 'test_string' => 'foo'), $row);
116
    }
117
118
    public function testPrepareWithFetchAll()
119
    {
120
        $paramInt = 1;
121
        $paramStr = 'foo';
122
123
        $sql = "SELECT test_int, test_string, test_datetime, test_array, test_object FROM fetch_table WHERE test_int = ? AND test_string = ?";
124
        $stmt = $this->_conn->prepare($sql);
125
        $this->assertInstanceOf('Doctrine\DBAL\Statement', $stmt);
126
127
        $stmt->bindParam(1, $paramInt, PDO::PARAM_INT);
128
        $stmt->bindParam(2, $paramStr, PDO::PARAM_STR);
129
        $stmt->execute();
130
131
        $rows = $stmt->fetchAll(\PDO::FETCH_ASSOC);
132
        $rows[0] = array_change_key_case($rows[0], \CASE_LOWER);
133
        $this->assertEquals(array(
134
            'test_int' => 1,
135
            'test_string' => 'foo',
136
            'test_datetime' => 1262340610000,
137
            'test_array' => array('foo', 'bar'),
138
            'test_object' => array('id'=>1, 'name'=>'foo', 'value'=>1.234)
139
        ), $rows[0]);
140
141
        $this->assertEquals($this->_conn->convertToPHPValue($rows[0]['test_datetime'], 'timestamp'),
142
            new \DateTime('2010-01-01 10:10:10'));
143
        $this->assertEquals($this->_conn->convertToPHPValue($rows[0]['test_object'], 'map'),
144
            array('id'=>1, 'name'=>'foo', 'value'=>1.234));
145
        $this->assertEquals($this->_conn->convertToPHPValue($rows[0]['test_array'], 'array'),
146
            array('foo','bar'));
147
    }
148
149
    /**
150
     * @group DBAL-228
151
     */
152
    public function testPrepareWithFetchAllBoth()
153
    {
154
        $paramInt = 1;
155
        $paramStr = 'foo';
156
157
        $sql = "SELECT test_int, test_string FROM fetch_table WHERE test_int = ? AND test_string = ?";
158
        $stmt = $this->_conn->prepare($sql);
159
        $this->assertInstanceOf('Doctrine\DBAL\Statement', $stmt);
160
161
        $stmt->bindParam(1, $paramInt, PDO::PARAM_INT);
162
        $stmt->bindParam(2, $paramStr, PDO::PARAM_STR);
163
        $stmt->execute();
164
165
        $rows = $stmt->fetchAll(\PDO::FETCH_BOTH);
166
        $rows[0] = array_change_key_case($rows[0], \CASE_LOWER);
167
        $this->assertEquals(array('test_int' => 1, 'test_string' => 'foo', 0 => 1, 1 => 'foo'), $rows[0]);
168
    }
169
170
    public function testPrepareWithFetchColumn()
171
    {
172
        $paramInt = 1;
173
        $paramStr = 'foo';
174
175
        $sql = "SELECT test_int FROM fetch_table WHERE test_int = ? AND test_string = ?";
176
        $stmt = $this->_conn->prepare($sql);
177
        $this->assertInstanceOf('Doctrine\DBAL\Statement', $stmt);
178
179
        $stmt->bindParam(1, $paramInt, PDO::PARAM_INT);
180
        $stmt->bindParam(2, $paramStr, PDO::PARAM_STR);
181
        $stmt->execute();
182
183
        $column = $stmt->fetchColumn();
184
        $this->assertEquals(1, $column);
185
    }
186
187
    public function testPrepareWithIterator()
188
    {
189
        $paramInt = 1;
190
        $paramStr = 'foo';
191
192
        $sql = "SELECT test_int, test_string FROM fetch_table WHERE test_int = ? AND test_string = ?";
193
        $stmt = $this->_conn->prepare($sql);
194
        $this->assertInstanceOf('Doctrine\DBAL\Statement', $stmt);
195
196
        $stmt->bindParam(1, $paramInt, PDO::PARAM_INT);
197
        $stmt->bindParam(2, $paramStr, PDO::PARAM_STR);
198
        $stmt->execute();
199
200
        $rows = array();
201
        $stmt->setFetchMode(\PDO::FETCH_ASSOC);
202
        foreach ($stmt as $row) {
203
            $rows[] = array_change_key_case($row, \CASE_LOWER);
204
        }
205
206
        $this->assertEquals(array('test_int' => 1, 'test_string' => 'foo'), $rows[0]);
207
    }
208
209
    public function testPrepareWithQuoted()
210
    {
211
        $table = 'fetch_table';
212
        $paramInt = 1;
213
        $paramStr = 'foo';
214
215
        $sql = "SELECT test_int, test_string FROM " . $this->_conn->quoteIdentifier($table) . " ".
216
               "WHERE test_int = " . $this->_conn->quote($paramInt, ParameterType::INTEGER) . " AND test_string = '" . $paramStr . "')";
217
        $stmt = $this->_conn->prepare($sql);
218
        $this->assertInstanceOf('Doctrine\DBAL\Statement', $stmt);
219
    }
220
221
    public function testPrepareWithExecuteParams()
222
    {
223
        $paramInt = 1;
224
        $paramStr = 'foo';
225
226
        $sql = "SELECT test_int, test_string FROM fetch_table WHERE test_int = ? AND test_string = ?";
227
        $stmt = $this->_conn->prepare($sql);
228
        $this->assertInstanceOf('Doctrine\DBAL\Statement', $stmt);
229
        $stmt->execute(array($paramInt, $paramStr));
230
231
        $row = $stmt->fetch(\PDO::FETCH_ASSOC);
232
        $this->assertTrue($row !== false);
233
        $row = array_change_key_case($row, \CASE_LOWER);
234
        $this->assertEquals(array('test_int' => 1, 'test_string' => 'foo'), $row);
235
    }
236
237
    public function testFetchAll()
238
    {
239
        $sql = "SELECT test_int, test_string FROM fetch_table WHERE test_int = ? AND test_string = ?";
240
        $data = $this->_conn->fetchAll($sql, array(1, 'foo'));
241
242
        $this->assertEquals(1, count($data));
243
244
        $row = $data[0];
245
        $this->assertEquals(2, count($row));
246
247
        $row = array_change_key_case($row, \CASE_LOWER);
248
        $this->assertEquals(1, $row['test_int']);
249
        $this->assertEquals('foo', $row['test_string']);
250
    }
251
252
    public function testFetchBoth()
253
    {
254
        $sql = "SELECT test_int, test_string FROM fetch_table WHERE test_int = ? AND test_string = ?";
255
        $row = $this->_conn->executeQuery($sql, array(1, 'foo'))->fetch(\PDO::FETCH_BOTH);
256
257
        $this->assertTrue($row !== false);
258
259
        $row = array_change_key_case($row, \CASE_LOWER);
260
261
        $this->assertEquals(1, $row['test_int']);
262
        $this->assertEquals('foo', $row['test_string']);
263
        $this->assertEquals(1, $row[0]);
264
        $this->assertEquals('foo', $row[1]);
265
    }
266
267
    public function testFetchRow()
268
    {
269
        $sql = "SELECT test_int, test_string FROM fetch_table WHERE test_int = ? AND test_string = ?";
270
        $row = $this->_conn->fetchAssoc($sql, array(1, 'foo'));
271
272
        $this->assertTrue($row !== false);
273
274
        $row = array_change_key_case($row, \CASE_LOWER);
0 ignored issues
show
Bug introduced by
It seems like $row can also be of type false; however, parameter $array of array_change_key_case() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

274
        $row = array_change_key_case(/** @scrutinizer ignore-type */ $row, \CASE_LOWER);
Loading history...
275
276
        $this->assertEquals(1, $row['test_int']);
277
        $this->assertEquals('foo', $row['test_string']);
278
    }
279
280
    public function testFetchArray()
281
    {
282
        $sql = "SELECT test_int, test_string FROM fetch_table WHERE test_int = ? AND test_string = ?";
283
        $row = $this->_conn->fetchArray($sql, array(1, 'foo'));
284
285
        $this->assertEquals(1, $row[0]);
286
        $this->assertEquals('foo', $row[1]);
287
    }
288
289
    public function testFetchColumn()
290
    {
291
        $sql = "SELECT test_int, test_string FROM fetch_table WHERE test_int = ? AND test_string = ?";
292
        $testInt = $this->_conn->fetchColumn($sql, array(1, 'foo'), 0);
293
294
        $this->assertEquals(1, $testInt);
295
296
        $sql = "SELECT test_int, test_string FROM fetch_table WHERE test_int = ? AND test_string = ?";
297
        $testString = $this->_conn->fetchColumn($sql, array(1, 'foo'), 1);
298
299
        $this->assertEquals('foo', $testString);
300
    }
301
302
    /**
303
     * @group DDC-697
304
     */
305
    public function testExecuteQueryBindDateTimeType()
306
    {
307
        $sql = 'SELECT count(*) AS c FROM fetch_table WHERE test_datetime = ?';
308
        $stmt = $this->_conn->executeQuery($sql,
309
            array(1 => new \DateTime('2010-01-01 10:10:10')),
310
            array(1 => Type::DATETIME)
0 ignored issues
show
Deprecated Code introduced by
The constant Doctrine\DBAL\Types\Type::DATETIME has been deprecated: Use {@see Types::DATETIME_MUTABLE} instead. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

310
            array(1 => /** @scrutinizer ignore-deprecated */ Type::DATETIME)

This class constant has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the constant will be removed from the class and what other constant to use instead.

Loading history...
311
        );
312
313
        $this->assertEquals(1, $stmt->fetchColumn());
314
    }
315
316
    /**
317
     * @group DDC-697
318
     */
319
    public function testExecuteUpdateBindDateTimeType()
320
    {
321
        $datetime = new \DateTime('2010-02-02 20:20:20');
322
323
        $sql = 'INSERT INTO fetch_table (test_int, test_string, test_datetime) VALUES (?, ?, ?)';
324
        $affectedRows = $this->_conn->executeUpdate($sql,
325
            array(1 => 50,              2 => 'foo',             3 => $datetime),
326
            array(1 => PDO::PARAM_INT,  2 => PDO::PARAM_STR,    3 => Type::DATETIME)
0 ignored issues
show
Deprecated Code introduced by
The constant Doctrine\DBAL\Types\Type::DATETIME has been deprecated: Use {@see Types::DATETIME_MUTABLE} instead. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

326
            array(1 => PDO::PARAM_INT,  2 => PDO::PARAM_STR,    3 => /** @scrutinizer ignore-deprecated */ Type::DATETIME)

This class constant has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the constant will be removed from the class and what other constant to use instead.

Loading history...
327
        );
328
        $this->assertEquals(1, $affectedRows);
329
        $this->refresh('fetch_table');
330
331
        $this->assertEquals(1, $this->_conn->executeQuery(
332
            'SELECT count(*) AS c FROM fetch_table WHERE test_datetime = ?',
333
            array(1 => $datetime),
334
            array(1 => Type::DATETIME)
0 ignored issues
show
Deprecated Code introduced by
The constant Doctrine\DBAL\Types\Type::DATETIME has been deprecated: Use {@see Types::DATETIME_MUTABLE} instead. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

334
            array(1 => /** @scrutinizer ignore-deprecated */ Type::DATETIME)

This class constant has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the constant will be removed from the class and what other constant to use instead.

Loading history...
335
        )->fetchColumn());
336
    }
337
338
    /**
339
     * @group DDC-697
340
     */
341
    public function testPrepareQueryBindValueDateTimeType()
342
    {
343
        $sql = 'SELECT count(*) AS c FROM fetch_table WHERE test_datetime = ?';
344
        $stmt = $this->_conn->prepare($sql);
345
        $stmt->bindValue(1, new \DateTime('2010-01-01 10:10:10'), Type::DATETIME);
0 ignored issues
show
Deprecated Code introduced by
The constant Doctrine\DBAL\Types\Type::DATETIME has been deprecated: Use {@see Types::DATETIME_MUTABLE} instead. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

345
        $stmt->bindValue(1, new \DateTime('2010-01-01 10:10:10'), /** @scrutinizer ignore-deprecated */ Type::DATETIME);

This class constant has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the constant will be removed from the class and what other constant to use instead.

Loading history...
346
        $stmt->execute();
347
348
        $this->assertEquals(1, $stmt->fetchColumn());
349
    }
350
351
    /**
352
     * @group DBAL-78
353
     */
354
    public function testNativeArrayListSupport()
355
    {
356
        for ($i = 100; $i < 110; $i++) {
357
            $this->_conn->insert('fetch_table', array('test_int' => $i, 'test_string' => 'foo' . $i, 'test_datetime' => '2010-01-01T10:10:10'));
358
        }
359
        $this->refresh('fetch_table');
360
361
        $stmt = $this->_conn->executeQuery('SELECT test_int FROM fetch_table WHERE test_int IN (?) ORDER BY test_int',
362
            array(array(100, 101, 102, 103, 104)), array(Connection::PARAM_INT_ARRAY));
363
364
        $data = $stmt->fetchAll(PDO::FETCH_NUM);
365
        $this->assertEquals(5, count($data));
366
        $this->assertEquals(array(array(100), array(101), array(102), array(103), array(104)), $data);
367
368
        $stmt = $this->_conn->executeQuery('SELECT test_int FROM fetch_table WHERE test_string IN (?) ORDER BY test_int',
369
            array(array('foo100', 'foo101', 'foo102', 'foo103', 'foo104')), array(Connection::PARAM_STR_ARRAY));
370
371
        $data = $stmt->fetchAll(PDO::FETCH_NUM);
372
        $this->assertEquals(5, count($data));
373
        $this->assertEquals(array(array(100), array(101), array(102), array(103), array(104)), $data);
374
    }
375
376
    /**
377
     * @group DDC-1014
378
     */
379
    public function testDateArithmetics()
380
    {
381
        $this->markTestSkipped('Data add day expression not supported by crate platform');
382
383
        $p = $this->_conn->getDatabasePlatform();
384
        $sql = 'SELECT ';
385
        $sql .= $p->getDateDiffExpression('test_datetime', $p->getCurrentTimestampSQL()) .' AS diff, ';
386
        $sql .= $p->getDateAddDaysExpression('test_datetime', 10) .' AS add_days, ';
387
        $sql .= $p->getDateSubDaysExpression('test_datetime', 10) .' AS sub_days, ';
388
        $sql .= $p->getDateAddMonthExpression('test_datetime', 2) .' AS add_month, ';
389
        $sql .= $p->getDateSubMonthExpression('test_datetime', 2) .' AS sub_month ';
390
        $sql .= 'FROM fetch_table';
391
392
        $row = $this->_conn->fetchAssoc($sql);
393
        $row = array_change_key_case($row, CASE_LOWER);
394
395
        $diff = floor( (strtotime('2010-01-01')-time()) / 3600 / 24);
396
        $this->assertEquals($diff, (int)$row['diff'], "Date difference should be approx. ".$diff." days.", 1);
397
        $this->assertEquals('2010-01-11', date('Y-m-d', strtotime($row['add_days'])), "Adding date should end up on 2010-01-11");
398
        $this->assertEquals('2009-12-22', date('Y-m-d', strtotime($row['sub_days'])), "Subtracting date should end up on 2009-12-22");
399
        $this->assertEquals('2010-03-01', date('Y-m-d', strtotime($row['add_month'])), "Adding month should end up on 2010-03-01");
400
        $this->assertEquals('2009-11-01', date('Y-m-d', strtotime($row['sub_month'])), "Adding month should end up on 2009-11-01");
401
    }
402
403
    public function testQuoteSQLInjection()
404
    {
405
        $this->expectException(DBALException::class);
406
407
        $sql = "SELECT * FROM fetch_table WHERE test_string = bar' OR '1'='1";
408
        $this->_conn->fetchAll($sql);
409
    }
410
411
    /**
412
     * @group DDC-1213
413
     */
414
    public function testBitComparisonExpressionSupport()
415
    {
416
        $this->markTestSkipped("Bit comparison expression not supported by crate");
417
418
        $this->_conn->executeQuery('DELETE FROM fetch_table')->execute();
419
        $platform = $this->_conn->getDatabasePlatform();
420
        $bitmap   = array();
421
422
        for ($i = 2; $i < 9; $i = $i + 2) {
423
            $bitmap[$i] = array(
424
                'bit_or'    => ($i | 2),
425
                'bit_and'   => ($i & 2)
426
            );
427
            $this->_conn->insert('fetch_table', array(
428
                'test_int'      => $i,
429
                'test_string'   => json_encode($bitmap[$i]),
430
                'test_datetime' => '2010-01-01T10:10:10'
431
            ));
432
        }
433
434
        $sql[]  = 'SELECT ';
0 ignored issues
show
Comprehensibility Best Practice introduced by
$sql was never initialized. Although not strictly required by PHP, it is generally a good practice to add $sql = array(); before regardless.
Loading history...
435
        $sql[]  = 'test_int, ';
436
        $sql[]  = 'test_string, ';
437
        $sql[]  = $platform->getBitOrComparisonExpression('test_int', 2) . ' AS bit_or, ';
438
        $sql[]  = $platform->getBitAndComparisonExpression('test_int', 2) . ' AS bit_and ';
439
        $sql[]  = 'FROM fetch_table';
440
441
        $stmt   = $this->_conn->executeQuery(implode(PHP_EOL, $sql));
442
        $data   = $stmt->fetchAll(PDO::FETCH_ASSOC);
443
444
445
        $this->assertEquals(4, count($data));
446
        $this->assertEquals(count($bitmap), count($data));
447
        foreach ($data as $row) {
448
            $row = array_change_key_case($row, CASE_LOWER);
449
450
            $this->assertArrayHasKey('test_int', $row);
451
452
            $id = $row['test_int'];
453
454
            $this->assertArrayHasKey($id, $bitmap);
455
            $this->assertArrayHasKey($id, $bitmap);
456
457
            $this->assertArrayHasKey('bit_or', $row);
458
            $this->assertArrayHasKey('bit_and', $row);
459
460
            $this->assertEquals($row['bit_or'], $bitmap[$id]['bit_or']);
461
            $this->assertEquals($row['bit_and'], $bitmap[$id]['bit_and']);
462
        }
463
    }
464
465
    public function testSetDefaultFetchMode()
466
    {
467
        $stmt = $this->_conn->query("SELECT * FROM fetch_table");
468
        $stmt->setFetchMode(\PDO::FETCH_NUM);
469
470
        $row = array_keys($stmt->fetch());
471
        $this->assertEquals(0, count( array_filter($row, function($v) { return ! is_numeric($v); })), "should be no non-numerical elements in the result.");
472
    }
473
474
    /**
475
     * @group DBAL-196
476
     */
477
    public function testFetchAllSupportFetchClass()
478
    {
479
        $this->markTestSkipped("PDO::FETCH_CLASS not supported by crate PDO");
480
481
        $this->setupFixture();
482
483
        $sql    = "SELECT test_int, test_string, test_datetime FROM fetch_table";
484
        $stmt   = $this->_conn->prepare($sql);
485
        $stmt->execute();
486
487
        $results = $stmt->fetchAll(
488
            \PDO::FETCH_CLASS,
489
            __NAMESPACE__.'\\MyFetchClass'
490
        );
491
492
        $this->assertEquals(1, count($results));
493
        $this->assertInstanceOf(__NAMESPACE__.'\\MyFetchClass', $results[0]);
494
495
        $this->assertEquals(1, $results[0]->test_int);
496
        $this->assertEquals('foo', $results[0]->test_string);
497
        $this->assertStringStartsWith('2010-01-01T10:10:10', $results[0]->test_datetime);
498
    }
499
500
    /**
501
     * @group DBAL-241
502
     */
503
    public function testFetchAllStyleColumn()
504
    {
505
        $sql = "DELETE FROM fetch_table";
506
        $this->_conn->executeUpdate($sql);
507
508
        $this->_conn->insert('fetch_table', array('test_int' => 1, 'test_string' => 'foo'));
509
        $this->_conn->insert('fetch_table', array('test_int' => 10, 'test_string' => 'foo'));
510
        $this->refresh("fetch_table");
511
512
        $sql = "SELECT test_int FROM fetch_table ORDER BY test_int ASC";
513
        $rows = $this->_conn->query($sql)->fetchAll(\PDO::FETCH_COLUMN);
514
515
        $this->assertEquals(array(1, 10), $rows);
516
    }
517
518
    /**
519
     * @group DBAL-214
520
     */
521
    public function testSetFetchModeClassFetchAll()
522
    {
523
        $this->markTestSkipped("PDO::FETCH_CLASS not supported crate PDO");
524
        $this->setupFixture();
525
526
        $sql = "SELECT * FROM fetch_table";
527
        $stmt = $this->_conn->query($sql);
528
        $stmt->setFetchMode(\PDO::FETCH_CLASS, __NAMESPACE__ . '\\MyFetchClass', array());
529
530
        $results = $stmt->fetchAll();
531
532
        $this->assertEquals(1, count($results));
533
        $this->assertInstanceOf(__NAMESPACE__.'\\MyFetchClass', $results[0]);
534
535
        $this->assertEquals(1, $results[0]->test_int);
536
        $this->assertEquals('foo', $results[0]->test_string);
537
        $this->assertStringStartsWith('2010-01-01T10:10:10', $results[0]->test_datetime);
538
    }
539
540
    /**
541
     * @group DBAL-214
542
     */
543
    public function testSetFetchModeClassFetch()
544
    {
545
        $this->markTestSkipped("PDO::FETCH_CLASS not supported by crate PDO");
546
547
        $this->setupFixture();
548
549
        $sql = "SELECT * FROM fetch_table";
550
        $stmt = $this->_conn->query($sql);
551
        $stmt->setFetchMode(\PDO::FETCH_CLASS, __NAMESPACE__ . '\\MyFetchClass', array());
552
553
        $results = array();
554
        while ($row = $stmt->fetch()) {
555
            $results[] = $row;
556
        }
557
558
        $this->assertEquals(1, count($results));
559
        $this->assertInstanceOf(__NAMESPACE__.'\\MyFetchClass', $results[0]);
560
561
        $this->assertEquals(1, $results[0]->test_int);
562
        $this->assertEquals('foo', $results[0]->test_string);
563
        $this->assertStringStartsWith('2010-01-01T10:10:10', $results[0]->test_datetime);
564
    }
565
566
    /**
567
     * @group DBAL-257
568
     */
569
    public function testEmptyFetchColumnReturnsFalse()
570
    {
571
        $this->_conn->executeQuery('DELETE FROM fetch_table')->execute();
572
        $this->refresh("fetch_table");
573
        $this->assertFalse($this->_conn->fetchColumn('SELECT test_int FROM fetch_table'));
574
        $this->assertFalse($this->_conn->query('SELECT test_int FROM fetch_table')->fetchColumn());
575
    }
576
577
    /**
578
     * @group DBAL-339
579
     */
580
    public function testSetFetchModeOnDbalStatement()
581
    {
582
        $sql = "SELECT test_int, test_string FROM fetch_table WHERE test_int = ? AND test_string = ?";
583
        $stmt = $this->_conn->executeQuery($sql, array(1, "foo"));
584
        $stmt->setFetchMode(\PDO::FETCH_NUM);
585
586
        while ($row = $stmt->fetch()) {
587
            $this->assertTrue(isset($row[0]));
588
            $this->assertTrue(isset($row[1]));
589
        }
590
    }
591
592
    private function setupFixture()
593
    {
594
        $this->_conn->executeQuery('DELETE FROM fetch_table')->execute();
595
        $this->_conn->insert('fetch_table', array(
596
            'test_int'      => 1,
597
            'test_string'   => 'foo',
598
            'test_datetime' => '2010-01-01T10:10:10'
599
        ));
600
    }
601
602
}
603