Failed Conditions
Pull Request — develop (#3348)
by Sergei
60:53
created

ConnectionTest::testFetchColumn()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 35
Code Lines 24

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 24
dl 0
loc 35
rs 9.536
c 0
b 0
f 0
cc 1
nc 1
nop 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Doctrine\Tests\DBAL;
6
7
use Doctrine\Common\Cache\Cache;
8
use Doctrine\Common\EventManager;
9
use Doctrine\DBAL\Cache\ArrayStatement;
10
use Doctrine\DBAL\Cache\QueryCacheProfile;
11
use Doctrine\DBAL\Configuration;
12
use Doctrine\DBAL\Connection;
13
use Doctrine\DBAL\ConnectionException;
14
use Doctrine\DBAL\DBALException;
15
use Doctrine\DBAL\Driver;
16
use Doctrine\DBAL\Driver\Connection as DriverConnection;
17
use Doctrine\DBAL\DriverManager;
18
use Doctrine\DBAL\Events;
19
use Doctrine\DBAL\Exception\InvalidArgumentException;
20
use Doctrine\DBAL\FetchMode;
21
use Doctrine\DBAL\Logging\DebugStack;
22
use Doctrine\DBAL\Logging\EchoSQLLogger;
23
use Doctrine\DBAL\ParameterType;
24
use Doctrine\DBAL\Platforms\AbstractPlatform;
25
use Doctrine\Tests\DbalTestCase;
26
use Doctrine\Tests\Mocks\DriverStatementMock;
27
use Doctrine\Tests\Mocks\ServerInfoAwareConnectionMock;
28
use Doctrine\Tests\Mocks\VersionAwarePlatformDriverMock;
29
use Exception;
30
use PHPUnit\Framework\MockObject\MockObject;
31
use stdClass;
32
33
/**
34
 * @requires extension pdo_mysql
35
 */
36
class ConnectionTest extends DbalTestCase
37
{
38
    /** @var Connection */
39
    private $connection;
40
41
    /** @var string[] */
42
    protected $params = [
43
        'driver' => 'pdo_mysql',
44
        'host' => 'localhost',
45
        'user' => 'root',
46
        'password' => 'password',
47
        'port' => 1234,
48
    ];
49
50
    protected function setUp() : void
51
    {
52
        $this->connection = DriverManager::getConnection($this->params);
53
    }
54
55
    /**
56
     * @return Connection|MockObject
57
     */
58
    private function getExecuteUpdateMockConnection()
59
    {
60
        $driverMock = $this->createMock(Driver::class);
61
62
        $driverMock->expects($this->any())
63
            ->method('connect')
64
            ->will($this->returnValue(
65
                $this->createMock(DriverConnection::class)
66
            ));
67
68
        $platform = $this->getMockForAbstractClass(AbstractPlatform::class);
69
70
        return $this->getMockBuilder(Connection::class)
71
            ->setMethods(['executeUpdate'])
72
            ->setConstructorArgs([['platform' => $platform], $driverMock])
73
            ->getMock();
74
    }
75
76
    public function testIsConnected() : void
77
    {
78
        self::assertFalse($this->connection->isConnected());
79
    }
80
81
    public function testNoTransactionActiveByDefault() : void
82
    {
83
        self::assertFalse($this->connection->isTransactionActive());
84
    }
85
86
    public function testCommitWithNoActiveTransactionThrowsException() : void
87
    {
88
        $this->expectException(ConnectionException::class);
89
        $this->connection->commit();
90
    }
91
92
    public function testRollbackWithNoActiveTransactionThrowsException() : void
93
    {
94
        $this->expectException(ConnectionException::class);
95
        $this->connection->rollBack();
96
    }
97
98
    public function testSetRollbackOnlyNoActiveTransactionThrowsException() : void
99
    {
100
        $this->expectException(ConnectionException::class);
101
        $this->connection->setRollbackOnly();
102
    }
103
104
    public function testIsRollbackOnlyNoActiveTransactionThrowsException() : void
105
    {
106
        $this->expectException(ConnectionException::class);
107
        $this->connection->isRollbackOnly();
108
    }
109
110
    public function testGetConfiguration() : void
111
    {
112
        $config = $this->connection->getConfiguration();
113
114
        self::assertInstanceOf(Configuration::class, $config);
115
    }
116
117
    public function testGetDriver() : void
118
    {
119
        self::assertInstanceOf(\Doctrine\DBAL\Driver\PDOMySql\Driver::class, $this->connection->getDriver());
120
    }
121
122
    public function testGetEventManager() : void
123
    {
124
        self::assertInstanceOf(EventManager::class, $this->connection->getEventManager());
125
    }
126
127
    public function testConnectDispatchEvent() : void
128
    {
129
        $listenerMock = $this->getMockBuilder('ConnectDispatchEventListener')
130
            ->setMethods(['postConnect'])
131
            ->getMock();
132
        $listenerMock->expects($this->once())->method('postConnect');
133
134
        $eventManager = new EventManager();
135
        $eventManager->addEventListener([Events::postConnect], $listenerMock);
136
137
        $driverMock = $this->createMock(Driver::class);
138
        $driverMock->expects($this->at(0))
139
                   ->method('connect');
140
141
        $conn = new Connection([], $driverMock, new Configuration(), $eventManager);
142
        $conn->connect();
143
    }
144
145
    public function testEventManagerPassedToPlatform() : void
146
    {
147
        $eventManager = new EventManager();
148
149
        /** @var AbstractPlatform|MockObject $driver */
150
        $platform = $this->createMock(AbstractPlatform::class);
151
        $platform->expects($this->once())
152
            ->method('setEventManager')
153
            ->with($eventManager);
154
155
        /** @var Driver|MockObject $driver */
156
        $driver = $this->createMock(Driver::class);
157
        $driver->expects($this->any())
158
            ->method('getDatabasePlatform')
159
            ->willReturn($platform);
160
161
        $connection = new Connection($this->params, $driver, null, $eventManager);
162
        $connection->getDatabasePlatform();
163
    }
164
165
    /**
166
     * @requires extension pdo_sqlite
167
     * @dataProvider getQueryMethods
168
     */
169
    public function testDriverExceptionIsWrapped(string $method) : void
170
    {
171
        $this->expectException(DBALException::class);
172
        $this->expectExceptionMessage("An exception occurred while executing \"MUUHAAAAHAAAA\":\n\nSQLSTATE[HY000]: General error: 1 near \"MUUHAAAAHAAAA\"");
173
174
        $connection = DriverManager::getConnection([
175
            'driver' => 'pdo_sqlite',
176
            'memory' => true,
177
        ]);
178
179
        $connection->$method('MUUHAAAAHAAAA');
180
    }
181
182
    /**
183
     * @return mixed[][]
184
     */
185
    public static function getQueryMethods() : iterable
186
    {
187
        return [
188
            ['exec'],
189
            ['query'],
190
            ['executeQuery'],
191
            ['executeUpdate'],
192
            ['prepare'],
193
        ];
194
    }
195
196
    /**
197
     * Pretty dumb test, however we want to check that the EchoSQLLogger correctly implements the interface.
198
     *
199
     * @group DBAL-11
200
     */
201
    public function testEchoSQLLogger() : void
202
    {
203
        $logger = new EchoSQLLogger();
204
        $this->connection->getConfiguration()->setSQLLogger($logger);
205
        self::assertSame($logger, $this->connection->getConfiguration()->getSQLLogger());
206
    }
207
208
    /**
209
     * Pretty dumb test, however we want to check that the DebugStack correctly implements the interface.
210
     *
211
     * @group DBAL-11
212
     */
213
    public function testDebugSQLStack() : void
214
    {
215
        $logger = new DebugStack();
216
        $this->connection->getConfiguration()->setSQLLogger($logger);
217
        self::assertSame($logger, $this->connection->getConfiguration()->getSQLLogger());
218
    }
219
220
    /**
221
     * @group DBAL-81
222
     */
223
    public function testIsAutoCommit() : void
224
    {
225
        self::assertTrue($this->connection->isAutoCommit());
226
    }
227
228
    /**
229
     * @group DBAL-81
230
     */
231
    public function testSetAutoCommit() : void
232
    {
233
        $this->connection->setAutoCommit(false);
234
        self::assertFalse($this->connection->isAutoCommit());
235
    }
236
237
    /**
238
     * @group DBAL-81
239
     */
240
    public function testConnectStartsTransactionInNoAutoCommitMode() : void
241
    {
242
        $driverMock = $this->createMock(Driver::class);
243
        $driverMock->expects($this->any())
244
            ->method('connect')
245
            ->will($this->returnValue(
246
                $this->createMock(DriverConnection::class)
247
            ));
248
        $conn = new Connection([], $driverMock);
249
250
        $conn->setAutoCommit(false);
251
252
        self::assertFalse($conn->isTransactionActive());
253
254
        $conn->connect();
255
256
        self::assertTrue($conn->isTransactionActive());
257
    }
258
259
    /**
260
     * @group DBAL-81
261
     */
262
    public function testCommitStartsTransactionInNoAutoCommitMode() : void
263
    {
264
        $driverMock = $this->createMock(Driver::class);
265
        $driverMock->expects($this->any())
266
            ->method('connect')
267
            ->will($this->returnValue(
268
                $this->createMock(DriverConnection::class)
269
            ));
270
        $conn = new Connection([], $driverMock);
271
272
        $conn->setAutoCommit(false);
273
        $conn->connect();
274
        $conn->commit();
275
276
        self::assertTrue($conn->isTransactionActive());
277
    }
278
279
    /**
280
     * @group DBAL-81
281
     */
282
    public function testRollBackStartsTransactionInNoAutoCommitMode() : void
283
    {
284
        $driverMock = $this->createMock(Driver::class);
285
        $driverMock->expects($this->any())
286
            ->method('connect')
287
            ->will($this->returnValue(
288
                $this->createMock(DriverConnection::class)
289
            ));
290
        $conn = new Connection([], $driverMock);
291
292
        $conn->setAutoCommit(false);
293
        $conn->connect();
294
        $conn->rollBack();
295
296
        self::assertTrue($conn->isTransactionActive());
297
    }
298
299
    /**
300
     * @group DBAL-81
301
     */
302
    public function testSwitchingAutoCommitModeCommitsAllCurrentTransactions() : void
303
    {
304
        $driverMock = $this->createMock(Driver::class);
305
        $driverMock->expects($this->any())
306
            ->method('connect')
307
            ->will($this->returnValue(
308
                $this->createMock(DriverConnection::class)
309
            ));
310
        $conn = new Connection([], $driverMock);
311
312
        $conn->connect();
313
        $conn->beginTransaction();
314
        $conn->beginTransaction();
315
        $conn->setAutoCommit(false);
316
317
        self::assertSame(1, $conn->getTransactionNestingLevel());
318
319
        $conn->beginTransaction();
320
        $conn->beginTransaction();
321
        $conn->setAutoCommit(true);
322
323
        self::assertFalse($conn->isTransactionActive());
324
    }
325
326
    public function testEmptyInsert() : void
327
    {
328
        $conn = $this->getExecuteUpdateMockConnection();
329
330
        $conn->expects($this->once())
331
            ->method('executeUpdate')
332
            ->with('INSERT INTO footable () VALUES ()');
333
334
        $conn->insert('footable', []);
335
    }
336
337
    /**
338
     * @group DBAL-2511
339
     */
340
    public function testUpdateWithDifferentColumnsInDataAndIdentifiers() : void
341
    {
342
        $conn = $this->getExecuteUpdateMockConnection();
343
344
        $conn->expects($this->once())
345
            ->method('executeUpdate')
346
            ->with(
347
                'UPDATE TestTable SET text = ?, is_edited = ? WHERE id = ? AND name = ?',
348
                [
349
                    'some text',
350
                    true,
351
                    1,
352
                    'foo',
353
                ],
354
                [
355
                    'string',
356
                    'boolean',
357
                    'integer',
358
                    'string',
359
                ]
360
            );
361
362
        $conn->update(
363
            'TestTable',
364
            [
365
                'text' => 'some text',
366
                'is_edited' => true,
367
            ],
368
            [
369
                'id' => 1,
370
                'name' => 'foo',
371
            ],
372
            [
373
                'text' => 'string',
374
                'is_edited' => 'boolean',
375
                'id' => 'integer',
376
                'name' => 'string',
377
            ]
378
        );
379
    }
380
381
    /**
382
     * @group DBAL-2511
383
     */
384
    public function testUpdateWithSameColumnInDataAndIdentifiers() : void
385
    {
386
        $conn = $this->getExecuteUpdateMockConnection();
387
388
        $conn->expects($this->once())
389
            ->method('executeUpdate')
390
            ->with(
391
                'UPDATE TestTable SET text = ?, is_edited = ? WHERE id = ? AND is_edited = ?',
392
                [
393
                    'some text',
394
                    true,
395
                    1,
396
                    false,
397
                ],
398
                [
399
                    'string',
400
                    'boolean',
401
                    'integer',
402
                    'boolean',
403
                ]
404
            );
405
406
        $conn->update(
407
            'TestTable',
408
            [
409
                'text' => 'some text',
410
                'is_edited' => true,
411
            ],
412
            [
413
                'id' => 1,
414
                'is_edited' => false,
415
            ],
416
            [
417
                'text' => 'string',
418
                'is_edited' => 'boolean',
419
                'id' => 'integer',
420
            ]
421
        );
422
    }
423
424
    /**
425
     * @group DBAL-2688
426
     */
427
    public function testUpdateWithIsNull() : void
428
    {
429
        $conn = $this->getExecuteUpdateMockConnection();
430
431
        $conn->expects($this->once())
432
            ->method('executeUpdate')
433
            ->with(
434
                'UPDATE TestTable SET text = ?, is_edited = ? WHERE id IS NULL AND name = ?',
435
                [
436
                    'some text',
437
                    null,
438
                    'foo',
439
                ],
440
                [
441
                    'string',
442
                    'boolean',
443
                    'string',
444
                ]
445
            );
446
447
        $conn->update(
448
            'TestTable',
449
            [
450
                'text' => 'some text',
451
                'is_edited' => null,
452
            ],
453
            [
454
                'id' => null,
455
                'name' => 'foo',
456
            ],
457
            [
458
                'text' => 'string',
459
                'is_edited' => 'boolean',
460
                'id' => 'integer',
461
                'name' => 'string',
462
            ]
463
        );
464
    }
465
466
    /**
467
     * @group DBAL-2688
468
     */
469
    public function testDeleteWithIsNull() : void
470
    {
471
        $conn = $this->getExecuteUpdateMockConnection();
472
473
        $conn->expects($this->once())
474
            ->method('executeUpdate')
475
            ->with(
476
                'DELETE FROM TestTable WHERE id IS NULL AND name = ?',
477
                ['foo'],
478
                ['string']
479
            );
480
481
        $conn->delete(
482
            'TestTable',
483
            [
484
                'id' => null,
485
                'name' => 'foo',
486
            ],
487
            [
488
                'id' => 'integer',
489
                'name' => 'string',
490
            ]
491
        );
492
    }
493
494
    public function testFetchAssoc() : void
495
    {
496
        $statement = 'SELECT * FROM foo WHERE bar = ?';
497
        $params    = [666];
498
        $types     = [ParameterType::INTEGER];
499
        $result    = [];
500
501
        $driverMock = $this->createMock(Driver::class);
502
503
        $driverMock->expects($this->any())
504
            ->method('connect')
505
            ->will($this->returnValue(
506
                $this->createMock(DriverConnection::class)
507
            ));
508
509
        $driverStatementMock = $this->createMock(DriverStatementMock::class);
510
511
        $driverStatementMock->expects($this->once())
512
            ->method('fetch')
513
            ->with(FetchMode::ASSOCIATIVE)
514
            ->will($this->returnValue($result));
515
516
        /** @var Connection|MockObject $conn */
517
        $conn = $this->getMockBuilder(Connection::class)
518
            ->setMethods(['executeQuery'])
519
            ->setConstructorArgs([[], $driverMock])
520
            ->getMock();
521
522
        $conn->expects($this->once())
523
            ->method('executeQuery')
524
            ->with($statement, $params, $types)
525
            ->will($this->returnValue($driverStatementMock));
526
527
        self::assertSame($result, $conn->fetchAssoc($statement, $params, $types));
528
    }
529
530
    public function testFetchArray() : void
531
    {
532
        $statement = 'SELECT * FROM foo WHERE bar = ?';
533
        $params    = [666];
534
        $types     = [ParameterType::INTEGER];
535
        $result    = [];
536
537
        $driverMock = $this->createMock(Driver::class);
538
539
        $driverMock->expects($this->any())
540
            ->method('connect')
541
            ->will($this->returnValue(
542
                $this->createMock(DriverConnection::class)
543
            ));
544
545
        $driverStatementMock = $this->createMock(DriverStatementMock::class);
546
547
        $driverStatementMock->expects($this->once())
548
            ->method('fetch')
549
            ->with(FetchMode::NUMERIC)
550
            ->will($this->returnValue($result));
551
552
        /** @var Connection|MockObject $conn */
553
        $conn = $this->getMockBuilder(Connection::class)
554
            ->setMethods(['executeQuery'])
555
            ->setConstructorArgs([[], $driverMock])
556
            ->getMock();
557
558
        $conn->expects($this->once())
559
            ->method('executeQuery')
560
            ->with($statement, $params, $types)
561
            ->will($this->returnValue($driverStatementMock));
562
563
        self::assertSame($result, $conn->fetchArray($statement, $params, $types));
564
    }
565
566
    public function testFetchColumn() : void
567
    {
568
        $statement = 'SELECT * FROM foo WHERE bar = ?';
569
        $params    = [666];
570
        $types     = [ParameterType::INTEGER];
571
        $column    = 0;
572
        $result    = [];
573
574
        $driverMock = $this->createMock(Driver::class);
575
576
        $driverMock->expects($this->any())
577
            ->method('connect')
578
            ->will($this->returnValue(
579
                $this->createMock(DriverConnection::class)
580
            ));
581
582
        $driverStatementMock = $this->createMock(DriverStatementMock::class);
583
584
        $driverStatementMock->expects($this->once())
585
            ->method('fetchColumn')
586
            ->with($column)
587
            ->will($this->returnValue($result));
588
589
        /** @var Connection|MockObject $conn */
590
        $conn = $this->getMockBuilder(Connection::class)
591
            ->setMethods(['executeQuery'])
592
            ->setConstructorArgs([[], $driverMock])
593
            ->getMock();
594
595
        $conn->expects($this->once())
596
            ->method('executeQuery')
597
            ->with($statement, $params, $types)
598
            ->will($this->returnValue($driverStatementMock));
599
600
        self::assertSame($result, $conn->fetchColumn($statement, $params, $column, $types));
601
    }
602
603
    public function testFetchAll() : void
604
    {
605
        $statement = 'SELECT * FROM foo WHERE bar = ?';
606
        $params    = [666];
607
        $types     = [ParameterType::INTEGER];
608
        $result    = [];
609
610
        $driverMock = $this->createMock(Driver::class);
611
612
        $driverMock->expects($this->any())
613
            ->method('connect')
614
            ->will($this->returnValue(
615
                $this->createMock(DriverConnection::class)
616
            ));
617
618
        $driverStatementMock = $this->createMock(DriverStatementMock::class);
619
620
        $driverStatementMock->expects($this->once())
621
            ->method('fetchAll')
622
            ->will($this->returnValue($result));
623
624
        /** @var Connection|MockObject $conn */
625
        $conn = $this->getMockBuilder(Connection::class)
626
            ->setMethods(['executeQuery'])
627
            ->setConstructorArgs([[], $driverMock])
628
            ->getMock();
629
630
        $conn->expects($this->once())
631
            ->method('executeQuery')
632
            ->with($statement, $params, $types)
633
            ->will($this->returnValue($driverStatementMock));
634
635
        self::assertSame($result, $conn->fetchAll($statement, $params, $types));
636
    }
637
638
    public function testCallingDeleteWithNoDeletionCriteriaResultsInInvalidArgumentException() : void
639
    {
640
        /** @var Driver $driver */
641
        $driver = $this->createMock(Driver::class);
642
        $conn   = new Connection([], $driver);
643
644
        $this->expectException(InvalidArgumentException::class);
645
        $conn->delete('kittens', []);
646
    }
647
648
    public function testCallConnectOnce() : void
649
    {
650
        /** @var Driver|MockObject $driver */
651
        $driver = $this->createMock(Driver::class);
652
        $driver->expects($this->once())
653
            ->method('connect');
654
655
        $platform = $this->createMock(AbstractPlatform::class);
656
657
        $conn = new Connection(['platform' => $platform], $driver);
658
        $conn->connect();
659
        $conn->connect();
660
    }
661
662
    /**
663
     * @group DBAL-1127
664
     */
665
    public function testPlatformDetectionIsTriggerOnlyOnceOnRetrievingPlatform() : void
666
    {
667
        /** @var VersionAwarePlatformDriverMock|MockObject $driverMock */
668
        $driverMock = $this->createMock(VersionAwarePlatformDriverMock::class);
669
670
        /** @var ServerInfoAwareConnectionMock|MockObject $driverConnectionMock */
671
        $driverConnectionMock = $this->createMock(ServerInfoAwareConnectionMock::class);
672
673
        /** @var AbstractPlatform|MockObject $platformMock */
674
        $platformMock = $this->getMockForAbstractClass(AbstractPlatform::class);
675
676
        $connection = new Connection([], $driverMock);
677
678
        $driverMock->expects($this->once())
679
            ->method('connect')
680
            ->will($this->returnValue($driverConnectionMock));
681
682
        $driverConnectionMock->expects($this->once())
683
            ->method('requiresQueryForServerVersion')
684
            ->will($this->returnValue(false));
685
686
        $driverConnectionMock->expects($this->once())
687
            ->method('getServerVersion')
688
            ->will($this->returnValue('6.6.6'));
689
690
        $driverMock->expects($this->once())
691
            ->method('createDatabasePlatformForVersion')
692
            ->with('6.6.6')
693
            ->will($this->returnValue($platformMock));
694
695
        self::assertSame($platformMock, $connection->getDatabasePlatform());
696
    }
697
698
    public function testConnectionParamsArePassedToTheQueryCacheProfileInExecuteCacheQuery() : void
699
    {
700
        $resultCacheDriverMock = $this->createMock(Cache::class);
701
702
        $resultCacheDriverMock
703
            ->expects($this->atLeastOnce())
704
            ->method('fetch')
705
            ->with('cacheKey')
706
            ->will($this->returnValue(['realKey' => []]));
707
708
        $query  = 'SELECT * FROM foo WHERE bar = ?';
709
        $params = [666];
710
        $types  = [ParameterType::INTEGER];
711
712
        /** @var QueryCacheProfile|MockObject $queryCacheProfileMock */
713
        $queryCacheProfileMock = $this->createMock(QueryCacheProfile::class);
714
715
        $queryCacheProfileMock
716
            ->expects($this->any())
717
            ->method('getResultCacheDriver')
718
            ->will($this->returnValue($resultCacheDriverMock));
719
720
        // This is our main expectation
721
        $queryCacheProfileMock
722
            ->expects($this->once())
723
            ->method('generateCacheKeys')
724
            ->with($query, $params, $types, $this->params)
725
            ->will($this->returnValue(['cacheKey', 'realKey']));
726
727
        /** @var Driver $driver */
728
        $driver = $this->createMock(Driver::class);
729
730
        self::assertInstanceOf(
731
            ArrayStatement::class,
732
            (new Connection($this->params, $driver))->executeCacheQuery($query, $params, $types, $queryCacheProfileMock)
733
        );
734
    }
735
736
    /**
737
     * @group #2821
738
     */
739
    public function testShouldNotPassPlatformInParamsToTheQueryCacheProfileInExecuteCacheQuery() : void
740
    {
741
        $resultCacheDriverMock = $this->createMock(Cache::class);
742
743
        $resultCacheDriverMock
744
            ->expects($this->atLeastOnce())
745
            ->method('fetch')
746
            ->with('cacheKey')
747
            ->will($this->returnValue(['realKey' => []]));
748
749
        /** @var QueryCacheProfile|MockObject $queryCacheProfileMock */
750
        $queryCacheProfileMock = $this->createMock(QueryCacheProfile::class);
751
752
        $queryCacheProfileMock
753
            ->expects($this->any())
754
            ->method('getResultCacheDriver')
755
            ->will($this->returnValue($resultCacheDriverMock));
756
757
        $query = 'SELECT 1';
758
759
        $connectionParams = $this->params;
760
761
        $queryCacheProfileMock
762
            ->expects($this->once())
763
            ->method('generateCacheKeys')
764
            ->with($query, [], [], $connectionParams)
765
            ->will($this->returnValue(['cacheKey', 'realKey']));
766
767
        $connectionParams['platform'] = $this->createMock(AbstractPlatform::class);
768
769
        /** @var Driver $driver */
770
        $driver = $this->createMock(Driver::class);
771
772
        (new Connection($connectionParams, $driver))->executeCacheQuery($query, [], [], $queryCacheProfileMock);
773
    }
774
775
    /**
776
     * @group #2821
777
     */
778
    public function testThrowsExceptionWhenInValidPlatformSpecified() : void
779
    {
780
        $connectionParams             = $this->params;
781
        $connectionParams['platform'] = new stdClass();
782
783
        /** @var Driver $driver */
784
        $driver = $this->createMock(Driver::class);
785
786
        $this->expectException(DBALException::class);
787
788
        new Connection($connectionParams, $driver);
789
    }
790
791
    /**
792
     * @group DBAL-990
793
     */
794
    public function testRethrowsOriginalExceptionOnDeterminingPlatformWhenConnectingToNonExistentDatabase() : void
795
    {
796
        /** @var VersionAwarePlatformDriverMock|MockObject $driverMock */
797
        $driverMock = $this->createMock(VersionAwarePlatformDriverMock::class);
798
799
        $connection        = new Connection(['dbname' => 'foo'], $driverMock);
800
        $originalException = new Exception('Original exception');
801
        $fallbackException = new Exception('Fallback exception');
802
803
        $driverMock->expects($this->at(0))
804
            ->method('connect')
805
            ->willThrowException($originalException);
806
807
        $driverMock->expects($this->at(1))
808
            ->method('connect')
809
            ->willThrowException($fallbackException);
810
811
        $this->expectExceptionMessage($originalException->getMessage());
812
813
        $connection->getDatabasePlatform();
814
    }
815
816
    /**
817
     * @group #3194
818
     */
819
    public function testExecuteCacheQueryStripsPlatformFromConnectionParamsBeforeGeneratingCacheKeys() : void
820
    {
821
        /** @var Driver|MockObject $driver */
822
        $driver = $this->createMock(Driver::class);
823
824
        /** @var AbstractPlatform|MockObject $platform */
825
        $platform = $this->createMock(AbstractPlatform::class);
826
827
        /** @var QueryCacheProfile|MockObject $queryCacheProfile */
828
        $queryCacheProfile = $this->createMock(QueryCacheProfile::class);
829
830
        /** @var Cache|MockObject $resultCacheDriver */
831
        $resultCacheDriver = $this->createMock(Cache::class);
832
833
        $queryCacheProfile
834
            ->expects($this->any())
835
            ->method('getResultCacheDriver')
836
            ->will($this->returnValue($resultCacheDriver));
837
838
        $resultCacheDriver
839
            ->expects($this->atLeastOnce())
840
            ->method('fetch')
841
            ->with('cacheKey')
842
            ->will($this->returnValue(['realKey' => []]));
843
844
        $query = 'SELECT 1';
845
846
        $params = [
847
            'dbname' => 'foo',
848
            'platform' => $platform,
849
        ];
850
851
        $paramsWithoutPlatform = $params;
852
        unset($paramsWithoutPlatform['platform']);
853
854
        $queryCacheProfile
855
            ->expects($this->once())
856
            ->method('generateCacheKeys')
857
            ->with($query, [], [], $paramsWithoutPlatform)
858
            ->will($this->returnValue(['cacheKey', 'realKey']));
859
860
        $connection = new Connection($params, $driver);
861
862
        self::assertSame($params, $connection->getParams());
863
864
        $connection->executeCacheQuery($query, [], [], $queryCacheProfile);
865
    }
866
}
867