1
0
mirror of synced 2025-02-09 00:39:25 +03:00

Merge branch 'feature/#6767-allow-association-as-JTI-identifier'

Close #6767
This commit is contained in:
Marco Pivetta 2017-12-19 18:02:48 +01:00
commit 4c89498359
No known key found for this signature in database
GPG Key ID: 4167D3337FD9D629
5 changed files with 173 additions and 29 deletions

View File

@ -183,19 +183,9 @@ class SchemaTool
}
} elseif ($class->isInheritanceTypeJoined()) {
// Add all non-inherited fields as columns
$pkColumns = [];
foreach ($class->fieldMappings as $fieldName => $mapping) {
if ( ! isset($mapping['inherited'])) {
$columnName = $this->quoteStrategy->getColumnName(
$mapping['fieldName'],
$class,
$this->platform
);
$this->gatherColumn($class, $mapping, $table);
if ($class->isIdentifier($fieldName)) {
$pkColumns[] = $columnName;
}
}
}
@ -206,10 +196,12 @@ class SchemaTool
$this->addDiscriminatorColumnDefinition($class, $table);
} else {
// Add an ID FK column to child tables
$pkColumns = [];
$inheritedKeyColumns = [];
foreach ($class->identifier as $identifierField) {
$idMapping = $class->fieldMappings[$identifierField];
if (isset($idMapping['inherited'])) {
if (isset($class->fieldMappings[$identifierField]['inherited'])) {
$idMapping = $class->fieldMappings[$identifierField];
$this->gatherColumn($class, $idMapping, $table);
$columnName = $this->quoteStrategy->getColumnName(
$identifierField,
@ -221,9 +213,38 @@ class SchemaTool
$pkColumns[] = $columnName;
$inheritedKeyColumns[] = $columnName;
continue;
}
if (isset($class->associationMappings[$identifierField]['inherited'])) {
$idMapping = $class->associationMappings[$identifierField];
$targetEntity = current(
array_filter(
$classes,
function (ClassMetadata $class) use ($idMapping) : bool {
return $class->name === $idMapping['targetEntity'];
}
)
);
foreach ($idMapping['joinColumns'] as $joinColumn) {
if (isset($targetEntity->fieldMappings[$joinColumn['referencedColumnName']])) {
$columnName = $this->quoteStrategy->getJoinColumnName(
$joinColumn,
$class,
$this->platform
);
$pkColumns[] = $columnName;
$inheritedKeyColumns[] = $columnName;
}
}
}
}
if (!empty($inheritedKeyColumns)) {
if ( ! empty($inheritedKeyColumns)) {
// Add a FK constraint on the ID column
$table->addForeignKeyConstraint(
$this->quoteStrategy->getTableName(
@ -236,10 +257,10 @@ class SchemaTool
);
}
if ( ! empty($pkColumns)) {
$table->setPrimaryKey($pkColumns);
}
}
$table->setPrimaryKey($pkColumns);
} elseif ($class->isInheritanceTypeTablePerClass()) {
throw ORMException::notSupported();
} else {
@ -330,7 +351,7 @@ class SchemaTool
}
}
if ( ! $this->platform->supportsSchemas() && ! $this->platform->canEmulateSchemas() ) {
if ( ! $this->platform->supportsSchemas() && ! $this->platform->canEmulateSchemas()) {
$schema->visit(new RemoveNamespacedAssets());
}
@ -496,8 +517,8 @@ class SchemaTool
*/
private function gatherRelationsSql($class, $table, $schema, &$addedFks, &$blacklistedFks)
{
foreach ($class->associationMappings as $mapping) {
if (isset($mapping['inherited'])) {
foreach ($class->associationMappings as $id => $mapping) {
if (isset($mapping['inherited']) && ! \in_array($id, $class->identifier, true)) {
continue;
}
@ -633,21 +654,21 @@ class SchemaTool
if ( ! $definingClass) {
throw new \Doctrine\ORM\ORMException(
"Column name `".$joinColumn['referencedColumnName']."` referenced for relation from ".
$mapping['sourceEntity'] . " towards ". $mapping['targetEntity'] . " does not exist."
'Column name `' . $joinColumn['referencedColumnName'] . '` referenced for relation from '
. $mapping['sourceEntity'] . ' towards ' . $mapping['targetEntity'] . ' does not exist.'
);
}
$quotedColumnName = $this->quoteStrategy->getJoinColumnName($joinColumn, $class, $this->platform);
$quotedRefColumnName = $this->quoteStrategy->getReferencedJoinColumnName(
$quotedColumnName = $this->quoteStrategy->getJoinColumnName($joinColumn, $class, $this->platform);
$quotedRefColumnName = $this->quoteStrategy->getReferencedJoinColumnName(
$joinColumn,
$class,
$this->platform
);
$primaryKeyColumns[] = $quotedColumnName;
$localColumns[] = $quotedColumnName;
$foreignColumns[] = $quotedRefColumnName;
$primaryKeyColumns[] = $quotedColumnName;
$localColumns[] = $quotedColumnName;
$foreignColumns[] = $quotedRefColumnName;
if ( ! $theJoinTable->hasColumn($quotedColumnName)) {
// Only add the column to the table if it does not exist already.
@ -666,7 +687,7 @@ class SchemaTool
$columnOptions = ['notnull' => false, 'columnDefinition' => $columnDef];
if (isset($joinColumn['nullable'])) {
$columnOptions['notnull'] = !$joinColumn['nullable'];
$columnOptions['notnull'] = ! $joinColumn['nullable'];
}
if (isset($fieldMapping['options'])) {
@ -713,7 +734,7 @@ class SchemaTool
}
}
$blacklistedFks[$compositeName] = true;
} elseif (!isset($blacklistedFks[$compositeName])) {
} elseif ( ! isset($blacklistedFks[$compositeName])) {
$addedFks[$compositeName] = ['foreignTableName' => $foreignTableName, 'foreignColumns' => $foreignColumns];
$theJoinTable->addUnnamedForeignKeyConstraint(
$foreignTableName,
@ -820,7 +841,7 @@ class SchemaTool
if ($table->hasPrimaryKey()) {
$columns = $table->getPrimaryKey()->getColumns();
if (count($columns) == 1) {
$checkSequence = $table->getName() . "_" . $columns[0] . "_seq";
$checkSequence = $table->getName() . '_' . $columns[0] . '_seq';
if ($fullSchema->hasSequence($checkSequence)) {
$visitor->acceptSequence($fullSchema->getSequence($checkSequence));
}

View File

@ -0,0 +1,22 @@
<?php
namespace Doctrine\Tests\Models\CompositeKeyInheritance;
/**
* @Entity
* @Table(name = "joined_derived_child")
*/
class JoinedDerivedChildClass extends JoinedDerivedRootClass
{
/**
* @var string
* @Column(type="string")
*/
public $extension = 'ext';
/**
* @var string
* @Column(type="string")
* @Id
*/
private $additionalId = 'additional';
}

View File

@ -0,0 +1,25 @@
<?php
namespace Doctrine\Tests\Models\CompositeKeyInheritance;
/**
* @Entity
* @Table(name = "joined_derived_identity")
*/
class JoinedDerivedIdentityClass
{
/**
* @var string
* @Column(type="string")
* @Id
*/
protected $id = 'part-0';
/**
* @var JoinedDerivedRootClass[]
* @OneToMany(
* targetEntity="JoinedDerivedRootClass",
* mappedBy="keyPart1"
* )
*/
protected $children;
}

View File

@ -0,0 +1,29 @@
<?php
namespace Doctrine\Tests\Models\CompositeKeyInheritance;
/**
* @Entity
* @Table(name = "joined_derived_root")
* @InheritanceType("JOINED")
* @DiscriminatorColumn(name="discr", type="string")
* @DiscriminatorMap({"child" = "JoinedDerivedChildClass", "root" = "JoinedDerivedRootClass"})
*/
class JoinedDerivedRootClass
{
/**
* @var JoinedDerivedIdentityClass
* @ManyToOne(
* targetEntity="JoinedDerivedIdentityClass",
* inversedBy="children"
* )
* @Id
*/
protected $keyPart1 = 'part-1';
/**
* @var string
* @Column(type="string")
* @Id
*/
protected $keyPart2 = 'part-2';
}

View File

@ -14,6 +14,9 @@ use Doctrine\Tests\Models\CMS\CmsEmployee;
use Doctrine\Tests\Models\CMS\CmsGroup;
use Doctrine\Tests\Models\CMS\CmsPhonenumber;
use Doctrine\Tests\Models\CMS\CmsUser;
use Doctrine\Tests\Models\CompositeKeyInheritance\JoinedDerivedChildClass;
use Doctrine\Tests\Models\CompositeKeyInheritance\JoinedDerivedIdentityClass;
use Doctrine\Tests\Models\CompositeKeyInheritance\JoinedDerivedRootClass;
use Doctrine\Tests\Models\Forum\ForumAvatar;
use Doctrine\Tests\Models\Forum\ForumUser;
use Doctrine\Tests\Models\NullDefault\NullDefaultColumn;
@ -184,6 +187,50 @@ class SchemaToolTest extends OrmTestCase
$this->assertEquals(255, $column->getLength());
}
public function testDerivedCompositeKey() : void
{
$em = $this->_getTestEntityManager();
$schemaTool = new SchemaTool($em);
$schema = $schemaTool->getSchemaFromMetadata(
[
$em->getClassMetadata(JoinedDerivedIdentityClass::class),
$em->getClassMetadata(JoinedDerivedRootClass::class),
$em->getClassMetadata(JoinedDerivedChildClass::class),
]
);
self::assertTrue($schema->hasTable('joined_derived_identity'));
self::assertTrue($schema->hasTable('joined_derived_root'));
self::assertTrue($schema->hasTable('joined_derived_child'));
$rootTable = $schema->getTable('joined_derived_root');
self::assertNotNull($rootTable->getPrimaryKey());
self::assertSame(['keyPart1_id', 'keyPart2'], $rootTable->getPrimaryKey()->getColumns());
$childTable = $schema->getTable('joined_derived_child');
self::assertNotNull($childTable->getPrimaryKey());
self::assertSame(['keyPart1_id', 'keyPart2'], $childTable->getPrimaryKey()->getColumns());
$childTableForeignKeys = $childTable->getForeignKeys();
self::assertCount(2, $childTableForeignKeys);
$expectedColumns = [
'joined_derived_identity' => [['keyPart1_id'], ['id']],
'joined_derived_root' => [['keyPart1_id', 'keyPart2'], ['keyPart1_id', 'keyPart2']],
];
foreach ($childTableForeignKeys as $foreignKey) {
self::assertArrayHasKey($foreignKey->getForeignTableName(), $expectedColumns);
[$localColumns, $foreignColumns] = $expectedColumns[$foreignKey->getForeignTableName()];
self::assertSame($localColumns, $foreignKey->getLocalColumns());
self::assertSame($foreignColumns, $foreignKey->getForeignColumns());
}
}
}
/**