From 4b53d8c0c5c680db9246cc2d4738a57eb39f82bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Poirier=20Th=C3=A9or=C3=AAt?= Date: Tue, 15 Oct 2024 19:49:46 -0400 Subject: [PATCH] [DoctrineExtra] New GenerateGraphSchemaCommand --- .docker/php/Dockerfile | 3 + Makefile | 2 + composer.json | 4 + doc/databse.svg | 926 ++++++++++++++++++ .../Command/GenerateGraphSchemaCommand.php | 75 ++ .../DoctrineExtraIntegrationTest.php | 7 + .../GenerateGraphSchemaCommandTest.php | 52 + 7 files changed, 1069 insertions(+) create mode 100644 doc/databse.svg create mode 100644 packages/doctrine-extra/ORM/Command/GenerateGraphSchemaCommand.php create mode 100644 tests/DoctrineExtra/ORM/Command/GenerateGraphSchemaCommandTest.php diff --git a/.docker/php/Dockerfile b/.docker/php/Dockerfile index 73ede6d8..53501f67 100755 --- a/.docker/php/Dockerfile +++ b/.docker/php/Dockerfile @@ -64,6 +64,9 @@ RUN apt-get update && apt-get install -y --no-install-recommends default-mysql-c #MONGODB RUN pecl install mongodb-1.17.2 && docker-php-ext-enable mongodb +#Graphviz +RUN apt-get update && apt-get install -y --no-install-recommends graphviz + ARG PUID=1000 ARG PGID=1000 diff --git a/Makefile b/Makefile index 90639c1d..4a0978ad 100644 --- a/Makefile +++ b/Makefile @@ -31,3 +31,5 @@ composer-normalize: sudo chmod a+x composer-normalize docker-compose exec php php composer-normalize +generate-artifact: + docker-compose exec php composer generate:artifact \ No newline at end of file diff --git a/composer.json b/composer.json index 74efcf40..b099e445 100644 --- a/composer.json +++ b/composer.json @@ -293,6 +293,10 @@ "test:run:coverage": [ "Composer\\Config::disableProcessTimeout", "vendor/bin/phpunit --coverage-html ./tmp/phpunit/report" + ], + "generate:artifact": [ + "Composer\\Config::disableProcessTimeout", + "bin/console draw:doctrine:generate-graph-schema | dot -Tsvg -o doc/databse.svg" ] }, "minimum-stability": "dev", diff --git a/doc/databse.svg b/doc/databse.svg new file mode 100644 index 00000000..36f147fc --- /dev/null +++ b/doc/databse.svg @@ -0,0 +1,926 @@ + + + + + + +draw + + + +acme__user_address:se->draw_acme__user:se + + + + + +draw_acme__user:se->draw_acme__base_object:se + + + + + +draw_acme__user:se->draw_acme__base_object:se + + + + + +draw_acme__user:se->draw_acme__base_object:se + + + + + +draw_acme__user:se->draw_acme__base_object:se + + + + + +draw_acme__user:se->draw_acme__base_object:se + + + + + +draw_acme__user:se->draw_acme__base_object:se + + + + + +draw_acme__user:se->draw_acme__base_object:se + + + + + +acme__user_tag:se->draw_acme__user:se + + + + + +acme__user_tag:se->draw_acme__tag:se + + + + + +cron_job__cron_job_execution:se->cron_job__cron_job:se + + + + + +user_tag:se->draw_acme__user:se + + + + + +user_tag:se->draw_acme__tag:se + + + + + +draw_messenger__message_tag:se->draw_messenger__message:se + + + + + +draw_user__user_lock:se->draw_acme__user:se + + + + + +import__column:se->import__import:se + + + + + +tag_translation:se->draw_acme__tag:se + + + + + +user_migration:se->draw_acme__user:se + + + + + +user_migration:se->draw_entity_migrator__migration:se + + + + + +acme__user_address + + +acme__user_address + +id + +integer + + + +user_id + +guid + + +position + +integer + + +address_street + +string + + +address_postal_code + +string + + +address_city + +string + + +address_country + +string + + + + + +draw_acme__user + + +draw_acme__user + +id + +guid + + + +child_object1_id + +integer + + +child_object2_id + +integer + + +on_delete_restrict_id + +integer + + +on_delete_cascade_id + +integer + + +on_delete_set_null_id + +integer + + +on_delete_cascade_config_overridden_id + +integer + + +on_delete_cascade_attribute_overridden_id + +integer + + +roles + +json + + +level + +string + + +date_of_birth + +datetime_immutable + + +comment + +text + + +preferred_locale + +string + + +email_auth_code + +string + + +email_auth_code_generated_at + +datetime_immutable + + +two_factor_authentication_enabled_providers + +json + + +force_enabling_two_factor_authentication + +boolean + + +totp_secret + +string + + +manual_lock + +boolean + + +need_change_password + +boolean + + +email + +string + + +password + +string + + +last_password_updated_at + +datetime_immutable + + +address_street + +string + + +address_postal_code + +string + + +address_city + +string + + +address_country + +string + + + + + +acme__user_tag + + +acme__user_tag + +id + +integer + + + +user_id + +guid + + +tag_id + +bigint + + + + + +draw_acme__tag + + +draw_acme__tag + +id + +bigint + + + +name + +string + + +active + +boolean + + + + + +command__execution + + +command__execution + +id + +guid + + + +command + +string + + +command_name + +string + + +state + +string + + +input + +json + + +output + +text + + +created_at + +datetime_immutable + + +updated_at + +datetime_immutable + + +auto_acknowledge_reason + +string + + + + + +cron_job__cron_job + + +cron_job__cron_job + +id + +integer + + + +name + +string + + +active + +boolean + + +command + +text + + +schedule + +string + + +time_to_live + +integer + + +execution_timeout + +integer + + +priority + +integer + + +notes + +text + + + + + +cron_job__cron_job_execution + + +cron_job__cron_job_execution + +id + +integer + + + +cron_job_id + +integer + + +requested_at + +datetime_immutable + + +state + +string + + +force + +boolean + + +execution_started_at + +datetime_immutable + + +execution_ended_at + +datetime_immutable + + +execution_delay + +integer + + +exit_code + +integer + + +error + +text + + + + + +draw__config + + +draw__config + +id + +string + + + +data + +json + + +updated_at + +datetime_immutable + + +created_at + +datetime_immutable + + + + + +draw_acme__base_object + + +draw_acme__base_object + +id + +integer + + + +discriminator_type + +string + + +attribute_1 + +string + + +date_time_immutable + +datetime_immutable + + +attribute_2 + +string + + + + + +user_tag + + +user_tag + +user_id + +guid + + + +tag_id + +bigint + + + + + + +draw_entity_migrator__migration + + +draw_entity_migrator__migration + +id + +integer + + + +name + +string + + +state + +string + + + + + +draw_messenger__message + + +draw_messenger__message + +id + +guid + + + +message_class + +string + + +body + +text + + +headers + +text + + +queue_name + +string + + +created_at + +datetime_immutable + + +available_at + +datetime_immutable + + +delivered_at + +datetime_immutable + + +expires_at + +datetime_immutable + + + + + +draw_messenger__message_tag + + +draw_messenger__message_tag + +name + +string + + + +message_id + +guid + + + + + + +draw_user__user_lock + + +draw_user__user_lock + +id + +guid + + + +user_id + +guid + + +reason + +string + + +created_at + +datetime_immutable + + +lock_on + +datetime_immutable + + +expires_at + +datetime_immutable + + +unlock_until + +datetime_immutable + + + + + +import__column + + +import__column + +id + +integer + + + +import_id + +integer + + +header_name + +string + + +sample + +text + + +is_identifier + +boolean + + +is_ignored + +boolean + + +mapped_to + +string + + +is_date + +boolean + + +created_at + +datetime + + +updated_at + +datetime + + + + + +import__import + + +import__import + +id + +integer + + + +entity_class + +string + + +insert_when_not_found + +boolean + + +file_content + +text + + +state + +string + + +created_at + +datetime + + +updated_at + +datetime + + + + + +tag_translation + + +tag_translation + +id + +integer + + + +translatable_id + +bigint + + +label + +string + + +locale + +string + + + + + +user_migration + + +user_migration + +id + +bigint + + + +entity_id + +guid + + +migration_id + +integer + + +state + +string + + +transition_logs + +json + + +created_at + +datetime_immutable + + + + + diff --git a/packages/doctrine-extra/ORM/Command/GenerateGraphSchemaCommand.php b/packages/doctrine-extra/ORM/Command/GenerateGraphSchemaCommand.php new file mode 100644 index 00000000..9c4ac595 --- /dev/null +++ b/packages/doctrine-extra/ORM/Command/GenerateGraphSchemaCommand.php @@ -0,0 +1,75 @@ +setName('draw:doctrine:generate-graph-schema') + ->setDescription('Get dot from database schema.') + ->setHelp(\sprintf('Usage: bin/console %s | dot -Tsvg -o /tmp/databse.svg', $this->getName())) + ; + } + + protected function execute(InputInterface $input, OutputInterface $output): int + { + $io = new SymfonyStyle($input, $output); + $io->writeln($this->getDot()); + + return Command::SUCCESS; + } + + /** + * Get dot from database schema. + */ + protected function getDot(): string + { + /** @var array> $metadata */ + $metadata = $this->entityManager->getMetadataFactory()->getAllMetadata(); + + usort($metadata, static fn (ClassMetadata $a, ClassMetadata $b): int => $a->getTableName() <=> $b->getTableName()); + + $tool = new SchemaTool($this->entityManager); + $schema = $tool->getSchemaFromMetadata($metadata); + + $visitor = new Graphviz(); + + $visitor->acceptSchema($schema); + + foreach ($schema->getTables() as $table) { + $visitor->acceptTable($table); + foreach ($table->getColumns() as $column) { + $visitor->acceptColumn($table, $column); + } + foreach ($table->getIndexes() as $index) { + $visitor->acceptIndex($table, $index); + } + foreach ($table->getForeignKeys() as $foreignKey) { + $visitor->acceptForeignKey($table, $foreignKey); + } + } + + foreach ($schema->getSequences() as $sequence) { + $visitor->acceptSequence($sequence); + } + + return $visitor->getOutput(); + } +} diff --git a/packages/doctrine-extra/Tests/DependencyInjection/DoctrineExtraIntegrationTest.php b/packages/doctrine-extra/Tests/DependencyInjection/DoctrineExtraIntegrationTest.php index 7320b5a8..10b271ff 100644 --- a/packages/doctrine-extra/Tests/DependencyInjection/DoctrineExtraIntegrationTest.php +++ b/packages/doctrine-extra/Tests/DependencyInjection/DoctrineExtraIntegrationTest.php @@ -8,6 +8,7 @@ use Draw\Component\DependencyInjection\Integration\Test\IntegrationTestCase; use Draw\Component\DependencyInjection\Integration\Test\ServiceConfiguration; use Draw\DoctrineExtra\DependencyInjection\DoctrineExtraIntegration; +use Draw\DoctrineExtra\ORM\Command\GenerateGraphSchemaCommand; use Draw\DoctrineExtra\ORM\Command\MysqlDumpCommand; use Draw\DoctrineExtra\ORM\Command\MysqlImportFileCommand; use Draw\DoctrineExtra\ORM\EntityHandler; @@ -76,6 +77,12 @@ public static function provideTestLoad(): iterable MysqlDumpCommand::class, ] ), + new ServiceConfiguration( + 'draw.doctrine_extra.orm.command.generate_graph_schema_command', + [ + GenerateGraphSchemaCommand::class, + ] + ), ], [ 'doctrine' => [ diff --git a/tests/DoctrineExtra/ORM/Command/GenerateGraphSchemaCommandTest.php b/tests/DoctrineExtra/ORM/Command/GenerateGraphSchemaCommandTest.php new file mode 100644 index 00000000..20b9befe --- /dev/null +++ b/tests/DoctrineExtra/ORM/Command/GenerateGraphSchemaCommandTest.php @@ -0,0 +1,52 @@ +execute([]) + ->test( + CommandDataTester::create() + ->setExpectedDisplay(null) + ) + ; + } +}