Failed Conditions
Push — develop ( 03730f...4e0a6e )
by Sergei
112:33 queued 47:35
created

ConnectionTest::testDeleteWithIsNull()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 21
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

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