Subversion-Projekte lars-tiefland.laravel_shop

Revision

Revision 148 | Zur aktuellen Revision | Ganze Datei anzeigen | Leerzeichen ignorieren | Details | Blame | Letzte Änderung | Log anzeigen | RSS feed

Revision 148 Revision 621
Zeile 5... Zeile 5...
5
use Doctrine\Common\EventManager;
5
use Doctrine\Common\EventManager;
6
use Doctrine\DBAL\Driver\IBMDB2;
6
use Doctrine\DBAL\Driver\IBMDB2;
7
use Doctrine\DBAL\Driver\Mysqli;
7
use Doctrine\DBAL\Driver\Mysqli;
8
use Doctrine\DBAL\Driver\OCI8;
8
use Doctrine\DBAL\Driver\OCI8;
9
use Doctrine\DBAL\Driver\PDO;
9
use Doctrine\DBAL\Driver\PDO;
-
 
10
use Doctrine\DBAL\Driver\PgSQL;
10
use Doctrine\DBAL\Driver\SQLite3;
11
use Doctrine\DBAL\Driver\SQLite3;
11
use Doctrine\DBAL\Driver\SQLSrv;
12
use Doctrine\DBAL\Driver\SQLSrv;
-
 
13
use Doctrine\DBAL\Exception\MalformedDsnException;
-
 
14
use Doctrine\DBAL\Tools\DsnParser;
12
use Doctrine\Deprecations\Deprecation;
15
use Doctrine\Deprecations\Deprecation;
-
 
16
use SensitiveParameter;
Zeile 13... Zeile 17...
13
 
17
 
14
use function array_keys;
18
use function array_keys;
15
use function array_merge;
-
 
16
use function assert;
-
 
17
use function class_implements;
-
 
18
use function in_array;
19
use function array_merge;
19
use function is_a;
-
 
20
use function is_string;
-
 
21
use function parse_str;
-
 
22
use function parse_url;
-
 
23
use function preg_replace;
-
 
24
use function rawurldecode;
-
 
25
use function str_replace;
-
 
26
use function strpos;
-
 
Zeile 27... Zeile 20...
27
use function substr;
20
use function is_a;
28
 
21
 
