DDC-130 - Refactored deleteJoinTableRecords() support
This commit is contained in:
parent
233b3cd0b9
commit
1794127d51
@ -68,6 +68,20 @@ class ManyToManyMapping extends AssociationMapping
|
||||
*/
|
||||
public $orderBy;
|
||||
|
||||
/**
|
||||
* READ-ONLY: Are entries on the owning side of this join-table deleted through a database onDelete="CASCADE" operation?
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public $owningIsOnDeleteCascade = false;
|
||||
|
||||
/**
|
||||
* READ-ONLY: Are entries on the inverse side of this join-table deleted through a database onDelete="CASCADE" operation?
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public $inverseIsOnDeleteCascade = false;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
@ -115,11 +129,19 @@ class ManyToManyMapping extends AssociationMapping
|
||||
}
|
||||
|
||||
foreach ($mapping['joinTable']['joinColumns'] as $joinColumn) {
|
||||
if (isset($joinColumn['onDelete']) && strtolower($joinColumn['onDelete']) == 'cascade') {
|
||||
$this->owningIsOnDeleteCascade = true;
|
||||
}
|
||||
|
||||
$this->relationToSourceKeyColumns[$joinColumn['name']] = $joinColumn['referencedColumnName'];
|
||||
$this->joinTableColumns[] = $joinColumn['name'];
|
||||
}
|
||||
|
||||
foreach ($mapping['joinTable']['inverseJoinColumns'] as $inverseJoinColumn) {
|
||||
if (isset($inverseJoinColumn['onDelete']) && strtolower($inverseJoinColumn['onDelete']) == 'cascade') {
|
||||
$this->inverseIsOnDeleteCascade = true;
|
||||
}
|
||||
|
||||
$this->relationToTargetKeyColumns[$inverseJoinColumn['name']] = $inverseJoinColumn['referencedColumnName'];
|
||||
$this->joinTableColumns[] = $inverseJoinColumn['name'];
|
||||
}
|
||||
@ -169,6 +191,12 @@ class ManyToManyMapping extends AssociationMapping
|
||||
$serialized[] = 'joinTableColumns';
|
||||
$serialized[] = 'relationToSourceKeyColumns';
|
||||
$serialized[] = 'relationToTargetKeyColumns';
|
||||
if ($this->owningIsOnDeleteCascade) {
|
||||
$serialized[] = 'owningIsOnDeleteCascade';
|
||||
}
|
||||
if ($this->inverseIsOnDeleteCascade) {
|
||||
$serialized[] = 'inverseIsOnDeleteCascade';
|
||||
}
|
||||
if ($this->orderBy) {
|
||||
$serialized[] = 'orderBy';
|
||||
}
|
||||
|
@ -335,8 +335,6 @@ class BasicEntityPersister
|
||||
}
|
||||
}
|
||||
|
||||
private $requiredJoinTableDeletions = null;
|
||||
|
||||
/**
|
||||
* @todo Add check for platform if it supports foreign keys/cascading.
|
||||
* @param array $identifier
|
||||
@ -344,44 +342,27 @@ class BasicEntityPersister
|
||||
*/
|
||||
protected function deleteJoinTableRecords($identifier)
|
||||
{
|
||||
if ($this->requiredJoinTableDeletions === null) {
|
||||
$this->requiredJoinTableDeletions = array();
|
||||
foreach ($this->_class->associationMappings AS $mapping) {
|
||||
/* @var $mapping \Doctrine\ORM\Mapping\AssociationMapping */
|
||||
if ($mapping->isManyToMany()) {
|
||||
// TODO: Write test for composite keys
|
||||
if (!$mapping->isOwningSide) {
|
||||
$relatedClass = $this->_em->getClassMetadata($mapping->targetEntityName);
|
||||
$mapping = $relatedClass->associationMappings[$mapping->mappedBy];
|
||||
$keys = array_keys($mapping->relationToTargetKeyColumns);
|
||||
foreach ($this->_class->associationMappings AS $mapping) {
|
||||
/* @var $mapping \Doctrine\ORM\Mapping\AssociationMapping */
|
||||
if ($mapping->isManyToMany()) {
|
||||
if($mapping->isOwningSide && (!$mapping->owningIsOnDeleteCascade || !$this->_platform->supportsForeignKeyConstraints())) {
|
||||
$this->_conn->delete(
|
||||
$mapping->joinTable['name'],
|
||||
array_combine(array_keys($mapping->relationToSourceKeyColumns), $identifier)
|
||||
);
|
||||
} else if (!$mapping->isOwningSide) {
|
||||
$relatedClass = $this->_em->getClassMetadata($mapping->targetEntityName);
|
||||
$relatedMapping = $relatedClass->associationMappings[$mapping->mappedBy];
|
||||
|
||||
// this is not semantically correct, onDelete should be an option of the joinColumns
|
||||
// @todo optimize this (potentially in the validate association/metadata already)
|
||||
foreach ($mapping->joinTable['inverseJoinColumns'] AS $joinColumn) {
|
||||
if (strtoupper($joinColumn['onDelete']) == 'CASCADE') {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// this is not semantically correct, onDelete should be an option of the joinColumns
|
||||
// @todo optimize this (potentially in the validate association/metadata already)
|
||||
foreach ($mapping->joinTable['joinColumns'] AS $joinColumn) {
|
||||
if (strtoupper($joinColumn['onDelete']) == 'CASCADE') {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
$keys = array_keys($mapping->relationToSourceKeyColumns);
|
||||
if (!$relatedMapping->inverseIsOnDeleteCascade || !$this->_platform->supportsForeignKeyConstraints()) {
|
||||
$this->_conn->delete(
|
||||
$relatedMapping->joinTable['name'],
|
||||
array_combine(array_keys($relatedMapping->relationToTargetKeyColumns), $identifier)
|
||||
);
|
||||
}
|
||||
$this->requiredJoinTableDeletions[$mapping->joinTable['name']] = $keys;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($this->requiredJoinTableDeletions AS $table => $keys) {
|
||||
$id = array_combine($keys, $identifier);
|
||||
$this->_conn->delete($table, $id);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -107,6 +107,25 @@ class ClassMetadataTest extends \Doctrine\Tests\OrmTestCase
|
||||
'joinColumns' => array(array('name' => 'CmsUser_id', 'referencedColumnName' => 'id', 'onDelete' => 'CASCADE')),
|
||||
'inverseJoinColumns' => array(array('name' => 'CmsGroup_id', 'referencedColumnName' => 'id', 'onDelete' => 'CASCADE'))
|
||||
), $assoc->joinTable);
|
||||
$this->assertTrue($assoc->owningIsOnDeleteCascade);
|
||||
$this->assertTrue($assoc->inverseIsOnDeleteCascade);
|
||||
}
|
||||
|
||||
public function testSerializeManyToManyJoinTableCascade()
|
||||
{
|
||||
$cm = new ClassMetadata('Doctrine\Tests\Models\CMS\CmsUser');
|
||||
$cm->mapManyToMany(
|
||||
array(
|
||||
'fieldName' => 'groups',
|
||||
'targetEntity' => 'CmsGroup'
|
||||
));
|
||||
|
||||
/* @var $assoc \Doctrine\ORM\Mapping\ManyToManyMapping */
|
||||
$assoc = $cm->associationMappings['groups'];
|
||||
$assoc = unserialize(serialize($assoc));
|
||||
|
||||
$this->assertTrue($assoc->owningIsOnDeleteCascade);
|
||||
$this->assertTrue($assoc->inverseIsOnDeleteCascade);
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user