1
0
mirror of synced 2025-01-19 06:51:40 +03:00

fix some an infinite recursion when deleting records that reference each other with ownsOne

This commit is contained in:
gnat 2007-07-06 21:18:36 +00:00
parent 56768b613f
commit 85ec506691
4 changed files with 67 additions and 5 deletions

View File

@ -222,8 +222,12 @@ class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module
$record->preDelete($event); $record->preDelete($event);
$record->state(Doctrine_Record::STATE_LOCKED);
$this->deleteComposites($record); $this->deleteComposites($record);
$record->state(Doctrine_Record::STATE_TDIRTY);
if ( ! $event->skipOperation) { if ( ! $event->skipOperation) {
$this->conn->transaction->addDelete($record); $this->conn->transaction->addDelete($record);
@ -329,7 +333,12 @@ class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module
case Doctrine_Relation::ONE_COMPOSITE: case Doctrine_Relation::ONE_COMPOSITE:
case Doctrine_Relation::MANY_COMPOSITE: case Doctrine_Relation::MANY_COMPOSITE:
$obj = $record->get($fk->getAlias()); $obj = $record->get($fk->getAlias());
if ( $obj instanceof Doctrine_Record &&
$obj->state() != Doctrine_Record::STATE_LOCKED) {
$obj->delete($this->conn); $obj->delete($this->conn);
}
break; break;
} }
} }

View File

@ -65,10 +65,10 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count
*/ */
const STATE_TCLEAN = 5; const STATE_TCLEAN = 5;
/** /**
* DELETED STATE * LOCKED STATE
* a Doctrine_Record turns into deleted state when it is deleted * a Doctrine_Record is temporarily locked during deletes
*/ */
const STATE_DELETED = 6; const STATE_LOCKED = 6;
/** /**
* @var object Doctrine_Table $_table the factory that created this data access object * @var object Doctrine_Table $_table the factory that created this data access object
*/ */

View File

@ -0,0 +1,52 @@
<?php
class Doctrine_Record_Lock_TestCase extends Doctrine_UnitTestCase {
public function prepareTables()
{
$this->tables[] = 'rec1';
$this->tables[] = 'rec2';
parent::prepareTables();
}
public function prepareData() { }
public function testDeleteRecords()
{
$rec1 = new Rec1();
$rec1->first_name = 'Some name';
$rec1->Account = new Rec2();
$rec1->Account->address = 'Some address';
$rec1->save();
$rec1->delete();
$this->pass();
}
}
class Rec1 extends Doctrine_Record
{
public function setTableDefinition()
{
$this->hasColumn('first_name', 'string', 128, array ());
}
public function setUp()
{
$this->ownsOne('Rec2 as Account', array('local' => 'id', 'foreign' => 'user_id'));
}
}
class Rec2 extends Doctrine_Record
{
public function setTableDefinition()
{
$this->hasColumn('user_id', 'integer', 10, array ( 'unique' => true,));
$this->hasColumn('address', 'string', 150, array ());
}
public function setUp()
{
$this->ownsOne('Rec1 as User', 'Rec2.user_id');
}
}

View File

@ -280,7 +280,8 @@ $test->addTestCase(new Doctrine_NewCore_TestCase());
$test->addTestCase(new Doctrine_Record_State_TestCase()); $test->addTestCase(new Doctrine_Record_State_TestCase());
// This test used to segfault php because of infinite recursion in Connection/UnitOfWork
$test->addTestCase(new Doctrine_Record_Lock_TestCase());
$test->addTestCase(new Doctrine_Tokenizer_TestCase()); $test->addTestCase(new Doctrine_Tokenizer_TestCase());