Skip to content

Commit 888d37f

Browse files
authored
DBAL 4 compatibility (#1707)
* run CI with DBAL 4 * initial work for DBAL 4 compatibility * review feedback + handle missing EventManager arg * improve DBAL 4 detection for EventManager * refactor getDatabasePlatform call
1 parent 4290d51 commit 888d37f

File tree

4 files changed

+39
-10
lines changed

4 files changed

+39
-10
lines changed

.github/workflows/continuous-integration.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,12 @@ jobs:
5454
stability: "stable"
5555
remove-orm: true
5656

57+
# DBAL 4
58+
- php-version: "8.2"
59+
dependencies: "highest"
60+
stability: "dev"
61+
remove-orm: true
62+
5763
# Bleeding edge
5864
- php-version: "8.2"
5965
dependencies: "highest"

ConnectionFactory.php

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,25 @@
55
use Doctrine\Common\EventManager;
66
use Doctrine\DBAL\Configuration;
77
use Doctrine\DBAL\Connection;
8+
use Doctrine\DBAL\Connection\StaticServerVersionProvider;
9+
use Doctrine\DBAL\ConnectionException;
810
use Doctrine\DBAL\DriverManager;
9-
use Doctrine\DBAL\Exception;
1011
use Doctrine\DBAL\Exception as DBALException;
1112
use Doctrine\DBAL\Exception\DriverException;
13+
use Doctrine\DBAL\Exception\DriverRequired;
14+
use Doctrine\DBAL\Exception\InvalidWrapperClass;
1215
use Doctrine\DBAL\Exception\MalformedDsnException;
1316
use Doctrine\DBAL\Platforms\AbstractMySQLPlatform;
1417
use Doctrine\DBAL\Platforms\AbstractPlatform;
1518
use Doctrine\DBAL\Tools\DsnParser;
1619
use Doctrine\DBAL\Types\Type;
1720
use Doctrine\Deprecations\Deprecation;
21+
use InvalidArgumentException;
1822

1923
use function array_merge;
24+
use function class_exists;
2025
use function is_subclass_of;
26+
use function method_exists;
2127
use function trigger_deprecation;
2228

2329
use const PHP_EOL;
@@ -63,6 +69,10 @@ public function __construct(array $typesConfig, ?DsnParser $dsnParser = null)
6369
*/
6470
public function createConnection(array $params, ?Configuration $config = null, ?EventManager $eventManager = null, array $mappingTypes = [])
6571
{
72+
if (! method_exists(Connection::class, 'getEventManager') && $eventManager !== null) {
73+
throw new InvalidArgumentException('Passing an EventManager instance is not supported with DBAL > 3');
74+
}
75+
6676
if (! $this->initialized) {
6777
$this->initializeTypes();
6878
}
@@ -92,17 +102,23 @@ public function createConnection(array $params, ?Configuration $config = null, ?
92102

93103
if (isset($params['wrapperClass'])) {
94104
if (! is_subclass_of($params['wrapperClass'], Connection::class)) {
105+
if (class_exists(InvalidWrapperClass::class)) {
106+
throw InvalidWrapperClass::new($params['wrapperClass']);
107+
}
108+
95109
throw DBALException::invalidWrapperClass($params['wrapperClass']);
96110
}
97111

98112
$wrapperClass = $params['wrapperClass'];
99113
$params['wrapperClass'] = null;
100114
}
101115

102-
$connection = DriverManager::getConnection($params, $config, $eventManager);
116+
$connection = DriverManager::getConnection(...array_merge([$params, $config], $eventManager ? [$eventManager] : []));
103117
$params = $this->addDatabaseSuffix(array_merge($connection->getParams(), $overriddenOptions));
104118
$driver = $connection->getDriver();
105-
$platform = $driver->getDatabasePlatform();
119+
$platform = $driver->getDatabasePlatform(
120+
...(class_exists(StaticServerVersionProvider::class) ? [new StaticServerVersionProvider($params['serverVersion'] ?? '')] : [])
121+
);
106122

107123
if (! isset($params['charset'])) {
108124
if ($platform instanceof AbstractMySQLPlatform) {
@@ -134,7 +150,7 @@ public function createConnection(array $params, ?Configuration $config = null, ?
134150

135151
$connection = new $wrapperClass($params, $driver, $config, $eventManager);
136152
} else {
137-
$connection = DriverManager::getConnection($params, $config, $eventManager);
153+
$connection = DriverManager::getConnection(...array_merge([$params, $config], $eventManager ? [$eventManager] : []));
138154
}
139155

140156
if (! empty($mappingTypes)) {
@@ -162,7 +178,9 @@ private function getDatabasePlatform(Connection $connection): AbstractPlatform
162178
try {
163179
return $connection->getDatabasePlatform();
164180
} catch (DriverException $driverException) {
165-
throw new DBALException(
181+
$class = class_exists(DBALException::class) ? DBALException::class : ConnectionException::class;
182+
183+
throw new $class(
166184
'An exception occurred while establishing a connection to figure out your platform version.' . PHP_EOL .
167185
"You can circumvent this by setting a 'server_version' configuration value" . PHP_EOL . PHP_EOL .
168186
'For further information have a look at:' . PHP_EOL .
@@ -226,7 +244,7 @@ private function addDatabaseSuffix(array $params): array
226244
* URL extracted into individual parameter parts.
227245
* @psalm-return Params
228246
*
229-
* @throws Exception
247+
* @throws DBALException
230248
*/
231249
private function parseDatabaseUrl(array $params): array
232250
{
@@ -237,7 +255,7 @@ private function parseDatabaseUrl(array $params): array
237255
try {
238256
$parsedParams = $this->dsnParser->parse($params['url']);
239257
} catch (MalformedDsnException $e) {
240-
throw new Exception('Malformed parameter "url".', 0, $e);
258+
throw new MalformedDsnException('Malformed parameter "url".', 0, $e);
241259
}
242260

243261
if (isset($parsedParams['driver'])) {
@@ -251,7 +269,11 @@ private function parseDatabaseUrl(array $params): array
251269
// If a schemeless connection URL is given, we require a default driver or default custom driver
252270
// as connection parameter.
253271
if (! isset($params['driverClass']) && ! isset($params['driver'])) {
254-
throw Exception::driverRequired($params['url']);
272+
if (class_exists(DriverRequired::class)) {
273+
throw DriverRequired::new($params['url']);
274+
}
275+
276+
throw DBALException::driverRequired($params['url']);
255277
}
256278

257279
unset($params['url']);

DependencyInjection/DoctrineExtension.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,8 @@ protected function loadDbalConnection($name, array $connection, ContainerBuilder
278278
->setArguments([
279279
$options,
280280
new Reference(sprintf('doctrine.dbal.%s_connection.configuration', $name)),
281-
new Reference(sprintf('doctrine.dbal.%s_connection.event_manager', $name)),
281+
// event manager is only supported on DBAL < 4
282+
method_exists(Connection::class, 'getEventManager') ? new Reference(sprintf('doctrine.dbal.%s_connection.event_manager', $name)) : null,
282283
$connection['mapping_types'],
283284
]);
284285

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
"require": {
3232
"php": "^7.4 || ^8.0",
3333
"doctrine/cache": "^1.11 || ^2.0",
34-
"doctrine/dbal": "^3.7.0",
34+
"doctrine/dbal": "^3.7.0 || ^4.0",
3535
"doctrine/persistence": "^2.2 || ^3",
3636
"doctrine/sql-formatter": "^1.0.1",
3737
"symfony/cache": "^5.4 || ^6.0 || ^7.0",

0 commit comments

Comments
 (0)