DDC-546 - Added functionality for extra-lazy PersistentCollection::contains().
This commit is contained in:
parent
7c567b305a
commit
75d59d8695
@ -404,22 +404,12 @@ final class PersistentCollection implements Collection
|
|||||||
*/
|
*/
|
||||||
public function contains($element)
|
public function contains($element)
|
||||||
{
|
{
|
||||||
/* DRAFT
|
if (!$this->initialized && $this->association['fetch'] == Mapping\ClassMetadataInfo::FETCH_EXTRALAZY) {
|
||||||
if ($this->initialized) {
|
return $this->coll->contains($element) ||
|
||||||
return $this->coll->contains($element);
|
$this->em->getUnitOfWork()
|
||||||
} else {
|
->getCollectionPersister($this->association)
|
||||||
if ($element is MANAGED) {
|
->contains($this, $element);
|
||||||
if ($this->coll->contains($element)) {
|
}
|
||||||
return true;
|
|
||||||
}
|
|
||||||
$exists = check db for existence;
|
|
||||||
if ($exists) {
|
|
||||||
$this->coll->add($element);
|
|
||||||
}
|
|
||||||
return $exists;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}*/
|
|
||||||
|
|
||||||
$this->initialize();
|
$this->initialize();
|
||||||
return $this->coll->contains($element);
|
return $this->coll->contains($element);
|
||||||
@ -481,7 +471,7 @@ final class PersistentCollection implements Collection
|
|||||||
if (!isset($this->doctrineCollectionCount)) {
|
if (!isset($this->doctrineCollectionCount)) {
|
||||||
$this->doctrineCollectionCount = $this->em->getUnitOfWork()
|
$this->doctrineCollectionCount = $this->em->getUnitOfWork()
|
||||||
->getCollectionPersister($this->association)
|
->getCollectionPersister($this->association)
|
||||||
->count($this) + count ($this->coll->toArray());
|
->count($this) + $this->coll->count();
|
||||||
}
|
}
|
||||||
return $this->doctrineCollectionCount;
|
return $this->doctrineCollectionCount;
|
||||||
}
|
}
|
||||||
|
@ -135,12 +135,12 @@ abstract class AbstractCollectionPersister
|
|||||||
throw new \BadMethodCallException("Slicing elements is not supported by this CollectionPersister.");
|
throw new \BadMethodCallException("Slicing elements is not supported by this CollectionPersister.");
|
||||||
}
|
}
|
||||||
|
|
||||||
public function contains(PersistentCollection $coll, $key)
|
public function contains(PersistentCollection $coll, $element)
|
||||||
{
|
{
|
||||||
throw new \BadMethodCallException("Checking for existance of an element is not supported by this CollectionPersister.");
|
throw new \BadMethodCallException("Checking for existance of an element is not supported by this CollectionPersister.");
|
||||||
}
|
}
|
||||||
|
|
||||||
public function containsKey(PersistentCollection $coll, $element)
|
public function containsKey(PersistentCollection $coll, $key)
|
||||||
{
|
{
|
||||||
throw new \BadMethodCallException("Checking for existance of a key is not supported by this CollectionPersister.");
|
throw new \BadMethodCallException("Checking for existance of a key is not supported by this CollectionPersister.");
|
||||||
}
|
}
|
||||||
|
@ -1326,21 +1326,17 @@ class BasicEntityPersister
|
|||||||
* @param object $entity
|
* @param object $entity
|
||||||
* @return boolean TRUE if the entity exists in the database, FALSE otherwise.
|
* @return boolean TRUE if the entity exists in the database, FALSE otherwise.
|
||||||
*/
|
*/
|
||||||
public function exists($entity)
|
public function exists($entity, array $extraConditions = array())
|
||||||
{
|
{
|
||||||
$criteria = $this->_class->getIdentifierValues($entity);
|
$criteria = $this->_class->getIdentifierValues($entity);
|
||||||
|
if ($extraConditions) {
|
||||||
|
$criteria = array_merge($criteria, $extraConditions);
|
||||||
|
}
|
||||||
|
|
||||||
$sql = 'SELECT 1 FROM ' . $this->_class->getQuotedTableName($this->_platform)
|
$sql = 'SELECT 1 FROM ' . $this->_class->getQuotedTableName($this->_platform)
|
||||||
. ' ' . $this->_getSQLTableAlias($this->_class->name)
|
. ' ' . $this->_getSQLTableAlias($this->_class->name)
|
||||||
. ' WHERE ' . $this->_getSelectConditionSQL($criteria);
|
. ' WHERE ' . $this->_getSelectConditionSQL($criteria);
|
||||||
|
|
||||||
return (bool) $this->_conn->fetchColumn($sql, array_values($criteria));
|
return (bool) $this->_conn->fetchColumn($sql, array_values($criteria));
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO
|
|
||||||
/*protected function _getOneToOneEagerFetchSQL()
|
|
||||||
{
|
|
||||||
|
|
||||||
}*/
|
|
||||||
|
|
||||||
#public function countCollection
|
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,8 @@
|
|||||||
|
|
||||||
namespace Doctrine\ORM\Persisters;
|
namespace Doctrine\ORM\Persisters;
|
||||||
|
|
||||||
use Doctrine\ORM\PersistentCollection;
|
use Doctrine\ORM\PersistentCollection,
|
||||||
|
Doctrine\ORM\UnitOfWork;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Persister for many-to-many collections.
|
* Persister for many-to-many collections.
|
||||||
@ -230,4 +231,53 @@ class ManyToManyPersister extends AbstractCollectionPersister
|
|||||||
->getEntityPersister($mapping['targetEntity'])
|
->getEntityPersister($mapping['targetEntity'])
|
||||||
->getManyToManyCollection($mapping, $coll->getOwner(), $offset, $length);
|
->getManyToManyCollection($mapping, $coll->getOwner(), $offset, $length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param PersistentCollection $coll
|
||||||
|
* @param object $element
|
||||||
|
*/
|
||||||
|
public function contains(PersistentCollection $coll, $element)
|
||||||
|
{
|
||||||
|
$uow = $this->_em->getUnitOfWork();
|
||||||
|
|
||||||
|
// shortcut for new entities
|
||||||
|
if ($uow->getEntityState($element, UnitOfWork::STATE_NEW) == UnitOfWork::STATE_NEW) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$params = array();
|
||||||
|
$mapping = $coll->getMapping();
|
||||||
|
$sourceClass = $this->_em->getClassMetadata($mapping['sourceEntity']);
|
||||||
|
$elementClass = $this->_em->getClassMetadata($mapping['targetEntity']);
|
||||||
|
$sourceId = $uow->getEntityIdentifier($coll->getOwner());
|
||||||
|
$elementId = $uow->getEntityIdentifier($element);
|
||||||
|
|
||||||
|
if ($mapping['isOwningSide']) {
|
||||||
|
$joinTable = $mapping['joinTable'];
|
||||||
|
} else {
|
||||||
|
$joinTable = $elementClass->associationMappings[$mapping['mappedBy']]['joinTable'];
|
||||||
|
}
|
||||||
|
|
||||||
|
$whereClause = '';
|
||||||
|
foreach ($mapping['joinTableColumns'] as $joinTableColumn) {
|
||||||
|
if (isset($mapping['relationToTargetKeyColumns'][$joinTableColumn])) {
|
||||||
|
if ($whereClause !== '') {
|
||||||
|
$whereClause .= ' AND ';
|
||||||
|
}
|
||||||
|
$whereClause .= "$joinTableColumn = ?";
|
||||||
|
|
||||||
|
$params[] = $elementId[$sourceClass->fieldNames[$mapping['relationToTargetKeyColumns'][$joinTableColumn]]];
|
||||||
|
} else if (isset($mapping['relationToSourceKeyColumns'][$joinTableColumn])) {
|
||||||
|
if ($whereClause !== '') {
|
||||||
|
$whereClause .= ' AND ';
|
||||||
|
}
|
||||||
|
$whereClause .= "$joinTableColumn = ?";
|
||||||
|
|
||||||
|
$params[] = $sourceId[$sourceClass->fieldNames[$mapping['relationToSourceKeyColumns'][$joinTableColumn]]];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$sql = 'SELECT 1 FROM ' . $joinTable['name'] . ' WHERE ' . $whereClause;
|
||||||
|
|
||||||
|
return (bool)$this->_conn->fetchColumn($sql, $params);
|
||||||
|
}
|
||||||
}
|
}
|
@ -21,7 +21,8 @@
|
|||||||
|
|
||||||
namespace Doctrine\ORM\Persisters;
|
namespace Doctrine\ORM\Persisters;
|
||||||
|
|
||||||
use Doctrine\ORM\PersistentCollection;
|
use Doctrine\ORM\PersistentCollection,
|
||||||
|
Doctrine\ORM\UnitOfWork;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Persister for one-to-many collections.
|
* Persister for one-to-many collections.
|
||||||
@ -153,4 +154,26 @@ class OneToManyPersister extends AbstractCollectionPersister
|
|||||||
->getEntityPersister($mapping['targetEntity'])
|
->getEntityPersister($mapping['targetEntity'])
|
||||||
->getOneToManyCollection($mapping, $coll->getOwner(), $offset, $length);
|
->getOneToManyCollection($mapping, $coll->getOwner(), $offset, $length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param PersistentCollection $coll
|
||||||
|
* @param object $element
|
||||||
|
*/
|
||||||
|
public function contains(PersistentCollection $coll, $element)
|
||||||
|
{
|
||||||
|
$mapping = $coll->getMapping();
|
||||||
|
$uow = $this->_em->getUnitOfWork();
|
||||||
|
|
||||||
|
// shortcut for new entities
|
||||||
|
if ($uow->getEntityState($element, UnitOfWork::STATE_NEW) == UnitOfWork::STATE_NEW) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// only works with single id identifier entities. Will throw an exception in Entity Persisters
|
||||||
|
// if that is not the case for the 'mappedBy' field.
|
||||||
|
$id = current( $uow->getEntityIdentifier($coll->getOwner()) );
|
||||||
|
|
||||||
|
return $uow->getEntityPersister($mapping['targetEntity'])
|
||||||
|
->exists($element, array($mapping['mappedBy'] => $id));
|
||||||
|
}
|
||||||
}
|
}
|
@ -15,6 +15,7 @@ class ExtraLazyCollectionTest extends \Doctrine\Tests\OrmFunctionalTestCase
|
|||||||
{
|
{
|
||||||
private $userId;
|
private $userId;
|
||||||
private $groupId;
|
private $groupId;
|
||||||
|
private $articleId;
|
||||||
|
|
||||||
public function setUp()
|
public function setUp()
|
||||||
{
|
{
|
||||||
@ -215,6 +216,70 @@ class ExtraLazyCollectionTest extends \Doctrine\Tests\OrmFunctionalTestCase
|
|||||||
$this->assertEquals($queryCount + 2, $this->getCurrentQueryCount());
|
$this->assertEquals($queryCount + 2, $this->getCurrentQueryCount());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @group DDC-546
|
||||||
|
*/
|
||||||
|
public function testContainsOneToMany()
|
||||||
|
{
|
||||||
|
$user = $this->_em->find('Doctrine\Tests\Models\CMS\CmsUser', $this->userId);
|
||||||
|
$this->assertFalse($user->articles->isInitialized(), "Pre-Condition: Collection is not initialized.");
|
||||||
|
|
||||||
|
$article = $this->_em->find('Doctrine\Tests\Models\CMS\CmsArticle', $this->articleId);
|
||||||
|
|
||||||
|
$queryCount = $this->getCurrentQueryCount();
|
||||||
|
$this->assertTrue($user->articles->contains($article));
|
||||||
|
$this->assertFalse($user->articles->isInitialized(), "Post-Condition: Collection is not initialized.");
|
||||||
|
$this->assertEquals($queryCount + 1, $this->getCurrentQueryCount());
|
||||||
|
|
||||||
|
$article = new \Doctrine\Tests\Models\CMS\CmsArticle();
|
||||||
|
$article->topic = "Testnew";
|
||||||
|
$article->text = "blub";
|
||||||
|
|
||||||
|
$queryCount = $this->getCurrentQueryCount();
|
||||||
|
$this->assertFalse($user->articles->contains($article));
|
||||||
|
$this->assertEquals($queryCount, $this->getCurrentQueryCount(), "Checking for contains of new entity should cause no query to be executed.");
|
||||||
|
|
||||||
|
$this->_em->persist($article);
|
||||||
|
$this->_em->flush();
|
||||||
|
|
||||||
|
$queryCount = $this->getCurrentQueryCount();
|
||||||
|
$this->assertFalse($user->articles->contains($article));
|
||||||
|
$this->assertEquals($queryCount+1, $this->getCurrentQueryCount(), "Checking for contains of managed entity should cause one query to be executed.");
|
||||||
|
$this->assertFalse($user->articles->isInitialized(), "Post-Condition: Collection is not initialized.");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @group DDC-546
|
||||||
|
*/
|
||||||
|
public function testContainsManyToMany()
|
||||||
|
{
|
||||||
|
$user = $this->_em->find('Doctrine\Tests\Models\CMS\CmsUser', $this->userId);
|
||||||
|
$this->assertFalse($user->groups->isInitialized(), "Pre-Condition: Collection is not initialized.");
|
||||||
|
|
||||||
|
$group = $this->_em->find('Doctrine\Tests\Models\CMS\CmsGroup', $this->groupId);
|
||||||
|
|
||||||
|
$queryCount = $this->getCurrentQueryCount();
|
||||||
|
$this->assertTrue($user->groups->contains($group));
|
||||||
|
$this->assertEquals($queryCount+1, $this->getCurrentQueryCount(), "Checking for contains of managed entity should cause one query to be executed.");
|
||||||
|
$this->assertFalse($user->groups->isInitialized(), "Post-Condition: Collection is not initialized.");
|
||||||
|
|
||||||
|
$group = new \Doctrine\Tests\Models\CMS\CmsGroup();
|
||||||
|
$group->name = "A New group!";
|
||||||
|
|
||||||
|
$queryCount = $this->getCurrentQueryCount();
|
||||||
|
$this->assertFalse($user->groups->contains($group));
|
||||||
|
$this->assertEquals($queryCount, $this->getCurrentQueryCount(), "Checking for contains of new entity should cause no query to be executed.");
|
||||||
|
$this->assertFalse($user->groups->isInitialized(), "Post-Condition: Collection is not initialized.");
|
||||||
|
|
||||||
|
$this->_em->persist($group);
|
||||||
|
$this->_em->flush();
|
||||||
|
|
||||||
|
$queryCount = $this->getCurrentQueryCount();
|
||||||
|
$this->assertFalse($user->groups->contains($group));
|
||||||
|
$this->assertEquals($queryCount+1, $this->getCurrentQueryCount(), "Checking for contains of managed entity should cause one query to be executed.");
|
||||||
|
$this->assertFalse($user->groups->isInitialized(), "Post-Condition: Collection is not initialized.");
|
||||||
|
}
|
||||||
|
|
||||||
private function loadFixture()
|
private function loadFixture()
|
||||||
{
|
{
|
||||||
$user1 = new \Doctrine\Tests\Models\CMS\CmsUser();
|
$user1 = new \Doctrine\Tests\Models\CMS\CmsUser();
|
||||||
@ -278,7 +343,8 @@ class ExtraLazyCollectionTest extends \Doctrine\Tests\OrmFunctionalTestCase
|
|||||||
|
|
||||||
$this->_em->flush();
|
$this->_em->flush();
|
||||||
$this->_em->clear();
|
$this->_em->clear();
|
||||||
|
|
||||||
|
$this->articleId = $article1->id;
|
||||||
$this->userId = $user1->getId();
|
$this->userId = $user1->getId();
|
||||||
$this->groupId = $group1->id;
|
$this->groupId = $group1->id;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user