Failed Conditions
Push — master ( 7bbed5...cf98cc )
by Sergei
84:08 queued 81:00
created

DriverManagerTest::testDatabaseUrlShard()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 34
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 21
dl 0
loc 34
rs 9.584
c 0
b 0
f 0
cc 2
nc 2
nop 0
1
<?php
2
3
namespace Doctrine\Tests\DBAL;
4
5
use Doctrine\DBAL\Connections\MasterSlaveConnection;
6
use Doctrine\DBAL\DBALException;
7
use Doctrine\DBAL\Driver\DrizzlePDOMySql\Driver as DrizzlePDOMySqlDriver;
8
use Doctrine\DBAL\Driver\PDOMySql\Driver as PDOMySQLDriver;
9
use Doctrine\DBAL\Driver\PDOSqlite\Driver as PDOSqliteDriver;
10
use Doctrine\DBAL\Driver\SQLSrv\Driver as SQLSrvDriver;
11
use Doctrine\DBAL\DriverManager;
12
use Doctrine\DBAL\Sharding\PoolingShardConnection;
13
use Doctrine\DBAL\Sharding\ShardChoser\MultiTenantShardChoser;
14
use Doctrine\Tests\DBAL\Mocks\MockPlatform;
15
use Doctrine\Tests\DbalTestCase;
16
use Doctrine\Tests\Mocks\ConnectionMock;
17
use Doctrine\Tests\Mocks\DriverMock;
18
use stdClass;
19
use function extension_loaded;
20
use function in_array;
21
use function is_array;
22
23
class DriverManagerTest extends DbalTestCase
24
{
25
    /**
26
     * @requires extension pdo_sqlite
27
     * @expectedException \Doctrine\DBAL\DBALException
28
     */
29
    public function testInvalidPdoInstance()
30
    {
31
        DriverManager::getConnection(['pdo' => 'test']);
32
    }
33
34
    /**
35
     * @requires extension pdo_sqlite
36
     */
37
    public function testValidPdoInstance()
38
    {
39
        $conn = DriverManager::getConnection([
40
            'pdo' => new \PDO('sqlite::memory:'),
41
        ]);
42
43
        self::assertEquals('sqlite', $conn->getDatabasePlatform()->getName());
44
    }
45
46
    /**
47
     * @group DBAL-32
48
     * @requires extension pdo_sqlite
49
     */
50
    public function testPdoInstanceSetErrorMode()
51
    {
52
        $pdo = new \PDO('sqlite::memory:');
53
        $pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_SILENT);
54
        $options = ['pdo' => $pdo];
55
56
        DriverManager::getConnection($options);
57
        self::assertEquals(\PDO::ERRMODE_EXCEPTION, $pdo->getAttribute(\PDO::ATTR_ERRMODE));
58
    }
59
60
    /**
61
     * @expectedException \Doctrine\DBAL\DBALException
62
     */
63
    public function testCheckParams()
64
    {
65
        DriverManager::getConnection([]);
66
    }
67
68
    /**
69
     * @expectedException \Doctrine\DBAL\DBALException
70
     */
71
    public function testInvalidDriver()
72
    {
73
        DriverManager::getConnection(['driver' => 'invalid_driver']);
74
    }
75
76
    /**
77
     * @requires extension pdo_sqlite
78
     */
79
    public function testCustomPlatform()
80
    {
81
        $mockPlatform = new MockPlatform();
82
        $options      = [
83
            'pdo'      => new \PDO('sqlite::memory:'),
84
            'platform' => $mockPlatform,
85
        ];
86
87
        $conn = DriverManager::getConnection($options);
88
        self::assertSame($mockPlatform, $conn->getDatabasePlatform());
89
    }
90
91
    /**
92
     * @requires extension pdo_sqlite
93
     */
94
    public function testCustomWrapper()
95
    {
96
        $wrapperClass = ConnectionMock::class;
97
98
        $options = [
99
            'pdo' => new \PDO('sqlite::memory:'),
100
            'wrapperClass' => $wrapperClass,
101
        ];
102
103
        $conn = DriverManager::getConnection($options);
104
        self::assertInstanceOf($wrapperClass, $conn);
105
    }
106
107
    /**
108
     * @requires extension pdo_sqlite
109
     */
110
    public function testInvalidWrapperClass()
111
    {
112
        $this->expectException(DBALException::class);
113
114
        $options = [
115
            'pdo' => new \PDO('sqlite::memory:'),
116
            'wrapperClass' => stdClass::class,
117
        ];
118
119
        DriverManager::getConnection($options);
120
    }
121
122
    public function testInvalidDriverClass()
123
    {
124
        $this->expectException(DBALException::class);
125
126
        $options = ['driverClass' => stdClass::class];
127
128
        DriverManager::getConnection($options);
129
    }
