Skip to content

Commit ac3500a

Browse files
authored
Add Doctrine DBAL 4 compatibility (#121)
This adds compatiblity with DBAL 4, while also supporting DBAL 3 for an easy transition. * The url connection parameter was removed in DBAL 4. Detect whether `Doctrine\DBAL\Tools\DsnParser` is available and use it to parse the DSN into connection parameters. On DBAL 3 (without `DsnParser`) the previous `['url' => ...]` array is used as a fallback. * DBAL 4 removed the EventManager and the `DC2Type` column comment mechanism along with it. The `DummyTypeRegistrationEventSubscriber` — which worked around unknown custom types encoded in column comments, see #102 — is therefore no longer needed. Its is now conditional, based on `class_exists(\Doctrine\DBAL\Events::class)`, which is only true on DBAL 3. * `Connection::getSchemaManager()` (deprecated in DBAL 3) was replaced with `createSchemaManager()`
1 parent 2a1e642 commit ac3500a

7 files changed

Lines changed: 48 additions & 31 deletions

File tree

.composer-require-checker.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"symbol-whitelist": [
3+
"Doctrine\\Common\\EventSubscriber",
4+
"Doctrine\\DBAL\\Event\\SchemaColumnDefinitionEventArgs",
5+
"Doctrine\\DBAL\\Events"
6+
]
7+
}

.github/workflows/dependencies.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,4 +33,6 @@ jobs:
3333
composer update --no-interaction --no-scripts --no-progress
3434
composer show
3535
- name: ComposerRequireChecker
36-
uses: docker://ghcr.io/webfactory/composer-require-checker:4.8.0
36+
uses: docker://ghcr.io/webfactory/composer-require-checker:4.18.0
37+
with:
38+
args: --config-file=.composer-require-checker.json

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
"ext-SimpleXML": "*",
2020
"ext-libxml": "*",
2121
"ext-pdo": "*",
22-
"doctrine/dbal": "^2.13 || ^3.0",
22+
"doctrine/dbal": "^3.3 || ^4.0",
2323
"doctrine/event-manager": "^1.0 || ^2.0",
2424
"fakerphp/faker": "^1.14",
2525
"symfony/console": "^4.0 || ^5.0 || ^6.0 || ^7.0 || ^8.0",

composer.lock

Lines changed: 17 additions & 25 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/Webfactory/Slimdump/Database/Dumper.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ private function dumpData(Schema\Table $asset, Table $tableConfig): void
126126
$progress->setRedrawFrequency((int) max($numRows / 100, 1));
127127
$progress->start();
128128

129-
$wrappedConnection = $this->connection->getWrappedConnection();
129+
$wrappedConnection = $this->connection->getNativeConnection();
130130
if ($wrappedConnection instanceof PDO) {
131131
$pdo = $wrappedConnection;
132132
} elseif ($wrappedConnection instanceof \Doctrine\DBAL\Driver\PDO\Connection) {

src/Webfactory/Slimdump/DumpTask.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ public function dump()
4545

4646
$db = $this->connection;
4747

48-
$manager = $db->getSchemaManager();
48+
$manager = $db->createSchemaManager();
4949

5050
foreach (array_merge($manager->listTables(), $manager->listViews()) as $asset) {
5151
$tableConfig = $this->config->findTable($asset->getName());

src/Webfactory/Slimdump/SlimdumpCommand.php

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
use Doctrine\DBAL\Connection;
66
use Doctrine\DBAL\Driver\PDO\MySQL\Driver as PDOMySqlDriver;
77
use Doctrine\DBAL\DriverManager;
8+
use Doctrine\DBAL\Tools\DsnParser;
89
use RuntimeException;
910
use Symfony\Component\Console\Command\Command;
1011
use Symfony\Component\Console\Input\InputArgument;
@@ -69,7 +70,14 @@ protected function execute(InputInterface $input, OutputInterface $output): int
6970
$progressOutput = $this->createProgressOutput($input, $output);
7071

7172
$connection = $this->createConnection($input);
72-
$connection->getEventManager()->addEventSubscriber(new DummyTypeRegistrationEventSubscriber($connection->getSchemaManager()));
73+
74+
// In DBAL 3, the SchemaManager parses DC2Type column comments and throws when encountering
75+
// unknown types. We register a DummyType for any unknown type to work around this.
76+
// In DBAL 4, the DC2Type comment mechanism was removed entirely, so this is no longer needed.
77+
if (class_exists(\Doctrine\DBAL\Events::class)) {
78+
$connection->getEventManager()->addEventSubscriber(new DummyTypeRegistrationEventSubscriber($connection->createSchemaManager()));
79+
}
80+
7381
$this->setMaxExecutionTimeUnlimited($connection, $progressOutput);
7482

7583
$config = ConfigBuilder::createConfigurationFromConsecutiveFiles($input->getArgument('config'));
@@ -146,8 +154,16 @@ private function createConnection(InputInterface $input): Connection
146154
}
147155

148156
$mysqliIndependentDsn = preg_replace('_^mysqli:_', 'mysql:', $dsn);
157+
158+
if (class_exists(DsnParser::class)) {
159+
// DBAL 4: the 'url' connection parameter was removed in favour of DsnParser
160+
$params = (new DsnParser(['mysql' => 'pdo_mysql']))->parse($mysqliIndependentDsn);
161+
} else {
162+
$params = ['url' => $mysqliIndependentDsn];
163+
}
164+
149165
$connection = DriverManager::getConnection(
150-
['url' => $mysqliIndependentDsn, 'charset' => 'utf8', 'driverClass' => PDOMySqlDriver::class]
166+
array_merge($params, ['charset' => 'utf8', 'driverClass' => PDOMySqlDriver::class])
151167
);
152168

153169
return $connection;

0 commit comments

Comments
 (0)