Skip to content

Commit

Permalink
Merge pull request #188 from thecodingmachine/5.1
Browse files Browse the repository at this point in the history
Porting Inheritance fix to 5.2
  • Loading branch information
moufmouf committed Dec 16, 2019
2 parents 2340c9e + 1b91945 commit 27db626
Show file tree
Hide file tree
Showing 5 changed files with 87 additions and 15 deletions.
25 changes: 16 additions & 9 deletions src/Utils/BeanDescriptor.php
Expand Up @@ -214,7 +214,7 @@ public function getBeanPropertyDescriptors(): array
public function getConstructorProperties(): array
{
$constructorProperties = array_filter($this->beanPropertyDescriptors, function (AbstractBeanPropertyDescriptor $property) {
return $property->isCompulsory();
return !$property instanceof InheritanceReferencePropertyDescriptor && $property->isCompulsory();
});

return $constructorProperties;
Expand Down Expand Up @@ -243,7 +243,7 @@ public function getPropertiesWithDefault(): array
public function getExposedProperties(): array
{
$exposedProperties = array_filter($this->beanPropertyDescriptors, function (AbstractBeanPropertyDescriptor $property) {
return $property->getTable()->getName() == $this->table->getName();
return !$property instanceof InheritanceReferencePropertyDescriptor && $property->getTable()->getName() === $this->table->getName();
});

return $exposedProperties;
Expand All @@ -269,7 +269,7 @@ private function getProperties(Table $table): array
$localProperties = $this->getPropertiesForTable($table);
foreach ($localProperties as $name => $property) {
// We do not override properties if this is a primary key!
if ($property->isPrimaryKey()) {
if (!$property instanceof InheritanceReferencePropertyDescriptor && $property->isPrimaryKey()) {
continue;
}
$properties[$name] = $property;
Expand All @@ -292,14 +292,14 @@ private function getPropertiesForTable(Table $table): array
{
$parentRelationship = $this->schemaAnalyzer->getParentRelationship($table->getName());
if ($parentRelationship) {
$ignoreColumns = $parentRelationship->getUnquotedLocalColumns();
$ignoreColumns = $parentRelationship->getUnquotedForeignColumns();
} else {
$ignoreColumns = [];
}

$beanPropertyDescriptors = [];
foreach ($table->getColumns() as $column) {
if (array_search($column->getName(), $ignoreColumns) !== false) {
if (in_array($column->getName(), $ignoreColumns, true)) {
continue;
}

Expand All @@ -311,13 +311,20 @@ private function getPropertiesForTable(Table $table): array
continue 2;
}
}
$propertyDescriptor = new ObjectBeanPropertyDescriptor($table, $fk, $this->namingStrategy, $this->beanNamespace, $this->annotationParser, $this->registry->getBeanForTableName($fk->getForeignTableName()));
// Check that this property is not an inheritance relationship
$parentRelationship = $this->schemaAnalyzer->getParentRelationship($table->getName());
if ($parentRelationship === $fk) {
continue;
if ($parentRelationship !== null && $parentRelationship->getName() === $fk->getName()) {
$beanPropertyDescriptors[] = new InheritanceReferencePropertyDescriptor(
$table,
$column,
$this->namingStrategy,
$this->annotationParser,
$propertyDescriptor
);
} else {
$beanPropertyDescriptors[] = $propertyDescriptor;
}

$beanPropertyDescriptors[] = new ObjectBeanPropertyDescriptor($table, $fk, $this->namingStrategy, $this->beanNamespace, $this->annotationParser, $this->registry->getBeanForTableName($fk->getForeignTableName()));
} else {
$beanPropertyDescriptors[] = new ScalarBeanPropertyDescriptor($table, $column, $this->namingStrategy, $this->annotationParser);
}
Expand Down
6 changes: 3 additions & 3 deletions src/Utils/DefaultNamingStrategy.php
Expand Up @@ -338,11 +338,11 @@ protected function getUpperCamelCaseName(AbstractBeanPropertyDescriptor $propert
{
if ($property instanceof ObjectBeanPropertyDescriptor) {
return $this->getForeignKeyUpperCamelCaseName($property->getForeignKey(), $property->isAlternativeName());
} elseif ($property instanceof ScalarBeanPropertyDescriptor) {
}
if ($property instanceof ScalarBeanPropertyDescriptor) {
return $this->getScalarColumnUpperCamelCaseName($property->getColumnName(), $property->isAlternativeName());
} else {
throw new TDBMException('Unexpected property type. Should be either ObjectBeanPropertyDescriptor or ScalarBeanPropertyDescriptor'); // @codeCoverageIgnore
}
throw new TDBMException('Unexpected property type. Should be either ObjectBeanPropertyDescriptor or ScalarBeanPropertyDescriptor'); // @codeCoverageIgnore
}

private function getSchema(): Schema
Expand Down
45 changes: 45 additions & 0 deletions src/Utils/InheritanceReferencePropertyDescriptor.php
@@ -0,0 +1,45 @@
<?php


namespace TheCodingMachine\TDBM\Utils;

use Doctrine\DBAL\Schema\Column;
use Doctrine\DBAL\Schema\Table;
use TheCodingMachine\TDBM\Utils\Annotation\AnnotationParser;

/**
* This class represents a reference to a AbstractBeanPropertyDescriptor used in an inheritance schema
*/
class InheritanceReferencePropertyDescriptor extends ScalarBeanPropertyDescriptor
{
/** @var AbstractBeanPropertyDescriptor */
private $referencedPropertyDescriptor;

public function __construct(
Table $table,
Column $column,
NamingStrategyInterface $namingStrategy,
AnnotationParser $annotationParser,
AbstractBeanPropertyDescriptor $referencedPropertyDescriptor
) {
parent::__construct($table, $column, $namingStrategy, $annotationParser);
$this->referencedPropertyDescriptor = $referencedPropertyDescriptor;
}

/**
* @return ScalarBeanPropertyDescriptor|ObjectBeanPropertyDescriptor
*/
public function getNonScalarReferencedPropertyDescriptor(): AbstractBeanPropertyDescriptor
{
if ($this->referencedPropertyDescriptor instanceof InheritanceReferencePropertyDescriptor) {
return $this->referencedPropertyDescriptor->getNonScalarReferencedPropertyDescriptor();
}
assert($this->referencedPropertyDescriptor instanceof ScalarBeanPropertyDescriptor || $this->referencedPropertyDescriptor instanceof ObjectBeanPropertyDescriptor);
return $this->referencedPropertyDescriptor;
}

public function getJsonSerializeCode(): string
{
return $this->getNonScalarReferencedPropertyDescriptor()->getJsonSerializeCode();
}
}
15 changes: 12 additions & 3 deletions src/Utils/ObjectBeanPropertyDescriptor.php
Expand Up @@ -258,9 +258,18 @@ private function getLazySerializeCode(string $propertyAccess): string
$rows = [];
foreach ($this->getForeignKey()->getUnquotedForeignColumns() as $column) {
$descriptor = $this->getBeanPropertyDescriptor($column);
$indexName = ltrim($descriptor->getVariableName(), '$');
$columnGetterName = $descriptor->getGetterName();
$rows[] = "'$indexName' => $propertyAccess->$columnGetterName()";
if ($descriptor instanceof InheritanceReferencePropertyDescriptor) {
$descriptor = $descriptor->getNonScalarReferencedPropertyDescriptor();
}
if ($descriptor instanceof ObjectBeanPropertyDescriptor) {
$rows[] = trim($descriptor->getLazySerializeCode($propertyAccess), '[]');
} elseif ($descriptor instanceof ScalarBeanPropertyDescriptor) {
$indexName = ltrim($descriptor->getVariableName(), '$');
$columnGetterName = $descriptor->getGetterName();
$rows[] = "'$indexName' => $propertyAccess->$columnGetterName()";
} else {
throw new TDBMException('PropertyDescriptor of class `' . get_class($descriptor) . '` cannot be serialized.');
}
}
return '[' . implode(', ', $rows) . ']';
}
Expand Down
11 changes: 11 additions & 0 deletions tests/TDBMAbstractServiceTest.php
Expand Up @@ -395,6 +395,17 @@ private static function initSchema(Connection $connection): void
->column('fk_2')->integer()
->then()->getDbalTable()->addForeignKeyConstraint($targetTable->getDbalTable(), ['fk_1', 'fk_2'], ['id_1', 'id_2']);

// Test case, the problem here is:
// - `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();
$db->table('inheritance_society')
->column('id_entity')->references('inheritance_entity')->primaryKey()
->then();
$db->table('inheritance_agency')
->column('id')->integer()->primaryKey()->autoIncrement()
->column('id_parent_society')->references('inheritance_society');

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

Expand Down

0 comments on commit 27db626

Please sign in to comment.