130
131
    public function testValidDriverClass()
132
    {
133
        $options = ['driverClass' => PDOMySQLDriver::class];
134
135
        $conn = DriverManager::getConnection($options);
136
        self::assertInstanceOf(PDOMySQLDriver::class, $conn->getDriver());
137
    }
138
139
    public function testDatabaseUrlMasterSlave()
140
    {
141
        $options = [
142
            'driver' => 'pdo_mysql',
143
            'master' => ['url' => 'mysql://foo:bar@localhost:11211/baz'],
144
            'slaves' => [
145
                'slave1' => ['url' => 'mysql://foo:bar@localhost:11211/baz_slave'],
146
            ],
147
            'wrapperClass' => MasterSlaveConnection::class,
148
        ];
149
150
        $conn = DriverManager::getConnection($options);
151
152
        $params = $conn->getParams();
153
        self::assertInstanceOf(PDOMySQLDriver::class, $conn->getDriver());
154
155
        $expected = [
156
            'user'     => 'foo',
157
            'password' => 'bar',
158
            'host'     => 'localhost',
159
            'port'     => 11211,
160
        ];
161
162
        foreach ($expected as $key => $value) {
163
            self::assertEquals($value, $params['master'][$key]);
164
            self::assertEquals($value, $params['slaves']['slave1'][$key]);
165
        }
166
167
        self::assertEquals('baz', $params['master']['dbname']);
168
        self::assertEquals('baz_slave', $params['slaves']['slave1']['dbname']);
169
    }
170
171
    public function testDatabaseUrlShard()
172
    {
173
        $options = [
174
            'driver' => 'pdo_mysql',
175
            'shardChoser' => MultiTenantShardChoser::class,
176
            'global' => ['url' => 'mysql://foo:bar@localhost:11211/baz'],
177
            'shards' => [
178
                [
179
                    'id' => 1,
180
                    'url' => 'mysql://foo:bar@localhost:11211/baz_slave',
181
                ],
182
            ],
183
            'wrapperClass' => PoolingShardConnection::class,
184
        ];
185
186
        $conn = DriverManager::getConnection($options);
187
188
        $params = $conn->getParams();
189
        self::assertInstanceOf(PDOMySQLDriver::class, $conn->getDriver());
190
191
        $expected = [
192
            'user'     => 'foo',
193
            'password' => 'bar',
194
            'host'     => 'localhost',
195
            'port'     => 11211,
196
        ];
197
198
        foreach ($expected as $key => $value) {
199
            self::assertEquals($value, $params['global'][$key]);
200
            self::assertEquals($value, $params['shards'][0][$key]);
201
        }
202
203
        self::assertEquals('baz', $params['global']['dbname']);
204
        self::assertEquals('baz_slave', $params['shards'][0]['dbname']);
205
    }
206
207
    /**
208
     * @dataProvider databaseUrls
209
     */
210
    public function testDatabaseUrl($url, $expected)
211
    {
212
        $options = is_array($url) ? $url : ['url' => $url];
213
214
        if (isset($options['pdo'])) {
215
            if (! extension_loaded('pdo')) {
216
                $this->markTestSkipped('PDO is not installed');
217
            }
218
219
            $options['pdo'] = $this->createMock(\PDO::class);
220
        }
221
222
        $options = is_array($url) ? $url : ['url' => $url];
223
224
        if ($expected === false) {
225
            $this->expectException(DBALException::class);
226
        }
227
228
        $conn = DriverManager::getConnection($options);
229
230
        $params = $conn->getParams();
231
        foreach ($expected as $key => $value) {
232
            if (in_array($key, ['pdo', 'driver', 'driverClass'], true)) {
233
                self::assertInstanceOf($value, $conn->getDriver());
234
            } else {
235
                self::assertEquals($value, $params[$key]);
236
            }
237
        }
238
    }
239
240
    public function databaseUrls()
