Skip to content

Commit 1b91945

Browse files
authored
Merge pull request #187 from homersimpsons/fix/inheritance
Fix inheritance with distinct column name
2 parents 7358a3f + d37eec8 commit 1b91945

File tree

5 files changed

+87
-15
lines changed

5 files changed

+87
-15
lines changed

src/Utils/BeanDescriptor.php

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,7 @@ public function getBeanPropertyDescriptors(): array
201201
public function getConstructorProperties(): array
202202
{
203203
$constructorProperties = array_filter($this->beanPropertyDescriptors, function (AbstractBeanPropertyDescriptor $property) {
204-
return $property->isCompulsory();
204+
return !$property instanceof InheritanceReferencePropertyDescriptor && $property->isCompulsory();
205205
});
206206

207207
return $constructorProperties;
@@ -230,7 +230,7 @@ public function getPropertiesWithDefault(): array
230230
public function getExposedProperties(): array
231231
{
232232
$exposedProperties = array_filter($this->beanPropertyDescriptors, function (AbstractBeanPropertyDescriptor $property) {
233-
return $property->getTable()->getName() == $this->table->getName();
233+
return !$property instanceof InheritanceReferencePropertyDescriptor && $property->getTable()->getName() === $this->table->getName();
234234
});
235235

236236
return $exposedProperties;
@@ -256,7 +256,7 @@ private function getProperties(Table $table): array
256256
$localProperties = $this->getPropertiesForTable($table);
257257
foreach ($localProperties as $name => $property) {
258258
// We do not override properties if this is a primary key!
259-
if ($property->isPrimaryKey()) {
259+
if (!$property instanceof InheritanceReferencePropertyDescriptor && $property->isPrimaryKey()) {
260260
continue;
261261
}
262262
$properties[$name] = $property;
@@ -279,14 +279,14 @@ private function getPropertiesForTable(Table $table): array
279279
{
280280
$parentRelationship = $this->schemaAnalyzer->getParentRelationship($table->getName());
281281
if ($parentRelationship) {
282-
$ignoreColumns = $parentRelationship->getUnquotedLocalColumns();
282+
$ignoreColumns = $parentRelationship->getUnquotedForeignColumns();
283283
} else {
284284
$ignoreColumns = [];
285285
}
286286

287287
$beanPropertyDescriptors = [];
288288
foreach ($table->getColumns() as $column) {
289-
if (array_search($column->getName(), $ignoreColumns) !== false) {
289+
if (in_array($column->getName(), $ignoreColumns, true)) {
290290
continue;
291291
}
292292

@@ -298,13 +298,20 @@ private function getPropertiesForTable(Table $table): array
298298
continue 2;
299299
}
300300
}
301+
$propertyDescriptor = new ObjectBeanPropertyDescriptor($table, $fk, $this->namingStrategy, $this->beanNamespace, $this->annotationParser, $this->registry->getBeanForTableName($fk->getForeignTableName()));
301302
// Check that this property is not an inheritance relationship
302303
$parentRelationship = $this->schemaAnalyzer->getParentRelationship($table->getName());
303-
if ($parentRelationship === $fk) {
304-
continue;
304+
if ($parentRelationship !== null && $parentRelationship->getName() === $fk->getName()) {
305+
$beanPropertyDescriptors[] = new InheritanceReferencePropertyDescriptor(
306+
$table,
307+
$column,
308+
$this->namingStrategy,
309+
$this->annotationParser,
310+
$propertyDescriptor
311+
);
312+
} else {
313+
$beanPropertyDescriptors[] = $propertyDescriptor;
305314
}
306-
307-
$beanPropertyDescriptors[] = new ObjectBeanPropertyDescriptor($table, $fk, $this->namingStrategy, $this->beanNamespace, $this->annotationParser, $this->registry->getBeanForTableName($fk->getForeignTableName()));
308315
} else {
309316
$beanPropertyDescriptors[] = new ScalarBeanPropertyDescriptor($table, $column, $this->namingStrategy, $this->annotationParser);
310317
}

src/Utils/DefaultNamingStrategy.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -312,11 +312,11 @@ protected function getUpperCamelCaseName(AbstractBeanPropertyDescriptor $propert
312312
{
313313
if ($property instanceof ObjectBeanPropertyDescriptor) {
314314
return $this->getForeignKeyUpperCamelCaseName($property->getForeignKey(), $property->isAlternativeName());
315-
} elseif ($property instanceof ScalarBeanPropertyDescriptor) {
315+
}
316+
if ($property instanceof ScalarBeanPropertyDescriptor) {
316317
return $this->getScalarColumnUpperCamelCaseName($property->getColumnName(), $property->isAlternativeName());
317-
} else {
318-
throw new TDBMException('Unexpected property type. Should be either ObjectBeanPropertyDescriptor or ScalarBeanPropertyDescriptor'); // @codeCoverageIgnore
319318
}
319+
throw new TDBMException('Unexpected property type. Should be either ObjectBeanPropertyDescriptor or ScalarBeanPropertyDescriptor'); // @codeCoverageIgnore
320320
}
321321

322322
private function getSchema(): Schema
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
<?php
2+
3+
4+
namespace TheCodingMachine\TDBM\Utils;
5+
6+
use Doctrine\DBAL\Schema\Column;
7+
use Doctrine\DBAL\Schema\Table;
8+
use TheCodingMachine\TDBM\Utils\Annotation\AnnotationParser;
9+
10+
/**
11+
* This class represents a reference to a AbstractBeanPropertyDescriptor used in an inheritance schema
12+
*/
13+
class InheritanceReferencePropertyDescriptor extends ScalarBeanPropertyDescriptor
14+
{
15+
/** @var AbstractBeanPropertyDescriptor */
16+
private $referencedPropertyDescriptor;
17+
18+
public function __construct(
19+
Table $table,
20+
Column $column,
21+
NamingStrategyInterface $namingStrategy,
22+
AnnotationParser $annotationParser,
23+
AbstractBeanPropertyDescriptor $referencedPropertyDescriptor
24+
) {
25+
parent::__construct($table, $column, $namingStrategy, $annotationParser);
26+
$this->referencedPropertyDescriptor = $referencedPropertyDescriptor;
27+
}
28+
29+
/**
30+
* @return ScalarBeanPropertyDescriptor|ObjectBeanPropertyDescriptor
31+
*/
32+
public function getNonScalarReferencedPropertyDescriptor(): AbstractBeanPropertyDescriptor
33+
{
34+
if ($this->referencedPropertyDescriptor instanceof InheritanceReferencePropertyDescriptor) {
35+
return $this->referencedPropertyDescriptor->getNonScalarReferencedPropertyDescriptor();
36+
}
37+
assert($this->referencedPropertyDescriptor instanceof ScalarBeanPropertyDescriptor || $this->referencedPropertyDescriptor instanceof ObjectBeanPropertyDescriptor);
38+
return $this->referencedPropertyDescriptor;
39+
}
40+
41+
public function getJsonSerializeCode(): string
42+
{
43+
return $this->getNonScalarReferencedPropertyDescriptor()->getJsonSerializeCode();
44+
}
45+
}

src/Utils/ObjectBeanPropertyDescriptor.php

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -258,9 +258,18 @@ private function getLazySerializeCode(string $propertyAccess): string
258258
$rows = [];
259259
foreach ($this->getForeignKey()->getUnquotedForeignColumns() as $column) {
260260
$descriptor = $this->getBeanPropertyDescriptor($column);
261-
$indexName = ltrim($descriptor->getVariableName(), '$');
262-
$columnGetterName = $descriptor->getGetterName();
263-
$rows[] = "'$indexName' => $propertyAccess->$columnGetterName()";
261+
if ($descriptor instanceof InheritanceReferencePropertyDescriptor) {
262+
$descriptor = $descriptor->getNonScalarReferencedPropertyDescriptor();
263+
}
264+
if ($descriptor instanceof ObjectBeanPropertyDescriptor) {
265+
$rows[] = trim($descriptor->getLazySerializeCode($propertyAccess), '[]');
266+
} elseif ($descriptor instanceof ScalarBeanPropertyDescriptor) {
267+
$indexName = ltrim($descriptor->getVariableName(), '$');
268+
$columnGetterName = $descriptor->getGetterName();
269+
$rows[] = "'$indexName' => $propertyAccess->$columnGetterName()";
270+
} else {
271+
throw new TDBMException('PropertyDescriptor of class `' . get_class($descriptor) . '` cannot be serialized.');
272+
}
264273
}
265274
return '[' . implode(', ', $rows) . ']';
266275
}

tests/TDBMAbstractServiceTest.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -466,6 +466,17 @@ private static function initSchema(Connection $connection): void
466466
->column('fk_2')->integer()
467467
->then()->getDbalTable()->addForeignKeyConstraint($targetTable->getDbalTable(), ['fk_1', 'fk_2'], ['id_1', 'id_2']);
468468

469+
// Test case, the problem here is:
470+
// - `inheritance_agency` have an FK to `inheritance_society.**id_entity**`
471+
// - `inheritance_society` have an FK to `inheritance_entity.**id**`
472+
$db->table('inheritance_entity')
473+
->column('id')->integer()->primaryKey()->autoIncrement();
474+
$db->table('inheritance_society')
475+
->column('id_entity')->references('inheritance_entity')->primaryKey()
476+
->then();
477+
$db->table('inheritance_agency')
478+
->column('id')->integer()->primaryKey()->autoIncrement()
479+
->column('id_parent_society')->references('inheritance_society');
469480

470481
$sqlStmts = $toSchema->getMigrateFromSql($fromSchema, $connection->getDatabasePlatform());
471482

0 commit comments

Comments
 (0)