From 3e4319a5af65fdd70e7810623d4e2b711ede7539 Mon Sep 17 00:00:00 2001 From: func0der <529819+func0der@users.noreply.github.com> Date: Fri, 3 Jul 2026 14:46:46 +0200 Subject: [PATCH 1/2] GH-126 Make the DummyType regsitration work with doctrine/dbal:3|4 --- .../Slimdump/Doctrine/DummyType.php | 6 +-- .../Doctrine/DummyTypeRegistration.php | 38 ++++++++++++++ .../DummyTypeRegistrationEventSubscriber.php | 50 ------------------- src/Webfactory/Slimdump/SlimdumpCommand.php | 9 +--- .../Doctrine/DummyTypeRegistrationTest.php | 48 ++++++++++++++++++ 5 files changed, 91 insertions(+), 60 deletions(-) create mode 100644 src/Webfactory/Slimdump/Doctrine/DummyTypeRegistration.php delete mode 100644 src/Webfactory/Slimdump/Doctrine/DummyTypeRegistrationEventSubscriber.php create mode 100644 test/Webfactory/Slimdump/Doctrine/DummyTypeRegistrationTest.php diff --git a/src/Webfactory/Slimdump/Doctrine/DummyType.php b/src/Webfactory/Slimdump/Doctrine/DummyType.php index ef4f1a1..8b1a2ef 100644 --- a/src/Webfactory/Slimdump/Doctrine/DummyType.php +++ b/src/Webfactory/Slimdump/Doctrine/DummyType.php @@ -10,17 +10,17 @@ class DummyType extends Type { public const NAME = 'dummy_type'; - public function convertToPHPValue($value, AbstractPlatform $platform) + public function convertToPHPValue(mixed $value, AbstractPlatform $platform): mixed { throw new LogicException('This Doctrine type assumes that the types won\'t be used to convert any data – it\'s just there to allow the rest of DBAL\'s functionality to work without throwing errors'); } - public function getSQLDeclaration(array $column, AbstractPlatform $platform) + public function getSQLDeclaration(array $column, AbstractPlatform $platform): string { throw new LogicException('This Doctrine type assumes that the types won\'t be used to convert any data – it\'s just there to allow the rest of DBAL\'s functionality to work without throwing errors'); } - public function getName() + public function getName(): string { return self::NAME; } diff --git a/src/Webfactory/Slimdump/Doctrine/DummyTypeRegistration.php b/src/Webfactory/Slimdump/Doctrine/DummyTypeRegistration.php new file mode 100644 index 0000000..a9e56f0 --- /dev/null +++ b/src/Webfactory/Slimdump/Doctrine/DummyTypeRegistration.php @@ -0,0 +1,38 @@ +getDatabasePlatform(); + + if (!Type::hasType(DummyType::NAME)) { + Type::addType(DummyType::NAME, DummyType::class); + } + + $schema = $connection->getDatabase(); + if (null === $schema) { + return; + } + + $sql = 'SELECT DISTINCT DATA_TYPE FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = ?'; + + foreach ($connection->fetchAllAssociative($sql, [$schema]) as $row) { + $dbType = strtolower((string) $row['DATA_TYPE']); + + if ('' !== $dbType && !$platform->hasDoctrineTypeMappingFor($dbType)) { + $platform->registerDoctrineTypeMapping($dbType, DummyType::NAME); + } + } + } +} diff --git a/src/Webfactory/Slimdump/Doctrine/DummyTypeRegistrationEventSubscriber.php b/src/Webfactory/Slimdump/Doctrine/DummyTypeRegistrationEventSubscriber.php deleted file mode 100644 index d279717..0000000 --- a/src/Webfactory/Slimdump/Doctrine/DummyTypeRegistrationEventSubscriber.php +++ /dev/null @@ -1,50 +0,0 @@ -schemaManager = $schemaManager; - } - - public function getSubscribedEvents(): array - { - return [Events::onSchemaColumnDefinition]; - } - - public function onSchemaColumnDefinition(SchemaColumnDefinitionEventArgs $event): void - { - $tableColumn = array_change_key_case($event->getTableColumn(), \CASE_LOWER); - $dbType = strtolower($tableColumn['type']); - $dbType = strtok($dbType, '(), '); - - if (isset($tableColumn['comment'])) { - $type = $this->schemaManager->extractDoctrineTypeFromComment($tableColumn['comment'], ''); - - if ($type && !Type::hasType($type)) { - Type::addType($type, DummyType::class); - } - } - - $databasePlatform = $this->schemaManager->getDatabasePlatform(); - if (!$databasePlatform->hasDoctrineTypeMappingFor($dbType)) { - if (!Type::hasType(DummyType::NAME)) { - Type::addType(DummyType::NAME, DummyType::class); - } - $databasePlatform->registerDoctrineTypeMapping($dbType, DummyType::NAME); - } - } -} diff --git a/src/Webfactory/Slimdump/SlimdumpCommand.php b/src/Webfactory/Slimdump/SlimdumpCommand.php index 7646962..3c10ab2 100644 --- a/src/Webfactory/Slimdump/SlimdumpCommand.php +++ b/src/Webfactory/Slimdump/SlimdumpCommand.php @@ -18,7 +18,7 @@ use Webfactory\Slimdump\Database\CsvOutputFormatDriver; use Webfactory\Slimdump\Database\MysqlOutputFormatDriver; use Webfactory\Slimdump\Database\OutputFormatDriverInterface; -use Webfactory\Slimdump\Doctrine\DummyTypeRegistrationEventSubscriber; +use Webfactory\Slimdump\Doctrine\DummyTypeRegistration; final class SlimdumpCommand extends Command { @@ -71,12 +71,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int $connection = $this->createConnection($input); - // In DBAL 3, the SchemaManager parses DC2Type column comments and throws when encountering - // unknown types. We register a DummyType for any unknown type to work around this. - // In DBAL 4, the DC2Type comment mechanism was removed entirely, so this is no longer needed. - if (class_exists(\Doctrine\DBAL\Events::class)) { - $connection->getEventManager()->addEventSubscriber(new DummyTypeRegistrationEventSubscriber($connection->createSchemaManager())); - } + DummyTypeRegistration::register($connection); $this->setMaxExecutionTimeUnlimited($connection, $progressOutput); diff --git a/test/Webfactory/Slimdump/Doctrine/DummyTypeRegistrationTest.php b/test/Webfactory/Slimdump/Doctrine/DummyTypeRegistrationTest.php new file mode 100644 index 0000000..b476ea0 --- /dev/null +++ b/test/Webfactory/Slimdump/Doctrine/DummyTypeRegistrationTest.php @@ -0,0 +1,48 @@ +createMock(AbstractPlatform::class); + $platform->method('hasDoctrineTypeMappingFor')->willReturnMap([ + ['int', true], + ['enum', false], + ]); + $platform->expects($this->once()) + ->method('registerDoctrineTypeMapping') + ->with('enum', DummyType::NAME); + + $connection = $this->createMock(Connection::class); + $connection->method('getDatabasePlatform')->willReturn($platform); + $connection->method('getDatabase')->willReturn('my_schema'); + $connection->method('fetchAllAssociative')->willReturn([ + ['DATA_TYPE' => 'int'], + ['DATA_TYPE' => 'enum'], + ]); + + DummyTypeRegistration::register($connection); + } + + #[Test] + public function returnsEarlyWhenSchemaNameIsNull(): void + { + $platform = $this->createMock(AbstractPlatform::class); + $platform->expects($this->never())->method('registerDoctrineTypeMapping'); + + $connection = $this->createMock(Connection::class); + $connection->method('getDatabasePlatform')->willReturn($platform); + $connection->method('getDatabase')->willReturn(null); + $connection->expects($this->never())->method('fetchAllAssociative'); + + DummyTypeRegistration::register($connection); + } +} From 46dcc33fd6a50790edd135d06744d46e4d0d7592 Mon Sep 17 00:00:00 2001 From: func0der <529819+func0der@users.noreply.github.com> Date: Fri, 3 Jul 2026 15:01:32 +0200 Subject: [PATCH 2/2] GH-126 fix-php-cs-fixer Fix php cs fixer --- .github/workflows/fix-cs-php.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/fix-cs-php.yml b/.github/workflows/fix-cs-php.yml index 81e45f4..7b7449c 100644 --- a/.github/workflows/fix-cs-php.yml +++ b/.github/workflows/fix-cs-php.yml @@ -17,8 +17,6 @@ jobs: steps: - name: Checkout code uses: actions/checkout@v6 - with: - ref: ${{ github.head_ref }} - name: Run PHP-CS-Fixer uses: docker://ghcr.io/php-cs-fixer/php-cs-fixer:3.62.0-php8.3