241
    {
242
        return [
243
            'simple URL' => [
244
                'mysql://foo:bar@localhost/baz',
245
                [
246
                    'user'     => 'foo',
247
                    'password' => 'bar',
248
                    'host'     => 'localhost',
249
                    'dbname'   => 'baz',
250
                    'driver'   => PDOMySQLDriver::class,
251
                ],
252
            ],
253
            'simple URL with port' => [
254
                'mysql://foo:bar@localhost:11211/baz',
255
                [
256
                    'user'     => 'foo',
257
                    'password' => 'bar',
258
                    'host'     => 'localhost',
259
                    'port'     => 11211,
260
                    'dbname'   => 'baz',
261
                    'driver'   => PDOMySQLDriver::class,
262
                ],
263
            ],
264
            'sqlite relative URL with host' => [
265
                'sqlite://localhost/foo/dbname.sqlite',
266
                [
267
                    'path'   => 'foo/dbname.sqlite',
268
                    'driver' => PDOSqliteDriver::class,
269
                ],
270
            ],
271
            'sqlite absolute URL with host' => [
272
                'sqlite://localhost//tmp/dbname.sqlite',
273
                [
274
                    'path'   => '/tmp/dbname.sqlite',
275
                    'driver' => PDOSqliteDriver::class,
276
                ],
277
            ],
278
            'sqlite relative URL without host' => [
279
                'sqlite:///foo/dbname.sqlite',
280
                [
281
                    'path'   => 'foo/dbname.sqlite',
282
                    'driver' => PDOSqliteDriver::class,
283
                ],
284
            ],
285
            'sqlite absolute URL without host' => [
286
                'sqlite:////tmp/dbname.sqlite',
287
                [
288
                    'path'   => '/tmp/dbname.sqlite',
289
                    'driver' => PDOSqliteDriver::class,
290
                ],
291
            ],
292
            'sqlite memory' => [
293
                'sqlite:///:memory:',
294
                [
295
                    'memory' => true,
296
                    'driver' => PDOSqliteDriver::class,
297
                ],
298
            ],
299
            'sqlite memory with host' => [
300
                'sqlite://localhost/:memory:',
301
                [
302
                    'memory' => true,
303
                    'driver' => PDOSqliteDriver::class,
304
                ],
305
            ],
306
            'params parsed from URL override individual params' => [
307
                [
308
                    'url'      => 'mysql://foo:bar@localhost/baz',
309
                    'password' => 'lulz',
310
                ],
311
                [
312
                    'user'     => 'foo',
313
                    'password' => 'bar',
314
                    'host'     => 'localhost',
315
                    'dbname'   => 'baz',
316
                    'driver'   => PDOMySQLDriver::class,
317
                ],
318
            ],
319
            'params not parsed from URL but individual params are preserved' => [
320
                [
321
                    'url'  => 'mysql://foo:bar@localhost/baz',
322
                    'port' => 1234,
323
                ],
324
                [
325
                    'user'     => 'foo',
326
                    'password' => 'bar',
327
                    'host'     => 'localhost',
328
                    'port'     => 1234,
329
                    'dbname'   => 'baz',
330
                    'driver'   => PDOMySQLDriver::class,
331
                ],
332
            ],
333
            'query params from URL are used as extra params' => [
334
                'url' => 'mysql://foo:bar@localhost/dbname?charset=UTF-8',
335
                ['charset' => 'UTF-8'],
336
            ],
337
            'simple URL with fallthrough scheme not defined in map' => [
338
                'sqlsrv://foo:bar@localhost/baz',
339
                [
340
                    'user'     => 'foo',
341
                    'password' => 'bar',
342
                    'host'     => 'localhost',
343
                    'dbname'   => 'baz',
344
                    'driver'   => SQLSrvDriver::class,
345
                ],
346
            ],
347
            'simple URL with fallthrough scheme containing underscores fails' => [
348
                'drizzle_pdo_mysql://foo:bar@localhost/baz',
349
                false,
350
            ],
351
            'simple URL with fallthrough scheme containing dashes works' => [
352
                'drizzle-pdo-mysql://foo:bar@localhost/baz',
353
                [
354
                    'user'     => 'foo',
355
                    'password' => 'bar',
356
                    'host'     => 'localhost',
357
                    'dbname'   => 'baz',
358
                    'driver'   => DrizzlePDOMySqlDriver::class,
359
                ],
360
            ],
361
            'simple URL with percent encoding' => [
362
                'mysql://foo%3A:bar%2F@localhost/baz+baz%40',
363
                [
364
                    'user'     => 'foo:',
365
                    'password' => 'bar/',
366
                    'host'     => 'localhost',
367
                    'dbname'   => 'baz+baz@',
368
                    'driver'   => PDOMySQLDriver::class,
369
                ],
370
            ],
371
            'simple URL with percent sign in password' => [
372
                'mysql://foo:bar%25bar@localhost/baz',
373
                [
374
                    'user'     => 'foo',
375
                    'password' => 'bar%bar',
376
                    'host'     => 'localhost',
377
                    'dbname'   => 'baz',
378
                    'driver'   => PDOMySQLDriver::class,
379
                ],
380
            ],
381
382
            // DBAL-1234
383
            'URL without scheme and without any driver information' => [
384
                ['url' => '//foo:bar@localhost/baz'],
385
                false,
386
            ],
387
            'URL without scheme but default PDO driver' => [
388
                [
389
                    'url' => '//foo:bar@localhost/baz',
390
                    'pdo' => true,
391
                ],
392
                false,
393
            ],
394
            'URL without scheme but default driver' => [
395
                [
396
                    'url'    => '//foo:bar@localhost/baz',
397
                    'driver' => 'pdo_mysql',
398
                ],
399
                [
400
                    'user'     => 'foo',
401
                    'password' => 'bar',
402
                    'host'     => 'localhost',
403
                    'dbname'   => 'baz',
404
                    'driver'   => PDOMySQLDriver::class,
405
                ],
406
            ],
407
            'URL without scheme but custom driver' => [
408
                [
409
                    'url'         => '//foo:bar@localhost/baz',
410
                    'driverClass' => DriverMock::class,
411
                ],
412
                [
413
                    'user'        => 'foo',
414
                    'password'    => 'bar',
415
                    'host'        => 'localhost',
416
                    'dbname'      => 'baz',
417
                    'driverClass' => DriverMock::class,
418
                ],
419
            ],
420
            'URL without scheme but default PDO driver and default driver' => [
421
                [
422
                    'url'    => '//foo:bar@localhost/baz',
423
                    'pdo'    => true,
424
                    'driver' => 'pdo_mysql',
425
                ],
426
                [
427
                    'user'     => 'foo',
428
                    'password' => 'bar',
429
                    'host'     => 'localhost',
430
                    'dbname'   => 'baz',
431
                    'driver'   => PDOMySQLDriver::class,
432
                ],
433
            ],
434
            'URL without scheme but driver and custom driver' => [
435
                [
436
                    'url'         => '//foo:bar@localhost/baz',
437
                    'driver'      => 'pdo_mysql',
438
                    'driverClass' => DriverMock::class,
439
                ],
440
                [
441
                    'user'        => 'foo',
442
                    'password'    => 'bar',
443
                    'host'        => 'localhost',
444
                    'dbname'      => 'baz',
445
                    'driverClass' => DriverMock::class,
446
                ],
447
            ],
448
            'URL with default PDO driver' => [
449
                [
450
                    'url' => 'mysql://foo:bar@localhost/baz',
451
                    'pdo' => true,
452
                ],
453
                [
454
                    'user'     => 'foo',
455
                    'password' => 'bar',
456
                    'host'     => 'localhost',
457
                    'dbname'   => 'baz',
458
                    'driver'   => PDOMySQLDriver::class,
459
                ],
460
            ],
461
            'URL with default driver' => [
462
                [
463
                    'url'    => 'mysql://foo:bar@localhost/baz',
464
                    'driver' => 'sqlite',
465
                ],
466
                [
467
                    'user'     => 'foo',
468
                    'password' => 'bar',
469
                    'host'     => 'localhost',
470
                    'dbname'   => 'baz',
471
                    'driver'   => PDOMySQLDriver::class,
472
                ],
473
            ],
474
            'URL with default custom driver' => [
475
                [
476
                    'url'         => 'mysql://foo:bar@localhost/baz',
477
                    'driverClass' => DriverMock::class,
478
                ],
479
                [
480
                    'user'     => 'foo',
481
                    'password' => 'bar',
482
                    'host'     => 'localhost',
483
                    'dbname'   => 'baz',
484
                    'driver'   => PDOMySQLDriver::class,
485
                ],
486
            ],
487
            'URL with default PDO driver and default driver' => [
488
                [
489
                    'url'    => 'mysql://foo:bar@localhost/baz',
490
                    'pdo'    => true,
491
                    'driver' => 'sqlite',
492
                ],
493
                [
494
                    'user'     => 'foo',
495
                    'password' => 'bar',
496
                    'host'     => 'localhost',
497
                    'dbname'   => 'baz',
498
                    'driver'   => PDOMySQLDriver::class,
499
                ],
500
            ],
501
            'URL with default driver and default custom driver' => [
502
                [
503
                    'url'         => 'mysql://foo:bar@localhost/baz',
504
                    'driver'      => 'sqlite',
505
                    'driverClass' => DriverMock::class,
506
                ],
507
                [
508
                    'user'     => 'foo',
509
                    'password' => 'bar',
510
                    'host'     => 'localhost',
511
                    'dbname'   => 'baz',
512
                    'driver'   => PDOMySQLDriver::class,
513
                ],
514
            ],
515
            'URL with default PDO driver and default driver and default custom driver' => [
516
                [
517
                    'url'         => 'mysql://foo:bar@localhost/baz',
518
                    'pdo'         => true,
519
                    'driver'      => 'sqlite',
520
                    'driverClass' => DriverMock::class,
521
                ],
522
                [
523
                    'user'     => 'foo',
524
                    'password' => 'bar',
525
                    'host'     => 'localhost',
526
                    'dbname'   => 'baz',
527
                    'driver'   => PDOMySQLDriver::class,
528
                ],
529
            ],
530
        ];
531
    }
532
}
533