DDC-130 - Refactored deleteJoinTableRecords() support
This commit is contained in:
parent
233b3cd0b9
commit
1794127d51
@ -68,6 +68,20 @@ class ManyToManyMapping extends AssociationMapping
|
|||||||
*/
|
*/
|
||||||
public $orderBy;
|
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}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
@ -115,11 +129,19 @@ class ManyToManyMapping extends AssociationMapping
|
|||||||
}
|
}
|
||||||
|
|
||||||
foreach ($mapping['joinTable']['joinColumns'] as $joinColumn) {
|
foreach ($mapping['joinTable']['joinColumns'] as $joinColumn) {
|
||||||
|
if (isset($joinColumn['onDelete']) && strtolower($joinColumn['onDelete']) == 'cascade') {
|
||||||
|
$this->owningIsOnDeleteCascade = true;
|
||||||
|
}
|
||||||
|
|
||||||
$this->relationToSourceKeyColumns[$joinColumn['name']] = $joinColumn['referencedColumnName'];
|
$this->relationToSourceKeyColumns[$joinColumn['name']] = $joinColumn['referencedColumnName'];
|
||||||
$this->joinTableColumns[] = $joinColumn['name'];
|
$this->joinTableColumns[] = $joinColumn['name'];
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($mapping['joinTable']['inverseJoinColumns'] as $inverseJoinColumn) {
|
foreach ($mapping['joinTable']['inverseJoinColumns'] as $inverseJoinColumn) {
|
||||||
|
if (isset($inverseJoinColumn['onDelete']) && strtolower($inverseJoinColumn['onDelete']) == 'cascade') {
|
||||||
|
$this->inverseIsOnDeleteCascade = true;
|
||||||
|
}
|
||||||
|
|
||||||
$this->relationToTargetKeyColumns[$inverseJoinColumn['name']] = $inverseJoinColumn['referencedColumnName'];
|
$this->relationToTargetKeyColumns[$inverseJoinColumn['name']] = $inverseJoinColumn['referencedColumnName'];
|
||||||
$this->joinTableColumns[] = $inverseJoinColumn['name'];
|
$this->joinTableColumns[] = $inverseJoinColumn['name'];
|
||||||
}
|
}
|
||||||
@ -169,6 +191,12 @@ class ManyToManyMapping extends AssociationMapping
|
|||||||
$serialized[] = 'joinTableColumns';
|
$serialized[] = 'joinTableColumns';
|
||||||
$serialized[] = 'relationToSourceKeyColumns';
|
$serialized[] = 'relationToSourceKeyColumns';
|
||||||
$serialized[] = 'relationToTargetKeyColumns';
|
$serialized[] = 'relationToTargetKeyColumns';
|
||||||
|
if ($this->owningIsOnDeleteCascade) {
|
||||||
|
$serialized[] = 'owningIsOnDeleteCascade';
|
||||||
|
}
|
||||||
|
if ($this->inverseIsOnDeleteCascade) {
|
||||||
|
$serialized[] = 'inverseIsOnDeleteCascade';
|
||||||
|
}
|
||||||
if ($this->orderBy) {
|
if ($this->orderBy) {
|
||||||
$serialized[] = 'orderBy';
|
$serialized[] = 'orderBy';
|
||||||
}
|
}
|
||||||
|
@ -335,8 +335,6 @@ class BasicEntityPersister
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private $requiredJoinTableDeletions = null;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @todo Add check for platform if it supports foreign keys/cascading.
|
* @todo Add check for platform if it supports foreign keys/cascading.
|
||||||
* @param array $identifier
|
* @param array $identifier
|
||||||
@ -344,43 +342,26 @@ class BasicEntityPersister
|
|||||||
*/
|
*/
|
||||||
protected function deleteJoinTableRecords($identifier)
|
protected function deleteJoinTableRecords($identifier)
|
||||||
{
|
{
|
||||||
if ($this->requiredJoinTableDeletions === null) {
|
|
||||||
$this->requiredJoinTableDeletions = array();
|
|
||||||
foreach ($this->_class->associationMappings AS $mapping) {
|
foreach ($this->_class->associationMappings AS $mapping) {
|
||||||
/* @var $mapping \Doctrine\ORM\Mapping\AssociationMapping */
|
/* @var $mapping \Doctrine\ORM\Mapping\AssociationMapping */
|
||||||
if ($mapping->isManyToMany()) {
|
if ($mapping->isManyToMany()) {
|
||||||
// TODO: Write test for composite keys
|
if($mapping->isOwningSide && (!$mapping->owningIsOnDeleteCascade || !$this->_platform->supportsForeignKeyConstraints())) {
|
||||||
if (!$mapping->isOwningSide) {
|
$this->_conn->delete(
|
||||||
|
$mapping->joinTable['name'],
|
||||||
|
array_combine(array_keys($mapping->relationToSourceKeyColumns), $identifier)
|
||||||
|
);
|
||||||
|
} else if (!$mapping->isOwningSide) {
|
||||||
$relatedClass = $this->_em->getClassMetadata($mapping->targetEntityName);
|
$relatedClass = $this->_em->getClassMetadata($mapping->targetEntityName);
|
||||||
$mapping = $relatedClass->associationMappings[$mapping->mappedBy];
|
$relatedMapping = $relatedClass->associationMappings[$mapping->mappedBy];
|
||||||
$keys = array_keys($mapping->relationToTargetKeyColumns);
|
|
||||||
|
|
||||||
// this is not semantically correct, onDelete should be an option of the joinColumns
|
if (!$relatedMapping->inverseIsOnDeleteCascade || !$this->_platform->supportsForeignKeyConstraints()) {
|
||||||
// @todo optimize this (potentially in the validate association/metadata already)
|
$this->_conn->delete(
|
||||||
foreach ($mapping->joinTable['inverseJoinColumns'] AS $joinColumn) {
|
$relatedMapping->joinTable['name'],
|
||||||
if (strtoupper($joinColumn['onDelete']) == 'CASCADE') {
|
array_combine(array_keys($relatedMapping->relationToTargetKeyColumns), $identifier)
|
||||||
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);
|
|
||||||
}
|
|
||||||
$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')),
|
'joinColumns' => array(array('name' => 'CmsUser_id', 'referencedColumnName' => 'id', 'onDelete' => 'CASCADE')),
|
||||||
'inverseJoinColumns' => array(array('name' => 'CmsGroup_id', 'referencedColumnName' => 'id', 'onDelete' => 'CASCADE'))
|
'inverseJoinColumns' => array(array('name' => 'CmsGroup_id', 'referencedColumnName' => 'id', 'onDelete' => 'CASCADE'))
|
||||||
), $assoc->joinTable);
|
), $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…
x
Reference in New Issue
Block a user