Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove the url connection param #5850

Merged
merged 1 commit into from
Jan 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 27 additions & 5 deletions UPGRADE.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,33 @@ awareness about deprecated code.

# Upgrade to 4.0

## Removed `Connection::PARAM_*_ARRAY` constants
## BC BREAK: Removed the `url` connection parameter

DBAL ships with a new and configurable DSN parser that can be used to parse a
database URL into connection parameters understood by `DriverManager`.

### Before

```php
$connection = DriverManager::getConnection(
['url' => 'mysql://my-user:t0ps3cr3t@my-host/my-database']
);
```

### After

```php
$dsnParser = new DsnParser(['mysql' => 'pdo_mysql']);
$connection = DriverManager::getConnection(
$dsnParser->parse('mysql://my-user:t0ps3cr3t@my-host/my-database')
);
```

## BC BREAK: Removed `Connection::PARAM_*_ARRAY` constants

Use the enum `ArrayParameterType` instead.

## Disallowed partial version numbers in ``serverVersion``
## BC BREAK: Disallowed partial version numbers in ``serverVersion``

The ``serverVersion`` connection parameter must consist of 3 numbers:

Expand All @@ -21,7 +43,7 @@ The ``serverVersion`` connection parameter must consist of 3 numbers:
+'serverVersion' => '8.0.31'
```

## Removed `mariadb-` prefix hack
## BC BREAK: Removed `mariadb-` prefix hack

Previously, it was necessary to prefix the `serverVersion` parameter with
`mariadb-` when using MariaDB. Doing so is now considered invalid, and you
Expand All @@ -33,11 +55,11 @@ should prefer using the version as returned by `SELECT VERSION();`
```


## Removed `SchemaDiff::$orphanedForeignKeys`
## BC BREAK: Removed `SchemaDiff::$orphanedForeignKeys`

The functionality of automatically dropping the foreign keys referencing the tables being dropped has been removed.

## BC Break: Removed registration of user defined functions for SQLite
## BC BREAK: Removed registration of user defined functions for SQLite

DBAL does not register functions for SQLite anymore. The following functions
which were previously provided by DBAL have been removed:
Expand Down
69 changes: 1 addition & 68 deletions src/DriverManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,9 @@
use Doctrine\DBAL\Exception\DriverRequired;
use Doctrine\DBAL\Exception\InvalidDriverClass;
use Doctrine\DBAL\Exception\InvalidWrapperClass;
use Doctrine\DBAL\Exception\MalformedDsnException;
use Doctrine\DBAL\Exception\UnknownDriver;
use Doctrine\DBAL\Tools\DsnParser;
use Doctrine\Deprecations\Deprecation;

use function array_keys;
use function array_merge;
use function class_implements;
use function in_array;
use function is_subclass_of;
Expand Down Expand Up @@ -62,7 +58,6 @@
* serverVersion?: string,
* sharding?: array<string,mixed>,
* slaves?: array<OverrideParams>,
* url?: string,
* user?: string,
* wrapperClass?: class-string<Connection>,
* unix_socket?: string,
Expand Down Expand Up @@ -158,20 +153,7 @@ private function __construct()
public static function getConnection(array $params, ?Configuration $config = null): Connection
{
$config ??= new Configuration();
$params = self::parseDatabaseUrl($params);

// URL support for PrimaryReplicaConnection
if (isset($params['primary'])) {
$params['primary'] = self::parseDatabaseUrl($params['primary']);
}

if (isset($params['replica'])) {
foreach ($params['replica'] as $key => $replicaParams) {
$params['replica'][$key] = self::parseDatabaseUrl($replicaParams);
}
}

$driver = self::createDriver($params);
$driver = self::createDriver($params);

foreach ($config->getMiddlewares() as $middleware) {
$driver = $middleware->wrap($driver);
Expand Down Expand Up @@ -228,53 +210,4 @@ private static function createDriver(array $params): Driver

throw DriverRequired::new();
}

/**
* Extracts parts from a database URL, if present, and returns an
* updated list of parameters.
*
* @param mixed[] $params The list of parameters.
* @psalm-param Params $params
*
* @return mixed[] A modified list of parameters with info from a database
* URL extracted into indidivual parameter parts.
* @psalm-return Params
*/
private static function parseDatabaseUrl(array $params): array
{
if (! isset($params['url'])) {
return $params;
}

Deprecation::trigger(
'doctrine/dbal',
'https://github.com/doctrine/dbal/pull/5843',
'The "url" connection parameter is deprecated. Please use %s to parse a database url before calling %s.',
DsnParser::class,
self::class,
);

$parser = new DsnParser();
try {
$parsedParams = $parser->parse($params['url']);
} catch (MalformedDsnException $e) {
throw new InvalidDriverClass('Malformed parameter "url".', 0, $e);
}

if (isset($parsedParams['driver'])) {
// The requested driver from the URL scheme takes precedence
// over the default custom driver from the connection parameters (if any).
unset($params['driverClass']);
}

$params = array_merge($params, $parsedParams);

// If a schemeless connection URL is given, we require a default driver or default custom driver
// as connection parameter.
if (! isset($params['driverClass']) && ! isset($params['driver'])) {
throw DriverRequired::new($params['url']);
}

return $params;
}
}
2 changes: 0 additions & 2 deletions src/Exception/MalformedDsnException.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@

namespace Doctrine\DBAL\Exception;

use InvalidArgumentException;

