Skip to content

Commit cf1e03d

Browse files
authored
Merge pull request #190 from homersimpsons/fix/inheritance-fk-save
Inheritance - FK save
2 parents c66408b + 0d0bf4e commit cf1e03d

File tree

3 files changed

+70
-28
lines changed

3 files changed

+70
-28
lines changed

src/Utils/BeanDescriptor.php

Lines changed: 52 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1223,7 +1223,6 @@ private function removeDuplicateIndexes(array $indexes): array
12231223
private function generateFindByDaoCodeForIndex(Index $index, string $beanNamespace, string $beanClassName): ?MethodGenerator
12241224
{
12251225
$columns = $index->getColumns();
1226-
$usedBeans = [];
12271226

12281227
/**
12291228
* The list of elements building this index (expressed as columns or foreign keys)
@@ -1249,42 +1248,26 @@ private function generateFindByDaoCodeForIndex(Index $index, string $beanNamespa
12491248
}
12501249

12511250
$parameters = [];
1252-
//$functionParameters = [];
12531251
$first = true;
12541252
/** @var AbstractBeanPropertyDescriptor $element */
12551253
foreach ($elements as $element) {
12561254
$parameter = new ParameterGenerator(ltrim($element->getSafeVariableName(), '$'));
12571255
if (!$first && !($element->isCompulsory() && $index->isUnique())) {
12581256
$parameterType = '?';
1259-
//$functionParameter = '?';
12601257
} else {
12611258
$parameterType = '';
1262-
//$functionParameter = '';
12631259
}
12641260
$parameterType .= $element->getPhpType();
12651261
$parameter->setType($parameterType);
12661262
if (!$first && !($element->isCompulsory() && $index->isUnique())) {
12671263
$parameter->setDefaultValue(null);
12681264
}
1269-
//$functionParameter .= $element->getPhpType();
1270-
$elementClassName = $element->getClassName();
1271-
if ($elementClassName) {
1272-
$usedBeans[] = $beanNamespace.'\\'.$elementClassName;
1273-
}
1274-
//$functionParameter .= ' '.$element->getVariableName();
12751265
if ($first) {
12761266
$first = false;
1277-
} /*else {
1278-
$functionParameter .= ' = null';
1279-
}*/
1280-
//$functionParameters[] = $functionParameter;
1267+
}
12811268
$parameters[] = $parameter;
12821269
}
12831270

