Skip to content

Commit

Permalink
Merge pull request #190 from homersimpsons/fix/inheritance-fk-save
Browse files Browse the repository at this point in the history
Inheritance - FK save
  • Loading branch information
moufmouf authored Jan 6, 2021
2 parents c66408b + 0d0bf4e commit cf1e03d
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 28 deletions.
77 changes: 52 additions & 25 deletions src/Utils/BeanDescriptor.php
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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 = [];
Expand All @@ -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 {
Expand All @@ -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);
Expand Down Expand Up @@ -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)
);
}
}

Expand Down Expand Up @@ -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,
];
}

Expand Down Expand Up @@ -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
Expand Down
6 changes: 3 additions & 3 deletions tests/TDBMAbstractServiceTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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');
Expand Down
15 changes: 15 additions & 0 deletions tests/TDBMDaoGeneratorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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('test');
$inheritanceSocietyDao->save($society);
$this->assertNotNull($society->getId());
$agency = new InheritanceAgencyBean($society);
$inheritanceAgencyDao->save($agency);
}
}

0 comments on commit cf1e03d

Please sign in to comment.