1
0
mirror of synced 2025-02-20 22:23:14 +03:00

Add support for optimized contains

This commit is contained in:
Michaël Gallego 2014-05-17 12:54:25 +02:00
parent d6c727dcc1
commit a04113f410
7 changed files with 75 additions and 11 deletions

View File

@ -190,8 +190,11 @@ abstract class AbstractEntityPersister implements CachedEntityPersister
/**
* {@inheritdoc}
* @param object $entity
* @param array $extraConditions
* @return bool
*/
public function exists($entity, array $extraConditions = array())
public function exists($entity, $extraConditions = array())
{
if (empty($extraConditions)) {
$key = new EntityCacheKey($this->class->rootEntityName, $this->class->getIdentifierValues($entity));

View File

@ -30,7 +30,7 @@ use Doctrine\ORM\Persisters\EntityPersister;
* A lazy collection that allow a fast count when using criteria object
* Once count gets executed once without collection being initialized, result
* is cached and returned on subsequent calls until collection gets loaded,
* then returning the number of loaded results.
* then returning the number of loaded results.
*
* @since 2.5
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
@ -82,6 +82,21 @@ class LazyCriteriaCollection extends AbstractLazyCollection implements Selectabl
return $this->count = $this->entityPersister->count($this->criteria);
}
/**
* Do an optimized search of an element
*
* @param object $element
* @return bool
*/
public function contains($element)
{
if ($this->isInitialized()) {
return $this->collection->contains($element);
}
return $this->entityPersister->exists($element, $this->criteria);
}
/**
* {@inheritDoc}
*/

View File

@ -1834,8 +1834,11 @@ class BasicEntityPersister implements EntityPersister
/**
* {@inheritdoc}
* @param object $entity
* @param array $extraConditions
* @return bool
*/
public function exists($entity, array $extraConditions = array())
public function exists($entity, $extraConditions = array())
{
$criteria = $this->class->getIdentifierValues($entity);
@ -1843,7 +1846,7 @@ class BasicEntityPersister implements EntityPersister
return false;
}
if ($extraConditions) {
if (is_array($extraConditions)) {
$criteria = array_merge($criteria, $extraConditions);
}
@ -1853,12 +1856,19 @@ class BasicEntityPersister implements EntityPersister
. $this->getLockTablesSql(null)
. ' WHERE ' . $this->getSelectConditionSQL($criteria);
list($params) = $this->expandParameters($criteria);
if ($extraConditions instanceof Criteria) {
$sql .= ' AND ' . $this->getSelectConditionCriteriaSQL($extraConditions);
list($criteriaParams, $values) = $this->expandCriteriaParameters($extraConditions);
$params = array_merge($params, $criteriaParams);
}
if ($filterSql = $this->generateFilterConditionSQL($this->class, $alias)) {
$sql .= ' AND ' . $filterSql;
}
list($params) = $this->expandParameters($criteria);
return (bool) $this->conn->fetchColumn($sql, $params);
}

View File

@ -319,10 +319,10 @@ interface EntityPersister
/**
* Checks whether the given managed entity exists in the database.
*
* @param object $entity
* @param array $extraConditions
* @param object $entity
* @param array|Criteria $extraConditions
*
* @return boolean TRUE if the entity exists in the database, FALSE otherwise.
*/
public function exists($entity, array $extraConditions = array());
public function exists($entity, $extraConditions = array());
}

View File

@ -168,7 +168,7 @@ class OneToManyPersister extends AbstractCollectionPersister
return (bool) $this->conn->fetchColumn($sql, $params);
}
private function getJoinTableRestrictions(PersistentCollection $coll, $addFilters)
{
$mapping = $coll->getMapping();

View File

@ -87,8 +87,11 @@ class EntityPersisterMock extends \Doctrine\ORM\Persisters\BasicEntityPersister
/**
* {@inheritdoc}
* @param object $entity
* @param array $extraConditions
* @return bool|void
*/
public function exists($entity, array $extraConditions = array())
public function exists($entity, $extraConditions = array())
{
$this->existsCalled = true;
}

View File

@ -21,6 +21,8 @@ namespace Doctrine\Tests\ORM\Functional;
use Doctrine\Tests\Models\Generic\DateTimeModel;
use Doctrine\Common\Collections\Criteria;
use Doctrine\Tests\Models\Tweet\Tweet;
use Doctrine\Tests\Models\Tweet\User;
/**
* @author Josiah <josiah@jjs.id.au>
@ -30,6 +32,7 @@ class EntityRepositoryCriteriaTest extends \Doctrine\Tests\OrmFunctionalTestCase
protected function setUp()
{
$this->useModelSet('generic');
$this->useModelSet('tweet');
parent::setUp();
}
@ -165,4 +168,34 @@ class EntityRepositoryCriteriaTest extends \Doctrine\Tests\OrmFunctionalTestCase
$date = $dates[0];
$this->assertTrue($dates->isInitialized());
}
public function testCanContainsWithoutLoadingCollection()
{
$user = new User();
$user->name = 'Marco';
$this->_em->persist($user);
$this->_em->flush();
$tweet = new Tweet();
$tweet->author = $user;
$tweet->content = 'Criteria is awesome';
$this->_em->persist($tweet);
$this->_em->flush();
$this->_em->clear();
$criteria = new Criteria();
$criteria->andWhere($criteria->expr()->contains('content', 'Criteria'));
$user = $this->_em->find('Doctrine\Tests\Models\Tweet\User', $user->id);
$tweets = $user->tweets->matching($criteria);
$this->assertInstanceOf('Doctrine\ORM\LazyCriteriaCollection', $tweets);
$this->assertFalse($tweets->isInitialized());
$tweets->contains($tweet);
$this->assertTrue($tweets->contains($tweet));
$this->assertFalse($tweets->isInitialized());
}
}