From 6c757b11e0125892ca215cc82667daebbe787626 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Biarda?= <1135380+michalbiarda@users.noreply.github.com> Date: Wed, 13 May 2026 17:31:38 +0200 Subject: [PATCH] fix(database): use SchemaRegistry in DiffCommand and MigrateCommand for extender merge MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Single-pass buildEntitySchema loop called schemaBuilder->build() per entity independently, so extender columns (Table(extends:)) were never merged into the parent table schema. Commands saw extender columns as missing from the entity definition — reporting existing ones as destructive drops and never generating ADD COLUMN for new ones. Replaced the loop with SchemaRegistry::registerEntities(), which already implements the correct two-pass merge. Removed the now-unused EntityMetadataFactory and SchemaBuilder constructor dependencies from both commands; updated test helpers accordingly. Co-Authored-By: Claude Sonnet 4.6 --- packages/database/src/Command/DiffCommand.php | 17 +++++------------ .../database/src/Command/MigrateCommand.php | 17 +++++------------ packages/database/tests/Command/Helpers.php | 4 ++-- .../tests/Command/MigrateCommandTest.php | 7 +++---- 4 files changed, 15 insertions(+), 30 deletions(-) diff --git a/packages/database/src/Command/DiffCommand.php b/packages/database/src/Command/DiffCommand.php index fcbee57f..0996a3f9 100644 --- a/packages/database/src/Command/DiffCommand.php +++ b/packages/database/src/Command/DiffCommand.php @@ -13,10 +13,9 @@ use Marko\Database\Diff\SchemaDiff; use Marko\Database\Diff\TableDiff; use Marko\Database\Entity\EntityDiscovery; -use Marko\Database\Entity\EntityMetadataFactory; -use Marko\Database\Entity\SchemaBuilder; use Marko\Database\Exceptions\EntityException; use Marko\Database\Introspection\IntrospectorInterface; +use Marko\Database\Schema\SchemaRegistry; use Marko\Database\Schema\Table; /** @noinspection PhpUnused */ @@ -26,8 +25,7 @@ public function __construct( private EntityDiscovery $discovery, private IntrospectorInterface $introspector, - private EntityMetadataFactory $metadataFactory, - private SchemaBuilder $schemaBuilder, + private SchemaRegistry $schemaRegistry, private DiffCalculator $diffCalculator, private ProjectPaths $paths, ) {} @@ -77,15 +75,10 @@ public function execute( private function buildEntitySchema( array $entityClasses, ): array { - $schema = []; - - foreach ($entityClasses as $entityClass) { - $metadata = $this->metadataFactory->parse($entityClass); - $table = $this->schemaBuilder->build($metadata); - $schema[$table->name] = $table; - } + $this->schemaRegistry->clear(); + $this->schemaRegistry->registerEntities($entityClasses); - return $schema; + return $this->schemaRegistry->getTables(); } /** diff --git a/packages/database/src/Command/MigrateCommand.php b/packages/database/src/Command/MigrateCommand.php index d5bad656..0e47e678 100644 --- a/packages/database/src/Command/MigrateCommand.php +++ b/packages/database/src/Command/MigrateCommand.php @@ -13,14 +13,13 @@ use Marko\Database\Diff\SchemaDiff; use Marko\Database\Diff\SqlGeneratorInterface; use Marko\Database\Entity\EntityDiscovery; -use Marko\Database\Entity\EntityMetadataFactory; -use Marko\Database\Entity\SchemaBuilder; use Marko\Database\Exceptions\EntityException; use Marko\Database\Exceptions\MigrationException; use Marko\Database\Introspection\IntrospectorInterface; use Marko\Database\Migration\DataMigrator; use Marko\Database\Migration\MigrationGenerator; use Marko\Database\Migration\Migrator; +use Marko\Database\Schema\SchemaRegistry; use Marko\Database\Schema\Table; /** @noinspection PhpUnused */ @@ -33,8 +32,7 @@ public function __construct( private MigrationGenerator $migrationGenerator, private EntityDiscovery $entityDiscovery, private IntrospectorInterface $introspector, - private EntityMetadataFactory $metadataFactory, - private SchemaBuilder $schemaBuilder, + private SchemaRegistry $schemaRegistry, private DiffCalculator $diffCalculator, private SqlGeneratorInterface $sqlGenerator, private ProjectPaths $paths, @@ -251,15 +249,10 @@ private function calculateDiff(): SchemaDiff private function buildEntitySchema( array $entityClasses, ): array { - $schema = []; - - foreach ($entityClasses as $entityClass) { - $metadata = $this->metadataFactory->parse($entityClass); - $table = $this->schemaBuilder->build($metadata); - $schema[$table->name] = $table; - } + $this->schemaRegistry->clear(); + $this->schemaRegistry->registerEntities($entityClasses); - return $schema; + return $this->schemaRegistry->getTables(); } /** diff --git a/packages/database/tests/Command/Helpers.php b/packages/database/tests/Command/Helpers.php index 4e750fe0..5b6e9190 100644 --- a/packages/database/tests/Command/Helpers.php +++ b/packages/database/tests/Command/Helpers.php @@ -14,6 +14,7 @@ use Marko\Database\Entity\EntityDiscovery; use Marko\Database\Entity\EntityMetadataFactory; use Marko\Database\Entity\SchemaBuilder; +use Marko\Database\Schema\SchemaRegistry; use Marko\Database\Introspection\IntrospectorInterface; use Marko\Database\Schema\Table; @@ -229,8 +230,7 @@ public static function createDiffCommand( return new DiffCommand( discovery: self::createStubEntityDiscovery(), introspector: self::createStubIntrospector($tables), - metadataFactory: new EntityMetadataFactory(), - schemaBuilder: new SchemaBuilder(), + schemaRegistry: new SchemaRegistry(new EntityMetadataFactory(), new SchemaBuilder()), diffCalculator: $diffCalculator ?? new DiffCalculator(), paths: new ProjectPaths('/test'), ); diff --git a/packages/database/tests/Command/MigrateCommandTest.php b/packages/database/tests/Command/MigrateCommandTest.php index 34b9c4de..2847f127 100644 --- a/packages/database/tests/Command/MigrateCommandTest.php +++ b/packages/database/tests/Command/MigrateCommandTest.php @@ -12,6 +12,7 @@ use Marko\Database\Diff\SqlGeneratorInterface; use Marko\Database\Entity\EntityMetadataFactory; use Marko\Database\Entity\SchemaBuilder; +use Marko\Database\Schema\SchemaRegistry; use Marko\Database\Exceptions\MigrationException; use Marko\Database\Migration\DataMigrator; use Marko\Database\Migration\MigrationGenerator; @@ -304,8 +305,7 @@ function createMigrateCommand( migrationGenerator: $generator ?? createMigrationGeneratorStub(), entityDiscovery: Helpers::createStubEntityDiscovery(), introspector: Helpers::createStubIntrospector(), - metadataFactory: new EntityMetadataFactory(), - schemaBuilder: new SchemaBuilder(), + schemaRegistry: new SchemaRegistry(new EntityMetadataFactory(), new SchemaBuilder()), diffCalculator: createMigrateDiffCalculator($diff ?? new SchemaDiff()), sqlGenerator: $sqlGenerator ?? createMigrateSqlGenerator(), paths: new ProjectPaths('/test'), @@ -684,8 +684,7 @@ function executeMigrateCommand( migrationGenerator: $generator, entityDiscovery: Helpers::createStubEntityDiscovery(), introspector: $introspector, - metadataFactory: new EntityMetadataFactory(), - schemaBuilder: new SchemaBuilder(), + schemaRegistry: new SchemaRegistry(new EntityMetadataFactory(), new SchemaBuilder()), diffCalculator: new DiffCalculator(), sqlGenerator: createMigrateSqlGenerator(), paths: new ProjectPaths('/test'),