29
/**
22
/**
30
 * Factory for creating {@see Connection} instances.
23
 * Factory for creating {@see Connection} instances.
Zeile 40... Zeile 33...
40
 *     password?: string,
33
 *     password?: string,
41
 *     path?: string,
34
 *     path?: string,
42
 *     pdo?: \PDO,
35
 *     pdo?: \PDO,
43
 *     platform?: Platforms\AbstractPlatform,
36
 *     platform?: Platforms\AbstractPlatform,
44
 *     port?: int,
37
 *     port?: int,
-
 
38
 *     url?: string,
45
 *     user?: string,
39
 *     user?: string,
46
 *     unix_socket?: string,
40
 *     unix_socket?: string,
47
 * }
41
 * }
48
 * @psalm-type Params = array{
42
 * @psalm-type Params = array{
49
 *     charset?: string,
43
 *     charset?: string,
Zeile 88... Zeile 82...
88
        'pdo_oci'            => PDO\OCI\Driver::class,
82
        'pdo_oci'            => PDO\OCI\Driver::class,
89
        'oci8'               => OCI8\Driver::class,
83
        'oci8'               => OCI8\Driver::class,
90
        'ibm_db2'            => IBMDB2\Driver::class,
84
        'ibm_db2'            => IBMDB2\Driver::class,
91
        'pdo_sqlsrv'         => PDO\SQLSrv\Driver::class,
85
        'pdo_sqlsrv'         => PDO\SQLSrv\Driver::class,
92
        'mysqli'             => Mysqli\Driver::class,
86
        'mysqli'             => Mysqli\Driver::class,
-
 
87
        'pgsql'              => PgSQL\Driver::class,
93
        'sqlsrv'             => SQLSrv\Driver::class,
88
        'sqlsrv'             => SQLSrv\Driver::class,
94
        'sqlite3'            => SQLite3\Driver::class,
89
        'sqlite3'            => SQLite3\Driver::class,
95
    ];
90
    ];
Zeile 96... Zeile 91...
96
 
91
 
Zeile 152... Zeile 147...
152
     * <b>driverClass</b>:
147
     * <b>driverClass</b>:
153
     * The driver class to use.
148
     * The driver class to use.
154
     *
149
     *
155
     * @param Configuration|null $config       The configuration to use.
150
     * @param Configuration|null $config       The configuration to use.
156
     * @param EventManager|null  $eventManager The event manager to use.
151
     * @param EventManager|null  $eventManager The event manager to use.
157
     * @psalm-param array{
152
     * @psalm-param Params $params
158
     *     charset?: string,
-
 
159
     *     dbname?: string,
-
 
160
     *     default_dbname?: string,
-
 
161
     *     driver?: key-of<self::DRIVER_MAP>,
-
 
162
     *     driverClass?: class-string<Driver>,
-
 
163
     *     driverOptions?: array<mixed>,
-
 
164
     *     host?: string,
-
 
165
     *     keepSlave?: bool,
-
 
166
     *     keepReplica?: bool,
-
 
167
     *     master?: OverrideParams,
-
 
168
     *     memory?: bool,
-
 
169
     *     password?: string,
-
 
170
     *     path?: string,
-
 
171
     *     pdo?: \PDO,
-
 
172
     *     platform?: Platforms\AbstractPlatform,
-
 
173
     *     port?: int,
-
 
174
     *     primary?: OverrideParams,
-
 
175
     *     replica?: array<OverrideParams>,
-
 
176
     *     sharding?: array<string,mixed>,
-
 
177
     *     slaves?: array<OverrideParams>,
-
 
178
     *     url?: string,
-
 
179
     *     user?: string,
-
 
180
     *     wrapperClass?: class-string<T>,
-
 
181
     * } $params
-
 
182
     *
153
     *
183
     * @psalm-return ($params is array{wrapperClass:mixed} ? T : Connection)
154
     * @psalm-return ($params is array{wrapperClass: class-string<T>} ? T : Connection)
184
     *
155
     *
185
     * @throws Exception
156
     * @throws Exception
186
     *
157
     *
187
     * @template T of Connection
158
     * @template T of Connection
188
     */
159
     */
189
    public static function getConnection(
160
    public static function getConnection(
-
 
161
        #[SensitiveParameter]
190
        array $params,
162
        array $params,
191
        ?Configuration $config = null,
163
        ?Configuration $config = null,
192
        ?EventManager $eventManager = null
164
        ?EventManager $eventManager = null
193
    ): Connection {
165
    ): Connection {
194
        // create default config and event manager, if not set
166
        // create default config and event manager, if not set
Zeile 205... Zeile 177...
205
            foreach ($params['replica'] as $key => $replicaParams) {
177
            foreach ($params['replica'] as $key => $replicaParams) {
206
                $params['replica'][$key] = self::parseDatabaseUrl($replicaParams);
178
                $params['replica'][$key] = self::parseDatabaseUrl($replicaParams);
207
            }
179
            }
208
        }
180
        }
Zeile 209... Zeile 181...
209
 
181
 
Zeile 210... Zeile 182...
210
        $driver = self::createDriver($params);
182
        $driver = self::createDriver($params['driver'] ?? null, $params['driverClass'] ?? null);
211
 
183
 
