1
0
mirror of synced 2025-01-18 22:41:43 +03:00

Merge branch 'DDC-1278'

This commit is contained in:
Benjamin Eberlei 2011-10-16 22:45:50 +02:00
commit 1a602a8cb3
5 changed files with 117 additions and 30 deletions

View File

@ -422,16 +422,11 @@ class EntityManager implements ObjectManager
* Clears the EntityManager. All entities that are currently managed * Clears the EntityManager. All entities that are currently managed
* by this EntityManager become detached. * by this EntityManager become detached.
* *
* @param string $entityName * @param string $entityName if given, only entities of this type will get detached
*/ */
public function clear($entityName = null) public function clear($entityName = null)
{ {
if ($entityName === null) { $this->unitOfWork->clear($entityName);
$this->unitOfWork->clear();
} else {
//TODO
throw new ORMException("EntityManager#clear(\$entityName) not yet implemented.");
}
} }
/** /**

View File

@ -36,12 +36,18 @@ class OnClearEventArgs extends \Doctrine\Common\EventArgs
*/ */
private $em; private $em;
/**
* @var string
*/
private $entityClass;
/** /**
* @param \Doctrine\ORM\EntityManager $em * @param \Doctrine\ORM\EntityManager $em
*/ */
public function __construct($em) public function __construct($em, $entityClass = null)
{ {
$this->em = $em; $this->em = $em;
$this->entityClass = $entityClass;
} }
/** /**
@ -51,4 +57,24 @@ class OnClearEventArgs extends \Doctrine\Common\EventArgs
{ {
return $this->em; return $this->em;
} }
/**
* Name of the entity class that is cleared, or empty if all are cleared.
*
* @return string
*/
public function getEntityClass()
{
return $this->entityClass;
}
/**
* Check if event clears all entities.
*
* @return bool
*/
public function clearsAllEntities()
{
return $this->entityClass === null;
}
} }

View File

@ -1567,8 +1567,9 @@ class UnitOfWork implements PropertyChangedListener
* *
* @param object $entity * @param object $entity
* @param array $visited * @param array $visited
* @param boolean $noCascade if true, don't cascade detach operation
*/ */
private function doDetach($entity, array &$visited) private function doDetach($entity, array &$visited, $noCascade = false)
{ {
$oid = spl_object_hash($entity); $oid = spl_object_hash($entity);
if (isset($visited[$oid])) { if (isset($visited[$oid])) {
@ -1591,8 +1592,10 @@ class UnitOfWork implements PropertyChangedListener
return; return;
} }
if (!$noCascade) {
$this->cascadeDetach($entity, $visited); $this->cascadeDetach($entity, $visited);
} }
}
/** /**
* Refreshes the state of the given entity from the database, overwriting * Refreshes the state of the given entity from the database, overwriting
@ -1842,9 +1845,12 @@ class UnitOfWork implements PropertyChangedListener
/** /**
* Clears the UnitOfWork. * Clears the UnitOfWork.
*
* @param string $entityName if given, only entities of this type will get detached
*/ */
public function clear() public function clear($entityName = null)
{ {
if ($entityName === null) {
$this->identityMap = $this->identityMap =
$this->entityIdentifiers = $this->entityIdentifiers =
$this->originalEntityData = $this->originalEntityData =
@ -1861,9 +1867,19 @@ class UnitOfWork implements PropertyChangedListener
if ($this->commitOrderCalculator !== null) { if ($this->commitOrderCalculator !== null) {
$this->commitOrderCalculator->clear(); $this->commitOrderCalculator->clear();
} }
} else {
$visited = array();
foreach ($this->identityMap as $className => $entities) {
if ($className === $entityName) {
foreach ($entities as $entity) {
$this->doDetach($entity, $visited, true);
}
}
}
}
if ($this->evm->hasListeners(Events::onClear)) { if ($this->evm->hasListeners(Events::onClear)) {
$this->evm->dispatchEvent(Events::onClear, new Event\OnClearEventArgs($this->em)); $this->evm->dispatchEvent(Events::onClear, new Event\OnClearEventArgs($this->em, $entityName));
} }
} }

View File

@ -35,7 +35,7 @@ class CmsUser
*/ */
public $phonenumbers; public $phonenumbers;
/** /**
* @OneToMany(targetEntity="CmsArticle", mappedBy="user") * @OneToMany(targetEntity="CmsArticle", mappedBy="user", cascade={"detach"})
*/ */
public $articles; public $articles;
/** /**
@ -48,7 +48,7 @@ class CmsUser
*/ */
public $email; public $email;
/** /**
* @ManyToMany(targetEntity="CmsGroup", inversedBy="users", cascade={"persist", "merge"}) * @ManyToMany(targetEntity="CmsGroup", inversedBy="users", cascade={"persist", "merge", "detach"})
* @JoinTable(name="cms_users_groups", * @JoinTable(name="cms_users_groups",
* joinColumns={@JoinColumn(name="user_id", referencedColumnName="id")}, * joinColumns={@JoinColumn(name="user_id", referencedColumnName="id")},
* inverseJoinColumns={@JoinColumn(name="group_id", referencedColumnName="id")} * inverseJoinColumns={@JoinColumn(name="group_id", referencedColumnName="id")}

View File

@ -980,4 +980,54 @@ class BasicFunctionalTest extends \Doctrine\Tests\OrmFunctionalTestCase
$this->assertTrue($article->user->__isInitialized__, "...but its initialized!"); $this->assertTrue($article->user->__isInitialized__, "...but its initialized!");
$this->assertEquals($qc+2, $this->getCurrentQueryCount()); $this->assertEquals($qc+2, $this->getCurrentQueryCount());
} }
/**
* @group DDC-1278
*/
public function testClearWithEntityName()
{
$user = new CmsUser;
$user->name = 'Dominik';
$user->username = 'domnikl';
$user->status = 'developer';
$address = new CmsAddress();
$address->city = "Springfield";
$address->zip = "12354";
$address->country = "Germany";
$address->street = "Foo Street";
$address->user = $user;
$user->address = $address;
$article1 = new CmsArticle();
$article1->topic = 'Foo';
$article1->text = 'Foo Text';
$article2 = new CmsArticle();
$article2->topic = 'Bar';
$article2->text = 'Bar Text';
$user->addArticle($article1);
$user->addArticle($article2);
$this->_em->persist($article1);
$this->_em->persist($article2);
$this->_em->persist($address);
$this->_em->persist($user);
$this->_em->flush();
$unitOfWork = $this->_em->getUnitOfWork();
$this->_em->clear('Doctrine\Tests\Models\CMS\CmsUser');
$this->assertEquals(\Doctrine\ORM\UnitOfWork::STATE_DETACHED, $unitOfWork->getEntityState($user));
$this->assertEquals(\Doctrine\ORM\UnitOfWork::STATE_MANAGED, $unitOfWork->getEntityState($address));
$this->assertEquals(\Doctrine\ORM\UnitOfWork::STATE_MANAGED, $unitOfWork->getEntityState($article1));
$this->assertEquals(\Doctrine\ORM\UnitOfWork::STATE_MANAGED, $unitOfWork->getEntityState($article2));
$this->_em->clear();
$this->assertEquals(\Doctrine\ORM\UnitOfWork::STATE_DETACHED, $unitOfWork->getEntityState($address));
}
} }