/** @psalm-immutable */
class MalformedDsnException extends InvalidArgumentException
{
Expand Down
5 changes: 3 additions & 2 deletions src/Tools/DsnParser.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,9 @@
final class DsnParser
{
/** @param array<string, string> $schemeMapping An array used to map DSN schemes to DBAL drivers */
public function __construct(private array $schemeMapping = [])
{
public function __construct(
private readonly array $schemeMapping = [],
) {
}

/**
Expand Down
138 changes: 2 additions & 136 deletions tests/DriverManagerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
namespace Doctrine\DBAL\Tests;

use Doctrine\DBAL\Connection;
use Doctrine\DBAL\Connections\PrimaryReadReplicaConnection;
use Doctrine\DBAL\Driver;
use Doctrine\DBAL\Driver\PDO;
use Doctrine\DBAL\Driver\SQLSrv\Driver as SQLSrvDriver;
Expand All @@ -16,7 +15,6 @@
use PHPUnit\Framework\TestCase;
use stdClass;

use function array_intersect_key;
use function array_merge;
use function in_array;
use function is_array;
Expand Down Expand Up @@ -48,7 +46,8 @@ public function testCustomWrapper(): void
$wrapperClass = $wrapper::class;

$options = [
'url' => 'pdo-sqlite::memory:',
'driver' => 'sqlite3',
'memory' => true,
'wrapperClass' => $wrapperClass,
];

Expand Down Expand Up @@ -90,79 +89,6 @@ public function testValidDriverClass(): void
self::assertInstanceOf(PDO\MySQL\Driver::class, $conn->getDriver());
}

public function testDatabaseUrlPrimaryReplica(): void
{
$options = [
'driver' => 'pdo_mysql',
'primary' => ['url' => 'mysql://foo:bar@localhost:11211/baz'],
'replica' => [
'replica1' => ['url' => 'mysql://foo:bar@localhost:11211/baz_replica'],
],
'wrapperClass' => PrimaryReadReplicaConnection::class,
];

$this->expectDeprecationWithIdentifier('https://github.com/doctrine/dbal/pull/5843');
$conn = DriverManager::getConnection($options);

$params = $conn->getParams();
self::assertInstanceOf(PDO\MySQL\Driver::class, $conn->getDriver());

$expected = [
'user' => 'foo',
'password' => 'bar',
'host' => 'localhost',
'port' => 11211,
'dbname' => 'baz',
'driver' => 'pdo_mysql',
'url' => 'mysql://foo:bar@localhost:11211/baz',
];

self::assertEquals(
[
'primary' => $expected,
'replica' => [
'replica1' => array_merge(
$expected,
[
'dbname' => 'baz_replica',
'url' => 'mysql://foo:bar@localhost:11211/baz_replica',
],
),
],
],
array_intersect_key($params, ['primary' => null, 'replica' => null]),
);
}

/**
* @param array<string, mixed>|false $expected
* @psalm-param Params|string $url
*
* @dataProvider databaseUrls
*/
public function testDatabaseUrlDeprecated(array|string $url, array|false $expected): void
{
$options = is_array($url) ? $url : ['url' => $url];

if ($expected === false) {
$this->expectException(Exception::class);
}

$this->expectDeprecationWithIdentifier('https://github.com/doctrine/dbal/pull/5843');
$conn = DriverManager::getConnection($options);

self::assertNotFalse($expected);

$params = $conn->getParams();
foreach ($expected as $key => $value) {
if (in_array($key, ['driver', 'driverClass'], true)) {
self::assertInstanceOf($value, $conn->getDriver());
} else {
self::assertEquals($value, $params[$key]);
}
}
}

/**
* @param array<string, mixed>|string $url
* @param array<string, mixed>|false $expected
Expand All @@ -172,12 +98,6 @@ public function testDatabaseUrlDeprecated(array|string $url, array|false $expect
public function testDatabaseUrl(array|string $url, array|false $expected): void
{
if (is_array($url)) {
if (isset($url['driverClass'])) {
self::markTestSkipped(
'Legacy test case: Merging driverClass into the parsed parameters has to be done in userland now.',
);
}

['url' => $url] = $options = $url;
unset($options['url']);
} else {
Expand Down Expand Up @@ -386,60 +306,6 @@ public function databaseUrls(): iterable
'driverClass' => $driverClass,
],
],
'URL without scheme but driver and custom driver' => [
[
'url' => '//foo:bar@localhost/baz',
'driver' => 'pdo_mysql',
'driverClass' => $driverClass,
],
[
'user' => 'foo',
'password' => 'bar',
'host' => 'localhost',
'dbname' => 'baz',
'driverClass' => $driverClass,
],
],
'URL with default driver' => [
[
'url' => 'pdo-mysql://foo:bar@localhost/baz',
'driver' => 'sqlite',
],
[
'user' => 'foo',
'password' => 'bar',
'host' => 'localhost',
'dbname' => 'baz',
'driver' => PDO\MySQL\Driver::class,
],
],
'URL with default custom driver' => [
[
'url' => 'pdo-mysql://foo:bar@localhost/baz',
'driverClass' => $driverClass,
],
[
'user' => 'foo',
'password' => 'bar',
'host' => 'localhost',
'dbname' => 'baz',
'driver' => PDO\MySQL\Driver::class,
],
],
'URL with default driver and default custom driver' => [
[
'url' => 'pdo-mysql://foo:bar@localhost/baz',
'driver' => 'sqlite',
'driverClass' => $driverClass,
],
[
'user' => 'foo',
'password' => 'bar',
'host' => 'localhost',
'dbname' => 'baz',
'driver' => PDO\MySQL\Driver::class,
],
],
];
}
}