From 5678e89eda6832a55522b92da026162e41cbbcd3 Mon Sep 17 00:00:00 2001 From: kastahov Date: Sat, 14 Jan 2023 13:50:59 +0200 Subject: [PATCH 1/5] Fixes that the JTI parent has fields from JTI's --- src/TableInheritance.php | 15 +++++++ tests/Annotated/Fixtures/Fixtures21/Buyer.php | 26 +++++++++++ .../Fixtures/Fixtures21/Employee.php | 23 ++++++++++ .../Annotated/Fixtures/Fixtures21/Person.php | 30 +++++++++++++ .../Common/Inheritance/JoinedTableTest.php | 43 +++++++++++++++++++ 5 files changed, 137 insertions(+) create mode 100644 tests/Annotated/Fixtures/Fixtures21/Buyer.php create mode 100644 tests/Annotated/Fixtures/Fixtures21/Employee.php create mode 100644 tests/Annotated/Fixtures/Fixtures21/Person.php diff --git a/src/TableInheritance.php b/src/TableInheritance.php index 6cc1cb7d..0137b92f 100644 --- a/src/TableInheritance.php +++ b/src/TableInheritance.php @@ -85,6 +85,7 @@ public function run(Registry $registry): Registry $this->removeStiExtraFields($entity, $allowedEntities); } elseif ($entity->getInheritance() instanceof JoinedTableInheritanceSchema) { $this->removeJtiExtraFields($entity); + $this->removeJtiFieldsFromParent($entity); $this->addForeignKey($this->parseMetadata($entity, Inheritance::class), $entity, $registry); } } @@ -190,6 +191,20 @@ private function removeJtiExtraFields(EntitySchema $entity): void } } + /** + * Removes JTI fields from parent + */ + public function removeJtiFieldsFromParent(EntitySchema $entity) + { + $parent = $entity->getInheritance()->getParent()->getFields(); + + foreach ($entity->getFields() as $name => $field) { + if (!$field->isPrimary() && $parent->hasColumn($name)) { + $parent->remove($name); + } + } + } + /** * Removes non STI child entity fields from given entity. */ diff --git a/tests/Annotated/Fixtures/Fixtures21/Buyer.php b/tests/Annotated/Fixtures/Fixtures21/Buyer.php new file mode 100644 index 00000000..5edceeb3 --- /dev/null +++ b/tests/Annotated/Fixtures/Fixtures21/Buyer.php @@ -0,0 +1,26 @@ + [__DIR__ . '/../../../../Fixtures/Fixtures21'], + 'exclude' => [], + ]) + ); + + $locator = $tokenizer->classLocator(); + + $r = new Registry($this->dbal); + + $schema = (new Compiler())->compile($r, [ + new ResetTables(), + new Embeddings($locator, $reader), + new Entities($locator, $reader), + new TableInheritance($reader), + new MergeColumns($reader), + new GenerateRelations(), + new RenderTables(), + new RenderRelations(), + new MergeIndexes($reader), + new SyncTables(), + new GenerateTypecast(), + ]); + + $this->assertNotEmpty($schema); + + $this->assertArrayHasKey(SchemaInterface::COLUMNS, $schema['person']); + + // assert that parent doesn't have jti columns + $this->assertSame([ + 'id' => 'id', + 'name' => 'name', + 'type' => 'type' + ], $schema['person'][SchemaInterface::COLUMNS]); + } } From 28e6f9d209d7337646f27ab9cc257c7b4465e2b2 Mon Sep 17 00:00:00 2001 From: kastahov Date: Sat, 14 Jan 2023 21:15:42 +0200 Subject: [PATCH 2/5] Fixes parent columns deletion if jti has jti --- src/Entities.php | 2 +- src/TableInheritance.php | 17 +++++++++----- tests/Annotated/Fixtures/Fixtures21/Buyer.php | 6 ++--- .../Fixtures/Fixtures21/Employee.php | 13 +++++------ .../Fixtures/Fixtures21/Executive.php | 22 +++++++++++++++++++ .../Annotated/Fixtures/Fixtures21/Person.php | 4 ++-- .../Common/Inheritance/JoinedTableTest.php | 2 +- 7 files changed, 46 insertions(+), 20 deletions(-) create mode 100644 tests/Annotated/Fixtures/Fixtures21/Executive.php diff --git a/src/Entities.php b/src/Entities.php index 767b29ac..780d7248 100644 --- a/src/Entities.php +++ b/src/Entities.php @@ -157,7 +157,7 @@ private function resolveTarget(Registry $registry, string $name): ?string return $name; } - if (! $registry->hasEntity($name)) { + if (!$registry->hasEntity($name)) { // point all relations to the parent foreach ($registry as $entity) { foreach ($registry->getChildren($entity) as $child) { diff --git a/src/TableInheritance.php b/src/TableInheritance.php index 0137b92f..05929c77 100644 --- a/src/TableInheritance.php +++ b/src/TableInheritance.php @@ -85,7 +85,7 @@ public function run(Registry $registry): Registry $this->removeStiExtraFields($entity, $allowedEntities); } elseif ($entity->getInheritance() instanceof JoinedTableInheritanceSchema) { $this->removeJtiExtraFields($entity); - $this->removeJtiFieldsFromParent($entity); + $this->removeJtiFieldsFromParent($registry, $entity); $this->addForeignKey($this->parseMetadata($entity, Inheritance::class), $entity, $registry); } } @@ -194,13 +194,18 @@ private function removeJtiExtraFields(EntitySchema $entity): void /** * Removes JTI fields from parent */ - public function removeJtiFieldsFromParent(EntitySchema $entity) + public function removeJtiFieldsFromParent(Registry $registry, EntitySchema $child) { - $parent = $entity->getInheritance()->getParent()->getFields(); + $parent = $this->findParent( + $registry, + $this->utils->findParent($child->getClass()) + ); - foreach ($entity->getFields() as $name => $field) { - if (!$field->isPrimary() && $parent->hasColumn($name)) { - $parent->remove($name); + $fields = $parent->getFields(); + + foreach ($child->getFields() as $name => $field) { + if (!$field->isPrimary() && $fields->hasColumn($name)) { + $fields->remove($name); } } } diff --git a/tests/Annotated/Fixtures/Fixtures21/Buyer.php b/tests/Annotated/Fixtures/Fixtures21/Buyer.php index 5edceeb3..d66ca281 100644 --- a/tests/Annotated/Fixtures/Fixtures21/Buyer.php +++ b/tests/Annotated/Fixtures/Fixtures21/Buyer.php @@ -6,14 +6,14 @@ use Cycle\Annotated\Annotation\Column; use Cycle\Annotated\Annotation\Entity; -use Cycle\Annotated\Annotation\Inheritance\JoinedTable as InheritanceJoinedTable; +use Cycle\Annotated\Annotation\Inheritance\JoinedTable; /** * @Entity - * @InheritanceJoinedTable(fkCreate=false) + * @JoinedTable */ #[Entity] -#[InheritanceJoinedTable(fkCreate: false)] +#[JoinedTable] class Buyer extends Person { /** @Column(type="string") */ diff --git a/tests/Annotated/Fixtures/Fixtures21/Employee.php b/tests/Annotated/Fixtures/Fixtures21/Employee.php index 87aaa682..6af918e3 100644 --- a/tests/Annotated/Fixtures/Fixtures21/Employee.php +++ b/tests/Annotated/Fixtures/Fixtures21/Employee.php @@ -2,22 +2,21 @@ declare(strict_types=1); -namespace Annotated\Fixtures\Fixtures21; +namespace Cycle\Annotated\Tests\Fixtures\Fixtures21; use Cycle\Annotated\Annotation\Column; use Cycle\Annotated\Annotation\Entity; -use Cycle\Annotated\Annotation\Inheritance\SingleTable as InheritanceSingleTable; -use Cycle\Annotated\Tests\Fixtures\Fixtures20\Person; +use Cycle\Annotated\Annotation\Inheritance\JoinedTable; /** * @Entity - * @InheritanceSingleTable + * @JoinedTable */ #[Entity] -#[InheritanceSingleTable] +#[JoinedTable] class Employee extends Person { - /** @Column(type="int") */ - #[Column(type: 'int')] + /** @Column(type="integer") */ + #[Column(type: 'integer')] public int $salary; } diff --git a/tests/Annotated/Fixtures/Fixtures21/Executive.php b/tests/Annotated/Fixtures/Fixtures21/Executive.php new file mode 100644 index 00000000..93b38e63 --- /dev/null +++ b/tests/Annotated/Fixtures/Fixtures21/Executive.php @@ -0,0 +1,22 @@ +assertSame([ 'id' => 'id', 'name' => 'name', - 'type' => 'type' + 'type' => 'type', ], $schema['person'][SchemaInterface::COLUMNS]); } } From 6f3110e90e0cbbe3975fcff375805957c3373812 Mon Sep 17 00:00:00 2001 From: Maxim Smakouz Date: Wed, 18 Jan 2023 22:08:54 +0200 Subject: [PATCH 3/5] Remove DiscriminatorColumn --- tests/Annotated/Fixtures/Fixtures21/Person.php | 3 --- 1 file changed, 3 deletions(-) diff --git a/tests/Annotated/Fixtures/Fixtures21/Person.php b/tests/Annotated/Fixtures/Fixtures21/Person.php index 7784f2bd..b1fd807e 100644 --- a/tests/Annotated/Fixtures/Fixtures21/Person.php +++ b/tests/Annotated/Fixtures/Fixtures21/Person.php @@ -6,14 +6,11 @@ use Cycle\Annotated\Annotation\Column; use Cycle\Annotated\Annotation\Entity; -use Cycle\Annotated\Annotation\Inheritance\DiscriminatorColumn; /** * @Entity - * @DiscriminatorColumn(name="type") */ #[Entity] -#[DiscriminatorColumn(name: 'type')] class Person { /** @Column(type="bigInteger", primary="true") */ From 982a5a910f6b1dbb0a768154fbb99a3cefa370d2 Mon Sep 17 00:00:00 2001 From: Maxim Smakouz Date: Wed, 18 Jan 2023 23:37:05 +0200 Subject: [PATCH 4/5] Fix parent in JTI --- composer.json | 2 +- src/Entities.php | 2 +- src/TableInheritance.php | 22 +------ .../Annotated/Fixtures/Fixtures21/Person.php | 4 +- .../Common/Inheritance/JoinedTableTest.php | 57 ++++++------------- 5 files changed, 23 insertions(+), 64 deletions(-) diff --git a/composer.json b/composer.json index 6e3c754e..0ee13779 100644 --- a/composer.json +++ b/composer.json @@ -8,7 +8,7 @@ "require": { "php": ">=8.0", "cycle/orm": "^2.2.0", - "cycle/schema-builder": "^2.1.0", + "cycle/schema-builder": "dev-register-child-without-merge", "doctrine/annotations": "^1.13", "spiral/attributes": "^2.8|^3.0", "spiral/tokenizer": "^2.8|^3.0", diff --git a/src/Entities.php b/src/Entities.php index 780d7248..a90ab4a0 100644 --- a/src/Entities.php +++ b/src/Entities.php @@ -81,7 +81,7 @@ public function run(Registry $registry): Registry } foreach ($children as $e) { - $registry->registerChild($registry->getEntity($this->utils->findParent($e->getClass())), $e); + $registry->registerChildWithoutMerge($registry->getEntity($this->utils->findParent($e->getClass())), $e); } return $this->normalizeNames($registry); diff --git a/src/TableInheritance.php b/src/TableInheritance.php index 05929c77..327d8dfe 100644 --- a/src/TableInheritance.php +++ b/src/TableInheritance.php @@ -85,7 +85,6 @@ public function run(Registry $registry): Registry $this->removeStiExtraFields($entity, $allowedEntities); } elseif ($entity->getInheritance() instanceof JoinedTableInheritanceSchema) { $this->removeJtiExtraFields($entity); - $this->removeJtiFieldsFromParent($registry, $entity); $this->addForeignKey($this->parseMetadata($entity, Inheritance::class), $entity, $registry); } } @@ -134,6 +133,8 @@ private function initInheritance( $parent->getInheritance()->setDiscriminator($annotation->getName()); } + $parent->merge($entity); + return $parent; } if ($inheritance instanceof Inheritance\JoinedTable) { @@ -191,25 +192,6 @@ private function removeJtiExtraFields(EntitySchema $entity): void } } - /** - * Removes JTI fields from parent - */ - public function removeJtiFieldsFromParent(Registry $registry, EntitySchema $child) - { - $parent = $this->findParent( - $registry, - $this->utils->findParent($child->getClass()) - ); - - $fields = $parent->getFields(); - - foreach ($child->getFields() as $name => $field) { - if (!$field->isPrimary() && $fields->hasColumn($name)) { - $fields->remove($name); - } - } - } - /** * Removes non STI child entity fields from given entity. */ diff --git a/tests/Annotated/Fixtures/Fixtures21/Person.php b/tests/Annotated/Fixtures/Fixtures21/Person.php index b1fd807e..80f1695e 100644 --- a/tests/Annotated/Fixtures/Fixtures21/Person.php +++ b/tests/Annotated/Fixtures/Fixtures21/Person.php @@ -13,8 +13,8 @@ #[Entity] class Person { - /** @Column(type="bigInteger", primary="true") */ - #[Column(type: 'bigInteger', primary: true)] + /** @Column(type="primary") */ + #[Column(type: 'primary')] protected int $id; /** @Column(type="string") */ diff --git a/tests/Annotated/Functional/Driver/Common/Inheritance/JoinedTableTest.php b/tests/Annotated/Functional/Driver/Common/Inheritance/JoinedTableTest.php index 56537480..d580367e 100644 --- a/tests/Annotated/Functional/Driver/Common/Inheritance/JoinedTableTest.php +++ b/tests/Annotated/Functional/Driver/Common/Inheritance/JoinedTableTest.php @@ -193,49 +193,37 @@ public function testAddIndex(ReaderInterface $reader): void $this->assertTrue(end($indexes)->isUnique()); } - private function compile(ReaderInterface $reader): array + /** + * @dataProvider allReadersProvider + */ + public function testJtiParentColumns(ReaderInterface $reader): void { - $tokenizer = new Tokenizer( - new TokenizerConfig([ - 'directories' => [__DIR__ . '/../../../../Fixtures/Fixtures16'], - 'exclude' => [], - ]) - ); + $schema = $this->compile($reader, 'Fixtures21'); - $locator = $tokenizer->classLocator(); + $this->assertNotEmpty($schema); - return (new Compiler())->compile(new Registry($this->dbal), [ - new ResetTables(), - new Embeddings($locator, $reader), - new Entities($locator, $reader), - new TableInheritance($reader), - new MergeColumns($reader), - new GenerateRelations(), - new RenderTables(), - new RenderRelations(), - new MergeIndexes($reader), - new SyncTables(), - new GenerateTypecast(), - ]); + $this->assertArrayHasKey(SchemaInterface::COLUMNS, $schema['person']); + + // assert that parent doesn't have jti columns + $this->assertSame([ + 'id' => 'id', + 'name' => 'name', + 'type' => 'type', + ], $schema['person'][SchemaInterface::COLUMNS]); } - /** - * @dataProvider allReadersProvider - */ - public function testJtiParentColumns(ReaderInterface $reader) + private function compile(ReaderInterface $reader, string $fixtures = 'Fixtures16'): array { $tokenizer = new Tokenizer( new TokenizerConfig([ - 'directories' => [__DIR__ . '/../../../../Fixtures/Fixtures21'], + 'directories' => [sprintf(__DIR__ . '/../../../../Fixtures/%s', $fixtures)], 'exclude' => [], ]) ); $locator = $tokenizer->classLocator(); - $r = new Registry($this->dbal); - - $schema = (new Compiler())->compile($r, [ + return (new Compiler())->compile(new Registry($this->dbal), [ new ResetTables(), new Embeddings($locator, $reader), new Entities($locator, $reader), @@ -248,16 +236,5 @@ public function testJtiParentColumns(ReaderInterface $reader) new SyncTables(), new GenerateTypecast(), ]); - - $this->assertNotEmpty($schema); - - $this->assertArrayHasKey(SchemaInterface::COLUMNS, $schema['person']); - - // assert that parent doesn't have jti columns - $this->assertSame([ - 'id' => 'id', - 'name' => 'name', - 'type' => 'type', - ], $schema['person'][SchemaInterface::COLUMNS]); } } From 8100751ea7faad01199a6dec866140299c4973a0 Mon Sep 17 00:00:00 2001 From: Maxim Smakouz Date: Thu, 19 Jan 2023 23:23:42 +0200 Subject: [PATCH 5/5] Up version of cycle/schema-builder --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index a25d95d0..c0590dc0 100644 --- a/composer.json +++ b/composer.json @@ -8,7 +8,7 @@ "require": { "php": ">=8.0", "cycle/orm": "^2.2.0", - "cycle/schema-builder": "^2.2", + "cycle/schema-builder": "^2.3", "doctrine/annotations": "^1.13 || ^2.0", "spiral/attributes": "^2.8|^3.0", "spiral/tokenizer": "^2.8|^3.0",