Failed Conditions
Pull Request — 2.10 (#3803)
by Sergei
62:38
created

DriverManagerTest::testDatabaseUrl()   A

Complexity

Conditions 5
Paths 12

Size

Total Lines 16
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 10
dl 0
loc 16
rs 9.6111
c 0
b 0
f 0
cc 5
nc 12
nop 2
1
<?php
2
3
namespace Doctrine\Tests\DBAL;
4
5
use Doctrine\DBAL\Connection;
6
use Doctrine\DBAL\Connections\MasterSlaveConnection;
7
use Doctrine\DBAL\DBALException;
8
use Doctrine\DBAL\Driver;
9
use Doctrine\DBAL\Driver\DrizzlePDOMySql\Driver as DrizzlePDOMySqlDriver;
10
use Doctrine\DBAL\Driver\PDOMySql\Driver as PDOMySQLDriver;
11
use Doctrine\DBAL\Driver\PDOSqlite\Driver as PDOSqliteDriver;
12
use Doctrine\DBAL\Driver\SQLSrv\Driver as SQLSrvDriver;
13
use Doctrine\DBAL\DriverManager;
14
use Doctrine\DBAL\Platforms\AbstractPlatform;
15
use Doctrine\DBAL\Sharding\PoolingShardConnection;
16
use Doctrine\DBAL\Sharding\ShardChoser\MultiTenantShardChoser;
17
use Doctrine\Tests\DbalTestCase;
18
use stdClass;
19
use function get_class;
20
use function in_array;
21
use function is_array;
22
23
class DriverManagerTest extends DbalTestCase
24
{
25
    public function testCheckParams() : void
26
    {
27
        $this->expectException(DBALException::class);
28
29
        DriverManager::getConnection([]);
30
    }
31
32
    public function testInvalidDriver() : void
33
    {
34
        $this->expectException(DBALException::class);
35
36
        DriverManager::getConnection(['driver' => 'invalid_driver']);
37
    }
38
39
    /**
40
     * @requires extension pdo_sqlite
41
     */
42
    public function testCustomPlatform() : void
43
    {
44
        $platform = $this->createMock(AbstractPlatform::class);
45
        $options  = [
46
            'url' => 'sqlite::memory:',
47
            'platform' => $platform,
48
        ];
49
50
        $conn = DriverManager::getConnection($options);
51
        self::assertSame($platform, $conn->getDatabasePlatform());
52
    }
53
54
    /**
55
     * @requires extension pdo_sqlite
56
     */
57
    public function testCustomWrapper() : void
58
    {
59
        $wrapper      = $this->createMock(Connection::class);
60
        $wrapperClass = get_class($wrapper);
61
62
        $options = [
63
            'url' => 'sqlite::memory:',
64
            'wrapperClass' => $wrapperClass,
65
        ];
66
67
        $conn = DriverManager::getConnection($options);
68
        self::assertInstanceOf($wrapperClass, $conn);
69
    }
70
71
    /**
72
     * @requires extension pdo_sqlite
73
     */
74
    public function testInvalidWrapperClass() : void
75
    {
76
        $this->expectException(DBALException::class);
77
78
        $options = [
79
            'url' => 'sqlite::memory:',
80
            'wrapperClass' => stdClass::class,
81
        ];
82
83
        DriverManager::getConnection($options);
84
    }
85
86
    public function testInvalidDriverClass() : void
87
    {
88
        $this->expectException(DBALException::class);
89
90
        $options = ['driverClass' => stdClass::class];
91
92
        DriverManager::getConnection($options);
93
    }
94
95
    public function testValidDriverClass() : void
96
    {
97
        $options = ['driverClass' => PDOMySQLDriver::class];
98
99
        $conn = DriverManager::getConnection($options);
100
        self::assertInstanceOf(PDOMySQLDriver::class, $conn->getDriver());
101
    }
102
103
    public function testDatabaseUrlMasterSlave() : void
104
    {
105
        $options = [
106
            'driver' => 'pdo_mysql',
107
            'master' => ['url' => 'mysql://foo:bar@localhost:11211/baz'],
108
            'slaves' => [
109
                'slave1' => ['url' => 'mysql://foo:bar@localhost:11211/baz_slave'],
110
            ],
111
            'wrapperClass' => MasterSlaveConnection::class,
112
        ];
113
114
        $conn = DriverManager::getConnection($options);
115
116
        $params = $conn->getParams();
117
        self::assertInstanceOf(PDOMySQLDriver::class, $conn->getDriver());
118
119
        $expected = [
120
            'user'     => 'foo',
121
            'password' => 'bar',
122
            'host'     => 'localhost',
123
            'port'     => 11211,
124
        ];
125
126
        foreach ($expected as $key => $value) {
127
            self::assertEquals($value, $params['master'][$key]);
128
            self::assertEquals($value, $params['slaves']['slave1'][$key]);
129
        }
130
131
        self::assertEquals('baz', $params['master']['dbname']);
132
        self::assertEquals('baz_slave', $params['slaves']['slave1']['dbname']);
133
    }
134
135
    public function testDatabaseUrlShard() : void
136
    {
137
        $options = [
138
            'driver' => 'pdo_mysql',
139
            'shardChoser' => MultiTenantShardChoser::class,
140
            'global' => ['url' => 'mysql://foo:bar@localhost:11211/baz'],
141
            'shards' => [
142
                [
143
                    'id' => 1,
144
                    'url' => 'mysql://foo:bar@localhost:11211/baz_slave',
145
                ],
146
            ],
147
            'wrapperClass' => PoolingShardConnection::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['global'][$key]);
164
            self::assertEquals($value, $params['shards'][0][$key]);
165
        }
166
167
        self::assertEquals('baz', $params['global']['dbname']);
168
        self::assertEquals('baz_slave', $params['shards'][0]['dbname']);
169
    }
170
171
    /**
172
     * @param mixed $url
173
     * @param mixed $expected
174
     *
175
     * @dataProvider databaseUrls
176
     */
177
    public function testDatabaseUrl($url, $expected) : void
178
    {
179
        $options = is_array($url) ? $url : ['url' => $url];
180
181
        if ($expected === false) {
182
            $this->expectException(DBALException::class);
183
        }
184
185
        $conn = DriverManager::getConnection($options);
186
187
        $params = $conn->getParams();
188
        foreach ($expected as $key => $value) {
189
            if (in_array($key, ['driver', 'driverClass'], true)) {
190
                self::assertInstanceOf($value, $conn->getDriver());
191
            } else {
192
                self::assertEquals($value, $params[$key]);
193
            }
194
        }
195
    }
196
197
    /**
198
     * @return array<string, array<int, mixed>>
199
     */
200
    public function databaseUrls() : iterable
201
    {
202
        $driver      = $this->createMock(Driver::class);
203
        $driverClass = get_class($driver);
204
205
        return [
206
            'simple URL' => [
207
                'mysql://foo:bar@localhost/baz',
208
                [
209
                    'user'     => 'foo',
210
                    'password' => 'bar',
211
                    'host'     => 'localhost',
212
                    'dbname'   => 'baz',
213
                    'driver'   => PDOMySQLDriver::class,
214
                ],
215
            ],
216
            'simple URL with port' => [
217
                'mysql://foo:bar@localhost:11211/baz',
218
                [
219
                    'user'     => 'foo',
220
                    'password' => 'bar',
221
                    'host'     => 'localhost',
222
                    'port'     => 11211,
223
                    'dbname'   => 'baz',
224
                    'driver'   => PDOMySQLDriver::class,
225
                ],
226
            ],
227
            'sqlite relative URL with host' => [
228
                'sqlite://localhost/foo/dbname.sqlite',
229
                [
230
                    'path'   => 'foo/dbname.sqlite',
231
                    'driver' => PDOSqliteDriver::class,
232
                ],
233
            ],
234
            'sqlite absolute URL with host' => [
235
                'sqlite://localhost//tmp/dbname.sqlite',
236
                [
237
                    'path'   => '/tmp/dbname.sqlite',
238
                    'driver' => PDOSqliteDriver::class,
239
                ],
240
            ],
241
            'sqlite relative URL without host' => [
242
                'sqlite:///foo/dbname.sqlite',
243
                [
244
                    'path'   => 'foo/dbname.sqlite',
245
                    'driver' => PDOSqliteDriver::class,
246
                ],
247
            ],
248
            'sqlite absolute URL without host' => [
249
                'sqlite:////tmp/dbname.sqlite',
250
                [
251
                    'path'   => '/tmp/dbname.sqlite',
252
                    'driver' => PDOSqliteDriver::class,
253
                ],
254
            ],
255
            'sqlite memory' => [
256
                'sqlite:///:memory:',
257
                [
258
                    'memory' => true,
259
                    'driver' => PDOSqliteDriver::class,
260
                ],
261
            ],
262
            'sqlite memory with host' => [
263
                'sqlite://localhost/:memory:',
264
                [
265
                    'memory' => true,
266
                    'driver' => PDOSqliteDriver::class,
267
                ],
268
            ],
269
            'params parsed from URL override individual params' => [
270
                [
271
                    'url'      => 'mysql://foo:bar@localhost/baz',
272
                    'password' => 'lulz',
273
                ],
274
                [
275
                    'user'     => 'foo',
276
                    'password' => 'bar',
277
                    'host'     => 'localhost',
278
                    'dbname'   => 'baz',
279
                    'driver'   => PDOMySQLDriver::class,
280
                ],
281
            ],
282
            'params not parsed from URL but individual params are preserved' => [
283
                [
284
                    'url'  => 'mysql://foo:bar@localhost/baz',
285
                    'port' => 1234,
286
                ],
287
                [
288
                    'user'     => 'foo',
289
                    'password' => 'bar',
290
                    'host'     => 'localhost',
291
                    'port'     => 1234,
292
                    'dbname'   => 'baz',
293
                    'driver'   => PDOMySQLDriver::class,
294
                ],
295
            ],
296
            'query params from URL are used as extra params' => [
297
                'url' => 'mysql://foo:bar@localhost/dbname?charset=UTF-8',
298
                ['charset' => 'UTF-8'],
299
            ],
300
            'simple URL with fallthrough scheme not defined in map' => [
301
                'sqlsrv://foo:bar@localhost/baz',
302
                [
303
                    'user'     => 'foo',
304
                    'password' => 'bar',
305
                    'host'     => 'localhost',
306
                    'dbname'   => 'baz',
307
                    'driver'   => SQLSrvDriver::class,
308
                ],
309
            ],
310
            'simple URL with fallthrough scheme containing underscores fails' => [
311
                'drizzle_pdo_mysql://foo:bar@localhost/baz',
312
                false,
313
            ],
314
            'simple URL with fallthrough scheme containing dashes works' => [
315
                'drizzle-pdo-mysql://foo:bar@localhost/baz',
316
                [
317
                    'user'     => 'foo',
318
                    'password' => 'bar',
319
                    'host'     => 'localhost',
320
                    'dbname'   => 'baz',
321
                    'driver'   => DrizzlePDOMySqlDriver::class,
322
                ],
323
            ],
324
            'simple URL with percent encoding' => [
325
                'mysql://foo%3A:bar%2F@localhost/baz+baz%40',
326
                [
327
                    'user'     => 'foo:',
328
                    'password' => 'bar/',
329
                    'host'     => 'localhost',
330
                    'dbname'   => 'baz+baz@',
331
                    'driver'   => PDOMySQLDriver::class,
332
                ],
333
            ],
334
            'simple URL with percent sign in password' => [
335
                'mysql://foo:bar%25bar@localhost/baz',
336
                [
337
                    'user'     => 'foo',
338
                    'password' => 'bar%bar',
339
                    'host'     => 'localhost',
340
                    'dbname'   => 'baz',
341
                    'driver'   => PDOMySQLDriver::class,
342
                ],
343
            ],
344
345
            // DBAL-1234
346
            'URL without scheme and without any driver information' => [
347
                ['url' => '//foo:bar@localhost/baz'],
348
                false,
349
            ],
350
            'URL without scheme but default driver' => [
351
                [
352
                    'url'    => '//foo:bar@localhost/baz',
353
                    'driver' => 'pdo_mysql',
354
                ],
355
                [
356
                    'user'     => 'foo',
357
                    'password' => 'bar',
358
                    'host'     => 'localhost',
359
                    'dbname'   => 'baz',
360
                    'driver'   => PDOMySQLDriver::class,
361
                ],
362
            ],
363
            'URL without scheme but custom driver' => [
364
                [
365
                    'url'         => '//foo:bar@localhost/baz',
366
                    'driverClass' => $driverClass,
367
                ],
368
                [
369
                    'user'        => 'foo',
370
                    'password'    => 'bar',
371
                    'host'        => 'localhost',
372
                    'dbname'      => 'baz',
373
                    'driverClass' => $driverClass,
374
                ],
375
            ],
376
            'URL without scheme but driver and custom driver' => [
377
                [
378
                    'url'         => '//foo:bar@localhost/baz',
379
                    'driver'      => 'pdo_mysql',
380
                    'driverClass' => $driverClass,
381
                ],
382
                [
383
                    'user'        => 'foo',
384
                    'password'    => 'bar',
385
                    'host'        => 'localhost',
386
                    'dbname'      => 'baz',
387
                    'driverClass' => $driverClass,
388
                ],
389
            ],
390
            'URL with default driver' => [
391
                [
392
                    'url'    => 'mysql://foo:bar@localhost/baz',
393
                    'driver' => 'sqlite',
394
                ],
395
                [
396
                    'user'     => 'foo',
397
                    'password' => 'bar',
398
                    'host'     => 'localhost',
399
                    'dbname'   => 'baz',
400
                    'driver'   => PDOMySQLDriver::class,
401
                ],
402
            ],
403
            'URL with default custom driver' => [
404
                [
405
                    'url'         => 'mysql://foo:bar@localhost/baz',
406
                    'driverClass' => $driverClass,
407
                ],
408
                [
409
                    'user'     => 'foo',
410
                    'password' => 'bar',
411
                    'host'     => 'localhost',
412
                    'dbname'   => 'baz',
413
                    'driver'   => PDOMySQLDriver::class,
414
                ],
415
            ],
416
            'URL with default driver and default custom driver' => [
417
                [
418
                    'url'         => 'mysql://foo:bar@localhost/baz',
419
                    'driver'      => 'sqlite',
420
                    'driverClass' => $driverClass,
421
                ],
422
                [
423
                    'user'     => 'foo',
424
                    'password' => 'bar',
425
                    'host'     => 'localhost',
426
                    'dbname'   => 'baz',
427
                    'driver'   => PDOMySQLDriver::class,
428
                ],
429
            ],
430
        ];
431
    }
432
}
433