From d30e3ab43ca89d9e81b1cbe940b25b40b510baa9 Mon Sep 17 00:00:00 2001 From: Guilherme Blanco Date: Fri, 16 May 2014 04:22:11 +0000 Subject: [PATCH] Added count cache when lazy collection is not yet initialized. Some cosmetic changes (primarily, there's no ELSE). --- lib/Doctrine/ORM/LazyCriteriaCollection.php | 19 +++++++++++++++++-- lib/Doctrine/ORM/PersistentCollection.php | 8 +++----- .../ORM/Persisters/BasicEntityPersister.php | 6 +++--- .../Persisters/JoinedSubclassPersister.php | 12 ++++++------ 4 files changed, 29 insertions(+), 16 deletions(-) diff --git a/lib/Doctrine/ORM/LazyCriteriaCollection.php b/lib/Doctrine/ORM/LazyCriteriaCollection.php index c88cc083e..488ec9cc0 100644 --- a/lib/Doctrine/ORM/LazyCriteriaCollection.php +++ b/lib/Doctrine/ORM/LazyCriteriaCollection.php @@ -28,8 +28,12 @@ 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. * * @since 2.5 + * @author Guilherme Blanco * @author Michaƫl Gallego */ class LazyCriteriaCollection extends AbstractLazyCollection implements Selectable @@ -44,6 +48,11 @@ class LazyCriteriaCollection extends AbstractLazyCollection implements Selectabl */ protected $criteria; + /** + * @var integer + */ + private $count; + /** * @param EntityPersister $entityPersister * @param Criteria $criteria @@ -57,7 +66,7 @@ class LazyCriteriaCollection extends AbstractLazyCollection implements Selectabl /** * Do an efficient count on the collection * - * @return int + * @return integer */ public function count() { @@ -65,7 +74,12 @@ class LazyCriteriaCollection extends AbstractLazyCollection implements Selectabl return $this->collection->count(); } - return $this->entityPersister->count($this->criteria); + // Return cached result in case count query was already executed + if ($this->count) { + return $this->count; + } + + return $this->count = $this->entityPersister->count($this->criteria); } /** @@ -74,6 +88,7 @@ class LazyCriteriaCollection extends AbstractLazyCollection implements Selectabl public function matching(Criteria $criteria) { $this->initialize(); + return $this->collection->matching($criteria); } diff --git a/lib/Doctrine/ORM/PersistentCollection.php b/lib/Doctrine/ORM/PersistentCollection.php index 1142c4266..c668d7a51 100644 --- a/lib/Doctrine/ORM/PersistentCollection.php +++ b/lib/Doctrine/ORM/PersistentCollection.php @@ -883,10 +883,8 @@ final class PersistentCollection implements Collection, Selectable $persister = $this->em->getUnitOfWork()->getEntityPersister($this->association['targetEntity']); - if ($this->association['fetch'] === ClassMetadataInfo::FETCH_EXTRA_LAZY) { - return new LazyCriteriaCollection($persister, $criteria); - } else { - return new ArrayCollection($persister->loadCriteria($criteria)); - } + return ($this->association['fetch'] === ClassMetadataInfo::FETCH_EXTRA_LAZY) + ? new LazyCriteriaCollection($persister, $criteria) + : new ArrayCollection($persister->loadCriteria($criteria)); } } diff --git a/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php b/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php index 8bb087e17..e7a74327c 100644 --- a/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php +++ b/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php @@ -848,9 +848,11 @@ class BasicEntityPersister implements EntityPersister public function expandCriteriaParameters(Criteria $criteria) { $expression = $criteria->getWhereExpression(); + $sqlParams = array(); + $sqlTypes = array(); if ($expression === null) { - return array(array(), array()); + return array($sqlParams, $sqlTypes); } $valueVisitor = new SqlValueVisitor(); @@ -859,12 +861,10 @@ class BasicEntityPersister implements EntityPersister list($params, $types) = $valueVisitor->getParamsAndTypes(); - $sqlParams = array(); foreach ($params as $param) { $sqlParams[] = $this->getValue($param); } - $sqlTypes = array(); foreach ($types as $type) { list($field, $value) = $type; $sqlTypes[] = $this->getType($field, $value); diff --git a/lib/Doctrine/ORM/Persisters/JoinedSubclassPersister.php b/lib/Doctrine/ORM/Persisters/JoinedSubclassPersister.php index 128fe4292..893a3e31e 100644 --- a/lib/Doctrine/ORM/Persisters/JoinedSubclassPersister.php +++ b/lib/Doctrine/ORM/Persisters/JoinedSubclassPersister.php @@ -560,15 +560,15 @@ class JoinedSubclassPersister extends AbstractEntityInheritancePersister */ private function getJoinSql($baseTableAlias) { - $joinSql = ''; - $identifierColumn = $this->class->getIdentifierColumnNames(); + $joinSql = ''; + $identifierColumn = $this->class->getIdentifierColumnNames(); // INNER JOIN parent tables foreach ($this->class->parentClasses as $parentClassName) { - $conditions = array(); - $parentClass = $this->em->getClassMetadata($parentClassName); - $tableAlias = $this->getSQLTableAlias($parentClassName); - $joinSql .= ' INNER JOIN ' . $this->quoteStrategy->getTableName($parentClass, $this->platform) . ' ' . $tableAlias . ' ON '; + $conditions = array(); + $parentClass = $this->em->getClassMetadata($parentClassName); + $tableAlias = $this->getSQLTableAlias($parentClassName); + $joinSql .= ' INNER JOIN ' . $this->quoteStrategy->getTableName($parentClass, $this->platform) . ' ' . $tableAlias . ' ON '; foreach ($identifierColumn as $idColumn) {