212
        foreach ($config->getMiddlewares() as $middleware) {
184
        foreach ($config->getMiddlewares() as $middleware) {
Zeile 223... Zeile 195...
223
 
195
 
224
    /**
196
    /**
225
     * Returns the list of supported drivers.
197
     * Returns the list of supported drivers.
226
     *
198
     *
-
 
199
     * @return string[]
227
     * @return string[]
200
     * @psalm-return list<key-of<self::DRIVER_MAP>>
228
     */
201
     */
229
    public static function getAvailableDrivers(): array
202
    public static function getAvailableDrivers(): array
230
    {
203
    {
231
        return array_keys(self::DRIVER_MAP);
204
        return array_keys(self::DRIVER_MAP);
Zeile 232... Zeile 205...
232
    }
205
    }
233
 
206
 
234
    /**
207
    /**
235
     * @param array<string,mixed> $params
208
     * @param class-string<Driver>|null     $driverClass
236
     * @psalm-param Params $params
209
     * @param key-of<self::DRIVER_MAP>|null $driver
237
     *
210
     *
238
     * @throws Exception
211
     * @throws Exception
239
     */
212
     */
240
    private static function createDriver(array $params): Driver
213
    private static function createDriver(?string $driver, ?string $driverClass): Driver
241
    {
214
    {
242
        if (isset($params['driverClass'])) {
-
 
243
            $interfaces = class_implements($params['driverClass']);
-
 
244
 
215
        if ($driverClass === null) {
245
            if ($interfaces === false || ! in_array(Driver::class, $interfaces, true)) {
216
            if ($driver === null) {
Zeile 246... Zeile -...
246
                throw Exception::invalidDriverClass($params['driverClass']);
-
 
247
            }
-
 
248
 
-
 
249
            return new $params['driverClass']();
-
 
250
        }
217
                throw Exception::driverRequired();
251
 
218
            }
252
        if (isset($params['driver'])) {
219
 
Zeile 253... Zeile 220...
253
            if (! isset(self::DRIVER_MAP[$params['driver']])) {
220
            if (! isset(self::DRIVER_MAP[$driver])) {
254
                throw Exception::unknownDriver($params['driver'], array_keys(self::DRIVER_MAP));
-
 
-
 
221
                throw Exception::unknownDriver($driver, array_keys(self::DRIVER_MAP));
255
            }
222
            }
256
 
223
 
Zeile 257... Zeile -...
257
            $class = self::DRIVER_MAP[$params['driver']];
-
 
258
 
-
 
259
            return new $class();
-
 
260
        }
-
 
261
 
-
 
262
        throw Exception::driverRequired();
-
 
263
    }
-
 
264
 
-
 
265
    /**
-
 
266
     * Normalizes the given connection URL path.
-
 
267
     *
-
 
268
     * @return string The normalized connection URL path
224
            $driverClass = self::DRIVER_MAP[$driver];
269
     */
225
        } elseif (! is_a($driverClass, Driver::class, true)) {
Zeile 270... Zeile 226...
270
    private static function normalizeDatabaseUrlPath(string $urlPath): string
226
            throw Exception::invalidDriverClass($driverClass);
271
    {
227
        }
272
        // Trim leading slash from URL path.
228
 
Zeile 284... Zeile 240...
284
     *                 URL extracted into indidivual parameter parts.
240
     *                 URL extracted into indidivual parameter parts.
285
     * @psalm-return Params
241
     * @psalm-return Params
286
     *
242
     *
287
     * @throws Exception
243
     * @throws Exception
288
     */
244
     */
289
    private static function parseDatabaseUrl(array $params): array
245
    private static function parseDatabaseUrl(
-
 
246
        #[SensitiveParameter]
-
 
247
        array $params
290
    {
248
    ): array {
291
        if (! isset($params['url'])) {
249
        if (! isset($params['url'])) {
292
            return $params;
250
            return $params;
293
        }
251
        }
Zeile 294... Zeile -...
294
 
-
 
295
        // (pdo_)?sqlite3?:///... => (pdo_)?sqlite3?://localhost/... or else the URL will be invalid
-
 
296
        $url = preg_replace('#^((?:pdo_)?sqlite3?):///#', '$1://localhost/', $params['url']);
-
 
297
        assert($url !== null);
-
 
298
 
252
 
299
        $url = parse_url($url);
-
 
300
 
-
 
301
        if ($url === false) {
-
 
302
            throw new Exception('Malformed parameter "url".');
-
 
303
        }
-
 
304
 
-
 
305
        foreach ($url as $param => $value) {
-
 
306
            if (! is_string($value)) {
253
        Deprecation::trigger(
307
                continue;
-
 
308
            }
-
 
309
 
254
            'doctrine/dbal',
310
            $url[$param] = rawurldecode($value);
-
 
311
        }
-
 
312
 
255
            'https://github.com/doctrine/dbal/pull/5843',
313
        $params = self::parseDatabaseUrlScheme($url['scheme'] ?? null, $params);
-
 
314
 
-
 
315
        if (isset($url['host'])) {
-
 
316
            $params['host'] = $url['host'];
-
 
317
        }
-
 
318
 
-
 
319
        if (isset($url['port'])) {
-
 
320
            $params['port'] = $url['port'];
-
 
321
        }
-
 
322
 
256
            'The "url" connection parameter is deprecated. Please use %s to parse a database url before calling %s.',
323
        if (isset($url['user'])) {
-
 
324
            $params['user'] = $url['user'];
-
 
325
        }
-
 
326
 
257
            DsnParser::class,
327
        if (isset($url['pass'])) {
-
 
328
            $params['password'] = $url['pass'];
258
            self::class,
329
        }
259
        );
330
 
-
 
331
        $params = self::parseDatabaseUrlPath($url, $params);
260
 
332
        $params = self::parseDatabaseUrlQuery($url, $params);
-
 
333
 
-
 
334
        return $params;
-
 
335
    }
-
 
336
 
-
 
337
    /**
-
 
338
     * Parses the given connection URL and resolves the given connection parameters.
-
 
339
     *
-
 
340
     * Assumes that the connection URL scheme is already parsed and resolved into the given connection parameters
-
 
341
     * via {@see parseDatabaseUrlScheme}.
-
 
342
     *
-
 
343
     * @see parseDatabaseUrlScheme
-
 
344
     *
-
 
345
     * @param mixed[] $url    The URL parts to evaluate.
-
 
346
     * @param mixed[] $params The connection parameters to resolve.
-
 
347
     *
-
 
348
     * @return mixed[] The resolved connection parameters.
-
 
349
     */
-
 
350
    private static function parseDatabaseUrlPath(array $url, array $params): array
-
 
351
    {
-
 
352
        if (! isset($url['path'])) {
-
 
353
            return $params;
261
        $parser = new DsnParser(self::$driverSchemeAliases);
354
        }
-
 
355
 
-
 
356
        $url['path'] = self::normalizeDatabaseUrlPath($url['path']);
-
 
357
 
-
 
358
        // If we do not have a known DBAL driver, we do not know any connection URL path semantics to evaluate
-
 
359
        // and therefore treat the path as regular DBAL connection URL path.
-
 
360
        if (! isset($params['driver'])) {
262
        try {
361
            return self::parseRegularDatabaseUrlPath($url, $params);
-
 
362
        }
-
 
363
 
263
            $parsedParams = $parser->parse($params['url']);
364
        if (strpos($params['driver'], 'sqlite') !== false) {
264
        } catch (MalformedDsnException $e) {
365
            return self::parseSqliteDatabaseUrlPath($url, $params);
265
            throw new Exception('Malformed parameter "url".', 0, $e);
Zeile 366... Zeile -...
366
        }
-
 
367
 
-
 
368
        return self::parseRegularDatabaseUrlPath($url, $params);
-
 
369
    }
-
 
370
 
-
 
371
    /**
-
 
372
     * Parses the query part of the given connection URL and resolves the given connection parameters.
-
 
373
     *
-
 
374
     * @param mixed[] $url    The connection URL parts to evaluate.
-
 
375
     * @param mixed[] $params The connection parameters to resolve.
-
 
376
     *
-
 
377
     * @return mixed[] The resolved connection parameters.
-
 
378
     */
-
 
379
    private static function parseDatabaseUrlQuery(array $url, array $params): array
266
        }
380
    {
-
 
381
        if (! isset($url['query'])) {
-
 
382
            return $params;
-
 
383
        }
-
 
384
 
-
 
385
        $query = [];
-
 
386
 
-
 
387
        parse_str($url['query'], $query); // simply ingest query as extra params, e.g. charset or sslmode
-
 
388
 
-
 
389
        return array_merge($params, $query); // parse_str wipes existing array elements
-
 
390
    }
-
 
391
 
-
 
392
    /**
-
 
393
     * Parses the given regular connection URL and resolves the given connection parameters.
-
 
394
     *
-
 
395
     * Assumes that the "path" URL part is already normalized via {@see normalizeDatabaseUrlPath}.
-
 
396
     *
-
 
397
     * @see normalizeDatabaseUrlPath
-
 
398
     *
-
 
399
     * @param mixed[] $url    The regular connection URL parts to evaluate.
-
 
400
     * @param mixed[] $params The connection parameters to resolve.
-
 
401
     *
-
 
402
     * @return mixed[] The resolved connection parameters.
-
 
403
     */
-
 
404
    private static function parseRegularDatabaseUrlPath(array $url, array $params): array
-
 
405
    {
-
 
406
        $params['dbname'] = $url['path'];
-
 
407
 
-
 
408
        return $params;
-
 
409
    }
-
 
410
 
-
 
411
    /**
-
 
412
     * Parses the given SQLite connection URL and resolves the given connection parameters.
-
 
413
     *
-
 
414
     * Assumes that the "path" URL part is already normalized via {@see normalizeDatabaseUrlPath}.
-
 
415
     *
-
 
416
     * @see normalizeDatabaseUrlPath
-
 
417
     *
-
 
418
     * @param mixed[] $url    The SQLite connection URL parts to evaluate.
-
 
419
     * @param mixed[] $params The connection parameters to resolve.
-
 
420
     *
-
 
421
     * @return mixed[] The resolved connection parameters.
-
 
422
     */
-
 
423
    private static function parseSqliteDatabaseUrlPath(array $url, array $params): array
-
 
424
    {
-
 
425
        if ($url['path'] === ':memory:') {
-
 
426
            $params['memory'] = true;
-
 
427
 
-
 
428
            return $params;
-
 
429
        }
-
 
430
 
-
 
431
        $params['path'] = $url['path']; // pdo_sqlite driver uses 'path' instead of 'dbname' key
-
 
432
 
-
 
433
        return $params;
-
 
434
    }
-
 
435
 
-
 
436
    /**
-
 
437
     * Parses the scheme part from given connection URL and resolves the given connection parameters.
-
 
438
     *
-
 
439
     * @param string|null $scheme The connection URL scheme, if available
-
 
440
     * @param mixed[]     $params The connection parameters to resolve.
-
 
441
     *
-
 
442
     * @return mixed[] The resolved connection parameters.
-
 
443
     *
-
 
444
     * @throws Exception If parsing failed or resolution is not possible.
-
 
445
     */
-
 
446
    private static function parseDatabaseUrlScheme(?string $scheme, array $params): array
-
 
447
    {
267
 
448
        if ($scheme !== null) {
268
        if (isset($parsedParams['driver'])) {
449
            // The requested driver from the URL scheme takes precedence
269
            // The requested driver from the URL scheme takes precedence
450
            // over the default custom driver from the connection parameters (if any).
-
 
451
            unset($params['driverClass']);
-
 
452
 
-
 
453
            // URL schemes must not contain underscores, but dashes are ok
-
 
454
            $driver = str_replace('-', '_', $scheme);
-
 
455
 
-
 
456
            // If the driver is an alias (e.g. "postgres"), map it to the actual name ("pdo-pgsql").
-
 
457
            // Otherwise, let checkParams decide later if the driver exists.
-
 
458
            if (isset(self::$driverSchemeAliases[$driver])) {
-
 
459
                $actualDriver = self::$driverSchemeAliases[$driver];
-
 
460
 
-
 
461
                Deprecation::trigger(
-
 
462
                    'doctrine/dbal',
-
 
463
                    'https://github.com/doctrine/dbal/pull/5697',
-
 
464
                    'Relying on driver name aliases is deprecated. Use %s instead of %s.',
-
 
465
                    str_replace('_', '-', $actualDriver),
-
 
466
                    $driver,
-
 
467
                );
-
 
468
 
-
 
469
                $driver = $actualDriver;
-
 
470
            }
-
 
471
 
-
 
472
            // The requested driver from the URL scheme takes precedence over the
-
 
473
            // default driver from the connection parameters.
-
 
474
            $params['driver'] = $driver;
-
 
475
 
270
            // over the default custom driver from the connection parameters (if any).
Zeile -... Zeile 271...
-
 
271
            unset($params['driverClass']);
-
 
272
        }
476
            return $params;
273
 
477
        }
274
        $params = array_merge($params, $parsedParams);
478
 
275
 
479
        // If a schemeless connection URL is given, we require a default driver or default custom driver
276
        // If a schemeless connection URL is given, we require a default driver or default custom driver
480
        // as connection parameter.
277
        // as connection parameter.