Completed
Push — develop ( c7cb25...56c936 )
by Sergei
20s queued 14s
created

OMeansConnectionIsConnected()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 9
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

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