From 02315a3853b3828a871d7adadc2ca75d6a6661bd Mon Sep 17 00:00:00 2001 From: Matthias Pigulla Date: Thu, 18 Jan 2024 13:44:36 +0100 Subject: [PATCH] Fill in dummy types to deal with DC2:... column comments (#102) We're using the `SchemaManager` to simplify listing tables, views and so on. But, the information provided by it also includes the DBAL types used for columns, and that information may be parsed from column comments in the database. The problem is that a table definition like so: ```sql CREATE TABLE `test` ( `some_col` int NOT NULL COMMENT '(DC2Type:some_type)' ) ``` ... `slimdump` fail fail with an exception because it does not know about the `some_type`. This type may be available and defined in your application, but we cannot put it into the `slimdump` command. Now, in fact, we don't care about the type and its conversion capabilities at all. So, this PR adds a runtime "just in type" registration of a `DummyType` that serves as a placeholder to avoid issues when loading the schema. Fixes #96. --- composer.json | 3 +- composer.lock | 23 +++++---- .../Slimdump/Doctrine/DummyType.php | 27 ++++++++++ .../DummyTypeRegistrationEventSubscriber.php | 50 +++++++++++++++++++ src/Webfactory/Slimdump/SlimdumpCommand.php | 3 +- 5 files changed, 93 insertions(+), 13 deletions(-) create mode 100644 src/Webfactory/Slimdump/Doctrine/DummyType.php create mode 100644 src/Webfactory/Slimdump/Doctrine/DummyTypeRegistrationEventSubscriber.php diff --git a/composer.json b/composer.json index ffc6e3e..ac0f4b2 100644 --- a/composer.json +++ b/composer.json @@ -16,10 +16,11 @@ ], "require": { "php": "^7.2|8.0.*|8.1.*", + "ext-SimpleXML": "*", "ext-libxml": "*", "ext-pdo": "*", - "ext-SimpleXML": "*", "doctrine/dbal": "^2.5.2", + "doctrine/event-manager": "^1.0", "fakerphp/faker": "^1.6", "symfony/console": "^4.0|^5.0|^6.0", "symfony/service-contracts": "^2.1.2" diff --git a/composer.lock b/composer.lock index 4759e3c..40f2fed 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "c6cdadfe7ae30a08e74f2be143357ba1", + "content-hash": "144ae8d95e365b5a7a939f8e9492da5e", "packages": [ { "name": "doctrine/cache", @@ -253,34 +253,35 @@ }, { "name": "doctrine/event-manager", - "version": "1.1.2", + "version": "1.2.0", "source": { "type": "git", "url": "https://github.com/doctrine/event-manager.git", - "reference": "eb2ecf80e3093e8f3c2769ac838e27d8ede8e683" + "reference": "95aa4cb529f1e96576f3fda9f5705ada4056a520" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/event-manager/zipball/eb2ecf80e3093e8f3c2769ac838e27d8ede8e683", - "reference": "eb2ecf80e3093e8f3c2769ac838e27d8ede8e683", + "url": "https://api.github.com/repos/doctrine/event-manager/zipball/95aa4cb529f1e96576f3fda9f5705ada4056a520", + "reference": "95aa4cb529f1e96576f3fda9f5705ada4056a520", "shasum": "" }, "require": { + "doctrine/deprecations": "^0.5.3 || ^1", "php": "^7.1 || ^8.0" }, "conflict": { "doctrine/common": "<2.9" }, "require-dev": { - "doctrine/coding-standard": "^9", - "phpstan/phpstan": "~1.4.10 || ^1.5.4", + "doctrine/coding-standard": "^9 || ^10", + "phpstan/phpstan": "~1.4.10 || ^1.8.8", "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", - "vimeo/psalm": "^4.22" + "vimeo/psalm": "^4.24" }, "type": "library", "autoload": { "psr-4": { - "Doctrine\\Common\\": "lib/Doctrine/Common" + "Doctrine\\Common\\": "src" } }, "notification-url": "https://packagist.org/downloads/", @@ -2707,9 +2708,9 @@ "prefer-lowest": false, "platform": { "php": "^7.2|8.0.*|8.1.*", + "ext-simplexml": "*", "ext-libxml": "*", - "ext-pdo": "*", - "ext-simplexml": "*" + "ext-pdo": "*" }, "platform-dev": [], "plugin-api-version": "2.1.0" diff --git a/src/Webfactory/Slimdump/Doctrine/DummyType.php b/src/Webfactory/Slimdump/Doctrine/DummyType.php new file mode 100644 index 0000000..2ee07ca --- /dev/null +++ b/src/Webfactory/Slimdump/Doctrine/DummyType.php @@ -0,0 +1,27 @@ +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 5861f77..750a260 100644 --- a/src/Webfactory/Slimdump/SlimdumpCommand.php +++ b/src/Webfactory/Slimdump/SlimdumpCommand.php @@ -18,6 +18,7 @@ use Webfactory\Slimdump\Database\CsvOutputFormatDriver; use Webfactory\Slimdump\Database\MysqlOutputFormatDriver; use Webfactory\Slimdump\Database\OutputFormatDriverInterface; +use Webfactory\Slimdump\Doctrine\DummyTypeRegistrationEventSubscriber; final class SlimdumpCommand extends Command { @@ -74,7 +75,7 @@ protected function execute(InputInterface $input, OutputInterface $output) $progressOutput = $this->createProgressOutput($input, $output); $connection = $this->createConnection($input); - $connection->getDatabasePlatform()->registerDoctrineTypeMapping('enum', 'string'); + $connection->getEventManager()->addEventSubscriber(new DummyTypeRegistrationEventSubscriber($connection->getSchemaManager())); $this->setMaxExecutionTimeUnlimited($connection, $progressOutput); $config = ConfigBuilder::createConfigurationFromConsecutiveFiles($input->getArgument('config'));