From ac15b184b675e68ed2dd7341ae70a82ee0fdc7c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Gallego?= Date: Sun, 5 Jan 2014 13:11:25 +0100 Subject: [PATCH] Fix tests for inheritance support --- lib/Doctrine/ORM/PersistentCollection.php | 13 ++- .../ORM/Persisters/BasicEntityPersister.php | 22 ++-- .../Persisters/JoinedSubclassPersister.php | 105 ++++++++++++------ .../ORM/Persisters/SingleTablePersister.php | 4 +- .../Functional/SingleTableInheritanceTest.php | 3 + 5 files changed, 96 insertions(+), 51 deletions(-) diff --git a/lib/Doctrine/ORM/PersistentCollection.php b/lib/Doctrine/ORM/PersistentCollection.php index ef1de936c..1142c4266 100644 --- a/lib/Doctrine/ORM/PersistentCollection.php +++ b/lib/Doctrine/ORM/PersistentCollection.php @@ -19,14 +19,13 @@ namespace Doctrine\ORM; -use Doctrine\ORM\Mapping\ClassMetadata; - +use Closure; use Doctrine\Common\Collections\Collection; use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\Selectable; use Doctrine\Common\Collections\Criteria; - -use Closure; +use Doctrine\ORM\Mapping\ClassMetadata; +use Doctrine\ORM\Mapping\ClassMetadataInfo; /** * A PersistentCollection represents a collection of elements that have persistent state. @@ -884,6 +883,10 @@ final class PersistentCollection implements Collection, Selectable $persister = $this->em->getUnitOfWork()->getEntityPersister($this->association['targetEntity']); - return new LazyCriteriaCollection($persister, $criteria); + if ($this->association['fetch'] === ClassMetadataInfo::FETCH_EXTRA_LAZY) { + return new LazyCriteriaCollection($persister, $criteria); + } else { + return new ArrayCollection($persister->loadCriteria($criteria)); + } } } diff --git a/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php b/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php index 1bf5f4347..8bb087e17 100644 --- a/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php +++ b/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php @@ -817,11 +817,11 @@ class BasicEntityPersister implements EntityPersister { $sql = $this->getCountSQL($criteria); - list($values, $types) = ($criteria instanceof Criteria) + list($params, $types) = ($criteria instanceof Criteria) ? $this->expandCriteriaParameters($criteria) : $this->expandParameters($criteria); - return $this->conn->fetchColumn($sql, $values); + return $this->conn->executeQuery($sql, $params, $types)->fetchColumn(); } /** @@ -857,20 +857,20 @@ class BasicEntityPersister implements EntityPersister $valueVisitor->dispatch($expression); - list($values, $types) = $valueVisitor->getParamsAndTypes(); + list($params, $types) = $valueVisitor->getParamsAndTypes(); - $sqlValues = array(); - foreach ($values as $value) { - $sqlValues[] = $this->getValue($value); + $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); + $sqlTypes[] = $this->getType($field, $value); } - return array($sqlValues, $sqlTypes); + return array($sqlParams, $sqlTypes); } /** @@ -1085,8 +1085,8 @@ class BasicEntityPersister implements EntityPersister */ public function getCountSQL($criteria = array()) { - $tableName = $this->quoteStrategy->getTableName($this->class, $this->platform); - $tableAlias = $this->getSQLTableAlias($this->class->name); + $tableName = $this->quoteStrategy->getTableName($this->class, $this->platform); + $tableAlias = $this->getSQLTableAlias($this->class->name); $conditionSql = ($criteria instanceof Criteria) ? $this->getSelectConditionCriteriaSQL($criteria) @@ -1101,7 +1101,7 @@ class BasicEntityPersister implements EntityPersister } $sql = 'SELECT COUNT(*) ' - . 'FROM ' . $tableName . ' ' . 't0' + . 'FROM ' . $tableName . ' ' . $tableAlias . (empty($conditionSql) ? '' : ' WHERE ' . $conditionSql); return $sql; diff --git a/lib/Doctrine/ORM/Persisters/JoinedSubclassPersister.php b/lib/Doctrine/ORM/Persisters/JoinedSubclassPersister.php index 559fefddc..128fe4292 100644 --- a/lib/Doctrine/ORM/Persisters/JoinedSubclassPersister.php +++ b/lib/Doctrine/ORM/Persisters/JoinedSubclassPersister.php @@ -298,39 +298,8 @@ class JoinedSubclassPersister extends AbstractEntityInheritancePersister */ public function getSelectSQL($criteria, $assoc = null, $lockMode = null, $limit = null, $offset = null, array $orderBy = null) { - $joinSql = ''; - $identifierColumn = $this->class->getIdentifierColumnNames(); - $baseTableAlias = $this->getSQLTableAlias($this->class->name); - - - // 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 '; - - - foreach ($identifierColumn as $idColumn) { - $conditions[] = $baseTableAlias . '.' . $idColumn . ' = ' . $tableAlias . '.' . $idColumn; - } - - $joinSql .= implode(' AND ', $conditions); - } - - // OUTER JOIN sub tables - foreach ($this->class->subClasses as $subClassName) { - $conditions = array(); - $subClass = $this->em->getClassMetadata($subClassName); - $tableAlias = $this->getSQLTableAlias($subClassName); - $joinSql .= ' LEFT JOIN ' . $this->quoteStrategy->getTableName($subClass, $this->platform) . ' ' . $tableAlias . ' ON '; - - foreach ($identifierColumn as $idColumn) { - $conditions[] = $baseTableAlias . '.' . $idColumn . ' = ' . $tableAlias . '.' . $idColumn; - } - - $joinSql .= implode(' AND ', $conditions); - } + $baseTableAlias = $this->getSQLTableAlias($this->class->name); + $joinSql = $this->getJoinSql($baseTableAlias); if ($assoc != null && $assoc['type'] == ClassMetadata::MANY_TO_MANY) { $joinSql .= $this->getSelectManyToManyJoinSQL($assoc); @@ -387,6 +356,35 @@ class JoinedSubclassPersister extends AbstractEntityInheritancePersister return $this->platform->modifyLimitQuery($query, $limit, $offset) . $lockSql; } + /** + * {@inheritDoc} + */ + public function getCountSQL($criteria = array()) + { + $tableName = $this->quoteStrategy->getTableName($this->class, $this->platform); + $baseTableAlias = $this->getSQLTableAlias($this->class->name); + $joinSql = $this->getJoinSql($baseTableAlias); + + $conditionSql = ($criteria instanceof Criteria) + ? $this->getSelectConditionCriteriaSQL($criteria) + : $this->getSelectConditionSQL($criteria); + + $filterSql = $this->generateFilterConditionSQL($this->em->getClassMetadata($this->class->rootEntityName), $this->getSQLTableAlias($this->class->rootEntityName)); + + if ('' !== $filterSql) { + $conditionSql = $conditionSql + ? $conditionSql . ' AND ' . $filterSql + : $filterSql; + } + + $sql = 'SELECT COUNT(*) ' + . 'FROM ' . $tableName . ' ' . $baseTableAlias + . $joinSql + . (empty($conditionSql) ? '' : ' WHERE ' . $conditionSql); + + return $sql; + } + /** * {@inheritdoc} */ @@ -555,4 +553,45 @@ class JoinedSubclassPersister extends AbstractEntityInheritancePersister $value = $this->fetchVersionValue($this->getVersionedClassMetadata(), $id); $this->class->setFieldValue($entity, $this->class->versionField, $value); } + + /** + * @param string $baseTableAlias + * @return string + */ + private function getJoinSql($baseTableAlias) + { + $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 '; + + + foreach ($identifierColumn as $idColumn) { + $conditions[] = $baseTableAlias . '.' . $idColumn . ' = ' . $tableAlias . '.' . $idColumn; + } + + $joinSql .= implode(' AND ', $conditions); + } + + // OUTER JOIN sub tables + foreach ($this->class->subClasses as $subClassName) { + $conditions = array(); + $subClass = $this->em->getClassMetadata($subClassName); + $tableAlias = $this->getSQLTableAlias($subClassName); + $joinSql .= ' LEFT JOIN ' . $this->quoteStrategy->getTableName($subClass, $this->platform) . ' ' . $tableAlias . ' ON '; + + foreach ($identifierColumn as $idColumn) { + $conditions[] = $baseTableAlias . '.' . $idColumn . ' = ' . $tableAlias . '.' . $idColumn; + } + + $joinSql .= implode(' AND ', $conditions); + } + + return $joinSql; + } } diff --git a/lib/Doctrine/ORM/Persisters/SingleTablePersister.php b/lib/Doctrine/ORM/Persisters/SingleTablePersister.php index e157a90a2..5b60f06a0 100644 --- a/lib/Doctrine/ORM/Persisters/SingleTablePersister.php +++ b/lib/Doctrine/ORM/Persisters/SingleTablePersister.php @@ -43,7 +43,7 @@ class SingleTablePersister extends AbstractEntityInheritancePersister } /** - * {@inheritdoc} + * {@inheritdoc} */ protected function getSelectColumnsSQL() { @@ -80,7 +80,7 @@ class SingleTablePersister extends AbstractEntityInheritancePersister // Foreign key columns foreach ($subClass->associationMappings as $assoc) { - if ( ! $assoc['isOwningSide'] + if ( ! $assoc['isOwningSide'] || ! ($assoc['type'] & ClassMetadata::TO_ONE) || isset($assoc['inherited'])) { continue; diff --git a/tests/Doctrine/Tests/ORM/Functional/SingleTableInheritanceTest.php b/tests/Doctrine/Tests/ORM/Functional/SingleTableInheritanceTest.php index cce203d17..c9dd82a4d 100644 --- a/tests/Doctrine/Tests/ORM/Functional/SingleTableInheritanceTest.php +++ b/tests/Doctrine/Tests/ORM/Functional/SingleTableInheritanceTest.php @@ -370,6 +370,9 @@ class SingleTableInheritanceTest extends \Doctrine\Tests\OrmFunctionalTestCase $contracts = $repository->matching(new Criteria( Criteria::expr()->eq('salesPerson', $this->salesPerson->getId()) )); + + // Load the association because it's wrapped in a lazy collection + $contracts->toArray(); } /**