1284-
//$functionParametersString = implode(', ', $functionParameters);
1285-
1286-
$count = 0;
1287-
12881271
$params = [];
12891272
$filterArrayCode = '';
12901273
$commentArguments = [];
@@ -1306,12 +1289,11 @@ private function generateFindByDaoCodeForIndex(Index $index, string $beanNamespa
13061289
} elseif ($element instanceof ObjectBeanPropertyDescriptor) {
13071290
$foreignKey = $element->getForeignKey();
13081291
$columns = SafeFunctions::arrayCombine($foreignKey->getLocalColumns(), $foreignKey->getForeignColumns());
1309-
++$count;
13101292
$foreignTable = $this->schema->getTable($foreignKey->getForeignTableName());
13111293
foreach ($columns as $localColumn => $foreignColumn) {
13121294
// 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.
13131295
$targetedElement = new ScalarBeanPropertyDescriptor($foreignTable, $foreignTable->getColumn($foreignColumn), $this->namingStrategy, $this->annotationParser);
1314-
if ($first || $element->isCompulsory() && $index->isUnique()) {
1296+
if ($first || ($element->isCompulsory() && $index->isUnique())) {
13151297
// First parameter for index is not nullable
13161298
$filterArrayCode .= ' '.var_export($localColumn, true).' => '.$element->getSafeVariableName().'->'.$targetedElement->getGetterName()."(),\n";
13171299
} else {
@@ -1326,9 +1308,6 @@ private function generateFindByDaoCodeForIndex(Index $index, string $beanNamespa
13261308
}
13271309
}
13281310

1329-
//$paramsString = implode("\n", $params);
1330-
1331-
13321311
$methodName = $this->namingStrategy->getFindByIndexMethodName($index, $elements);
13331312

13341313
$method = new MethodGenerator($methodName);
@@ -1408,7 +1387,11 @@ private function generateOnDeleteCode(): ?MethodGenerator
14081387
foreach ($relationships as $relationship) {
14091388
if ($relationship instanceof ObjectBeanPropertyDescriptor) {
14101389
$tdbmFk = ForeignKey::createFromFk($relationship->getForeignKey());
1411-
$code .= '$this->setRef('.var_export($tdbmFk->getCacheKey(), true).', null, '.var_export($this->table->getName(), true).");\n";
1390+
$code .= sprintf(
1391+
"\$this->setRef(%s, null, %s);\n",
1392+
var_export($tdbmFk->getCacheKey(), true),
1393+
var_export($this->table->getName(), true)
1394+
);
14121395
}
14131396
}
14141397

@@ -1607,10 +1590,21 @@ private function generateGetForeignKeys(array $fks): MethodGenerator
16071590

16081591
foreach ($fks as $fk) {
16091592
$tdbmFk = ForeignKey::createFromFk($fk);
1593+
1594+
// Override column name in case of inheritance
1595+
$foreignTableName = $fk->getForeignTableName();
1596+
$foreignColumns = $fk->getUnquotedForeignColumns();
1597+
foreach ($foreignColumns as $key => $foreignColumn) {
1598+
$descriptor = $this->findScalarPropertyDescriptorInTable($foreignTableName, $foreignColumn);
1599+
if ($descriptor instanceof InheritanceReferencePropertyDescriptor) {
1600+
$foreignColumns[$key] = $this->foreignColumnNameInInheritance($descriptor, $foreignColumn);
1601+
}
1602+
}
1603+
16101604
$fkArray[$tdbmFk->getCacheKey()] = [
16111605
ForeignKey::FOREIGN_TABLE => $fk->getForeignTableName(),
16121606
ForeignKey::LOCAL_COLUMNS => $fk->getUnquotedLocalColumns(),
1613-
ForeignKey::FOREIGN_COLUMNS => $fk->getUnquotedForeignColumns(),
1607+
ForeignKey::FOREIGN_COLUMNS => $foreignColumns,
16141608
];
16151609
}
16161610

@@ -1646,6 +1640,39 @@ private function generateGetForeignKeys(array $fks): MethodGenerator
16461640
return $method;
16471641
}
16481642

1643+
private function findScalarPropertyDescriptorInTable(string $tableName, string $columnName): ?ScalarBeanPropertyDescriptor
1644+
{
1645+
$beanDescriptor = $this->registry->getBeanForTableName($tableName);
1646+
foreach ($beanDescriptor->getBeanPropertyDescriptors() as $descriptor) {
1647+
if ($descriptor instanceof ScalarBeanPropertyDescriptor && $descriptor->getColumnName() === $columnName) {
1648+
return $descriptor;
1649+
}
1650+
}
1651+
return null;
1652+
}
1653+
1654+
/**
1655+
* Extract the foreign column name from a InheritanceReferencePropertyDescriptor
1656+
*/
1657+
private function foreignColumnNameInInheritance(InheritanceReferencePropertyDescriptor $descriptor, string $column): string
1658+
{
1659+
$nonReferenceDescriptor = $descriptor->getNonScalarReferencedPropertyDescriptor();
1660+
if ($nonReferenceDescriptor instanceof ScalarBeanPropertyDescriptor) {
1661+
return $nonReferenceDescriptor->getColumnName();
1662+
}
1663+
if ($nonReferenceDescriptor instanceof ObjectBeanPropertyDescriptor) {
1664+
$foreignKey = $nonReferenceDescriptor->getForeignKey();
1665+
$localColumns = $foreignKey->getLocalColumns();
1666+
$foreignColumns = $foreignKey->getForeignColumns();
1667+
foreach ($localColumns as $key => $localColumn) {
1668+
if ($localColumn === $column) {
1669+
return $foreignColumns[$key];
1670+
}
1671+
}
1672+
}
1673+
return $column;
1674+
}
1675+
16491676
/**
16501677
* @param mixed $var
16511678
* @param string $indent

tests/TDBMAbstractServiceTest.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -476,10 +476,10 @@ private static function initSchema(Connection $connection): void
476476
// - `inheritance_agency` have an FK to `inheritance_society.**id_entity**`
477477
// - `inheritance_society` have an FK to `inheritance_entity.**id**`
478478
$db->table('inheritance_entity')
479-
->column('id')->integer()->primaryKey()->autoIncrement();
479+
->column('id')->integer()->primaryKey()->autoIncrement()
480+
->column('name')->string();
480481
$db->table('inheritance_society')
481-
->column('id_entity')->references('inheritance_entity')->primaryKey()
482-
->then();
482+
->column('id_entity')->references('inheritance_entity')->primaryKey();
483483
$db->table('inheritance_agency')
484484
->column('id')->integer()->primaryKey()->autoIncrement()
485485
->column('id_parent_society')->references('inheritance_society');

tests/TDBMDaoGeneratorTest.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,8 @@
6262
use TheCodingMachine\TDBM\Test\Dao\Bean\Generated\BoatBaseBean;
6363
use TheCodingMachine\TDBM\Test\Dao\Bean\Generated\FileBaseBean;
6464
use TheCodingMachine\TDBM\Test\Dao\Bean\Generated\UserBaseBean;
65+
use TheCodingMachine\TDBM\Test\Dao\Bean\InheritanceAgencyBean;
66+
use TheCodingMachine\TDBM\Test\Dao\Bean\InheritanceSocietyBean;
6567
use TheCodingMachine\TDBM\Test\Dao\Bean\InheritedObjectBean;
6668
use TheCodingMachine\TDBM\Test\Dao\Bean\NodeBean;
6769
use TheCodingMachine\TDBM\Test\Dao\Bean\PersonBean;
@@ -78,6 +80,8 @@
7880
use TheCodingMachine\TDBM\Test\Dao\DogDao;
7981
use TheCodingMachine\TDBM\Test\Dao\FileDao;
8082
use TheCodingMachine\TDBM\Test\Dao\Generated\UserBaseDao;
83+
use TheCodingMachine\TDBM\Test\Dao\InheritanceAgencyDao;
84+
use TheCodingMachine\TDBM\Test\Dao\InheritanceSocietyDao;
8185
use TheCodingMachine\TDBM\Test\Dao\InheritedObjectDao;
8286
use TheCodingMachine\TDBM\Test\Dao\NodeDao;
8387
use TheCodingMachine\TDBM\Test\Dao\PersonDao;
@@ -2208,4 +2212,15 @@ public function testFindFromRawSQLOnInheritance(): void
22082212
$this->assertNotNull($objects->first());
22092213
$this->assertEquals(6, $objects->count());
22102214
}
2215+
2216+
public function testInheritanceFkWithDifferentPkName(): void
2217+
{
2218+
$inheritanceSocietyDao = new InheritanceSocietyDao($this->tdbmService);
2219+
$inheritanceAgencyDao = new InheritanceAgencyDao($this->tdbmService);
2220+
$society = new InheritanceSocietyBean('test');
2221+
$inheritanceSocietyDao->save($society);
2222+
$this->assertNotNull($society->getId());
2223+
$agency = new InheritanceAgencyBean($society);
2224+
$inheritanceAgencyDao->save($agency);
2225+
}
22112226
}

0 commit comments

Comments
 (0)