From 074e7d00cfe00a9893606538ef89c32b9729e5d0 Mon Sep 17 00:00:00 2001 From: Guillaume Date: Thu, 16 Jan 2020 14:10:38 +0100 Subject: [PATCH 1/4] Inheritance - FK save: test case --- tests/TDBMDaoGeneratorTest.php | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/tests/TDBMDaoGeneratorTest.php b/tests/TDBMDaoGeneratorTest.php index 1d18f56c..a141c871 100644 --- a/tests/TDBMDaoGeneratorTest.php +++ b/tests/TDBMDaoGeneratorTest.php @@ -62,6 +62,8 @@ use TheCodingMachine\TDBM\Test\Dao\Bean\Generated\BoatBaseBean; use TheCodingMachine\TDBM\Test\Dao\Bean\Generated\FileBaseBean; use TheCodingMachine\TDBM\Test\Dao\Bean\Generated\UserBaseBean; +use TheCodingMachine\TDBM\Test\Dao\Bean\InheritanceAgencyBean; +use TheCodingMachine\TDBM\Test\Dao\Bean\InheritanceSocietyBean; use TheCodingMachine\TDBM\Test\Dao\Bean\InheritedObjectBean; use TheCodingMachine\TDBM\Test\Dao\Bean\NodeBean; use TheCodingMachine\TDBM\Test\Dao\Bean\PersonBean; @@ -78,6 +80,8 @@ use TheCodingMachine\TDBM\Test\Dao\DogDao; use TheCodingMachine\TDBM\Test\Dao\FileDao; use TheCodingMachine\TDBM\Test\Dao\Generated\UserBaseDao; +use TheCodingMachine\TDBM\Test\Dao\InheritanceAgencyDao; +use TheCodingMachine\TDBM\Test\Dao\InheritanceSocietyDao; use TheCodingMachine\TDBM\Test\Dao\InheritedObjectDao; use TheCodingMachine\TDBM\Test\Dao\NodeDao; use TheCodingMachine\TDBM\Test\Dao\PersonDao; @@ -2208,4 +2212,15 @@ public function testFindFromRawSQLOnInheritance(): void $this->assertNotNull($objects->first()); $this->assertEquals(6, $objects->count()); } + + public function testInheritanceFkWithDifferentPkName(): void + { + $inheritanceSocietyDao = new InheritanceSocietyDao($this->tdbmService); + $inheritanceAgencyDao = new InheritanceAgencyDao($this->tdbmService); + $society = new InheritanceSocietyBean(); + $inheritanceSocietyDao->save($society); + $this->assertIsInt($society->getId()); + $agency = new InheritanceAgencyBean($society); + $inheritanceAgencyDao->save($agency); + } } From b32a138f28d92728fc2e1933df59d79b38dffc93 Mon Sep 17 00:00:00 2001 From: Guillaume Date: Thu, 16 Jan 2020 16:33:32 +0100 Subject: [PATCH 2/4] Inheritance - FK save: Ensure column name is the base one --- src/Utils/BeanDescriptor.php | 77 ++++++++++++++++++++++++------------ 1 file changed, 52 insertions(+), 25 deletions(-) diff --git a/src/Utils/BeanDescriptor.php b/src/Utils/BeanDescriptor.php index d7f73df4..24c2a79d 100644 --- a/src/Utils/BeanDescriptor.php +++ b/src/Utils/BeanDescriptor.php @@ -1223,7 +1223,6 @@ private function removeDuplicateIndexes(array $indexes): array private function generateFindByDaoCodeForIndex(Index $index, string $beanNamespace, string $beanClassName): ?MethodGenerator { $columns = $index->getColumns(); - $usedBeans = []; /** * The list of elements building this index (expressed as columns or foreign keys) @@ -1249,42 +1248,26 @@ private function generateFindByDaoCodeForIndex(Index $index, string $beanNamespa } $parameters = []; - //$functionParameters = []; $first = true; /** @var AbstractBeanPropertyDescriptor $element */ foreach ($elements as $element) { $parameter = new ParameterGenerator(ltrim($element->getSafeVariableName(), '$')); if (!$first && !($element->isCompulsory() && $index->isUnique())) { $parameterType = '?'; - //$functionParameter = '?'; } else { $parameterType = ''; - //$functionParameter = ''; } $parameterType .= $element->getPhpType(); $parameter->setType($parameterType); if (!$first && !($element->isCompulsory() && $index->isUnique())) { $parameter->setDefaultValue(null); } - //$functionParameter .= $element->getPhpType(); - $elementClassName = $element->getClassName(); - if ($elementClassName) { - $usedBeans[] = $beanNamespace.'\\'.$elementClassName; - } - //$functionParameter .= ' '.$element->getVariableName(); if ($first) { $first = false; - } /*else { - $functionParameter .= ' = null'; - }*/ - //$functionParameters[] = $functionParameter; + } $parameters[] = $parameter; } - //$functionParametersString = implode(', ', $functionParameters); - - $count = 0; - $params = []; $filterArrayCode = ''; $commentArguments = []; @@ -1306,12 +1289,11 @@ private function generateFindByDaoCodeForIndex(Index $index, string $beanNamespa } elseif ($element instanceof ObjectBeanPropertyDescriptor) { $foreignKey = $element->getForeignKey(); $columns = SafeFunctions::arrayCombine($foreignKey->getLocalColumns(), $foreignKey->getForeignColumns()); - ++$count; $foreignTable = $this->schema->getTable($foreignKey->getForeignTableName()); foreach ($columns as $localColumn => $foreignColumn) { // TODO: a foreign key could point to another foreign key. In this case, there is no getter for the pointed column. We don't support this case. $targetedElement = new ScalarBeanPropertyDescriptor($foreignTable, $foreignTable->getColumn($foreignColumn), $this->namingStrategy, $this->annotationParser); - if ($first || $element->isCompulsory() && $index->isUnique()) { + if ($first || ($element->isCompulsory() && $index->isUnique())) { // First parameter for index is not nullable $filterArrayCode .= ' '.var_export($localColumn, true).' => '.$element->getSafeVariableName().'->'.$targetedElement->getGetterName()."(),\n"; } else { @@ -1326,9 +1308,6 @@ private function generateFindByDaoCodeForIndex(Index $index, string $beanNamespa } } - //$paramsString = implode("\n", $params); - - $methodName = $this->namingStrategy->getFindByIndexMethodName($index, $elements); $method = new MethodGenerator($methodName); @@ -1408,7 +1387,11 @@ private function generateOnDeleteCode(): ?MethodGenerator foreach ($relationships as $relationship) { if ($relationship instanceof ObjectBeanPropertyDescriptor) { $tdbmFk = ForeignKey::createFromFk($relationship->getForeignKey()); - $code .= '$this->setRef('.var_export($tdbmFk->getCacheKey(), true).', null, '.var_export($this->table->getName(), true).");\n"; + $code .= sprintf( + "\$this->setRef(%s, null, %s);\n", + var_export($tdbmFk->getCacheKey(), true), + var_export($this->table->getName(), true) + ); } } @@ -1607,10 +1590,21 @@ private function generateGetForeignKeys(array $fks): MethodGenerator foreach ($fks as $fk) { $tdbmFk = ForeignKey::createFromFk($fk); + + // Override column name in case of inheritance + $foreignTableName = $fk->getForeignTableName(); + $foreignColumns = $fk->getUnquotedForeignColumns(); + foreach ($foreignColumns as $key => $foreignColumn) { + $descriptor = $this->findScalarPropertyDescriptorInTable($foreignTableName, $foreignColumn); + if ($descriptor instanceof InheritanceReferencePropertyDescriptor) { + $foreignColumns[$key] = $this->foreignColumnNameInInheritance($descriptor, $foreignColumn); + } + } + $fkArray[$tdbmFk->getCacheKey()] = [ ForeignKey::FOREIGN_TABLE => $fk->getForeignTableName(), ForeignKey::LOCAL_COLUMNS => $fk->getUnquotedLocalColumns(), - ForeignKey::FOREIGN_COLUMNS => $fk->getUnquotedForeignColumns(), + ForeignKey::FOREIGN_COLUMNS => $foreignColumns, ]; } @@ -1646,6 +1640,39 @@ private function generateGetForeignKeys(array $fks): MethodGenerator return $method; } + private function findScalarPropertyDescriptorInTable(string $tableName, string $columnName): ?ScalarBeanPropertyDescriptor + { + $beanDescriptor = $this->registry->getBeanForTableName($tableName); + foreach ($beanDescriptor->getBeanPropertyDescriptors() as $descriptor) { + if ($descriptor instanceof ScalarBeanPropertyDescriptor && $descriptor->getColumnName() === $columnName) { + return $descriptor; + } + } + return null; + } + + /** + * Extract the foreign column name from a InheritanceReferencePropertyDescriptor + */ + private function foreignColumnNameInInheritance(InheritanceReferencePropertyDescriptor $descriptor, string $column): string + { + $nonReferenceDescriptor = $descriptor->getNonScalarReferencedPropertyDescriptor(); + if ($nonReferenceDescriptor instanceof ScalarBeanPropertyDescriptor) { + return $nonReferenceDescriptor->getColumnName(); + } + if ($nonReferenceDescriptor instanceof ObjectBeanPropertyDescriptor) { + $foreignKey = $nonReferenceDescriptor->getForeignKey(); + $localColumns = $foreignKey->getLocalColumns(); + $foreignColumns = $foreignKey->getForeignColumns(); + foreach ($localColumns as $key => $localColumn) { + if ($localColumn === $column) { + return $foreignColumns[$key]; + } + } + } + return $column; + } + /** * @param mixed $var * @param string $indent From a4815788fd3ad978136cd031ad0ff1ae3b1816f1 Mon Sep 17 00:00:00 2001 From: Guillaume Date: Thu, 16 Jan 2020 16:43:52 +0100 Subject: [PATCH 3/4] Inheritance - FK save: Fix lowest phpunit --- tests/TDBMDaoGeneratorTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/TDBMDaoGeneratorTest.php b/tests/TDBMDaoGeneratorTest.php index a141c871..207b6cde 100644 --- a/tests/TDBMDaoGeneratorTest.php +++ b/tests/TDBMDaoGeneratorTest.php @@ -2219,7 +2219,7 @@ public function testInheritanceFkWithDifferentPkName(): void $inheritanceAgencyDao = new InheritanceAgencyDao($this->tdbmService); $society = new InheritanceSocietyBean(); $inheritanceSocietyDao->save($society); - $this->assertIsInt($society->getId()); + $this->assertNotNull($society->getId()); $agency = new InheritanceAgencyBean($society); $inheritanceAgencyDao->save($agency); } From 0d0bf4ed42ab46e88fbe16fee49f0261c3fd9d6c Mon Sep 17 00:00:00 2001 From: Guillaume Date: Wed, 22 Jan 2020 16:51:22 +0100 Subject: [PATCH 4/4] Inheritance - FK save: Fix postgres test --- tests/TDBMAbstractServiceTest.php | 6 +++--- tests/TDBMDaoGeneratorTest.php | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/TDBMAbstractServiceTest.php b/tests/TDBMAbstractServiceTest.php index 60cdcdfb..678fc1ba 100644 --- a/tests/TDBMAbstractServiceTest.php +++ b/tests/TDBMAbstractServiceTest.php @@ -476,10 +476,10 @@ private static function initSchema(Connection $connection): void // - `inheritance_agency` have an FK to `inheritance_society.**id_entity**` // - `inheritance_society` have an FK to `inheritance_entity.**id**` $db->table('inheritance_entity') - ->column('id')->integer()->primaryKey()->autoIncrement(); + ->column('id')->integer()->primaryKey()->autoIncrement() + ->column('name')->string(); $db->table('inheritance_society') - ->column('id_entity')->references('inheritance_entity')->primaryKey() - ->then(); + ->column('id_entity')->references('inheritance_entity')->primaryKey(); $db->table('inheritance_agency') ->column('id')->integer()->primaryKey()->autoIncrement() ->column('id_parent_society')->references('inheritance_society'); diff --git a/tests/TDBMDaoGeneratorTest.php b/tests/TDBMDaoGeneratorTest.php index 207b6cde..65b9a507 100644 --- a/tests/TDBMDaoGeneratorTest.php +++ b/tests/TDBMDaoGeneratorTest.php @@ -2217,7 +2217,7 @@ public function testInheritanceFkWithDifferentPkName(): void { $inheritanceSocietyDao = new InheritanceSocietyDao($this->tdbmService); $inheritanceAgencyDao = new InheritanceAgencyDao($this->tdbmService); - $society = new InheritanceSocietyBean(); + $society = new InheritanceSocietyBean('test'); $inheritanceSocietyDao->save($society); $this->assertNotNull($society->getId()); $agency = new InheritanceAgencyBean($society);