From 30f9403790ce01c54a48bacf5c49351aa0f4218b Mon Sep 17 00:00:00 2001 From: guilhermeblanco Date: Wed, 10 Feb 2010 02:31:55 +0000 Subject: [PATCH] [2.0][DDC-308] Implemented SIZE() function support to many2many relations --- .../ORM/Query/AST/Functions/SizeFunction.php | 38 ++++++++++++++----- .../ORM/Query/SelectSqlGenerationTest.php | 8 ++++ 2 files changed, 36 insertions(+), 10 deletions(-) diff --git a/lib/Doctrine/ORM/Query/AST/Functions/SizeFunction.php b/lib/Doctrine/ORM/Query/AST/Functions/SizeFunction.php index c6f069692..4e4b2cca4 100644 --- a/lib/Doctrine/ORM/Query/AST/Functions/SizeFunction.php +++ b/lib/Doctrine/ORM/Query/AST/Functions/SizeFunction.php @@ -44,10 +44,12 @@ class SizeFunction extends FunctionNode public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker) { $dqlAlias = $this->collectionPathExpression->identificationVariable; - $qComp = $sqlWalker->getQueryComponent($dqlAlias); $parts = $this->collectionPathExpression->parts; - - $assoc = $qComp['metadata']->associationMappings[$parts[0]]; + $assocField = array_pop($parts); + + $qComp = $sqlWalker->getQueryComponent(implode('.', array_merge((array) $dqlAlias, $parts))); + $assoc = $qComp['metadata']->associationMappings[$assocField]; + $sql = ''; if ($assoc->isOneToMany()) { $targetClass = $sqlWalker->getEntityManager()->getClassMetadata($assoc->targetEntityName); @@ -56,17 +58,33 @@ class SizeFunction extends FunctionNode $targetTableAlias = $sqlWalker->getSqlTableAlias($targetClass->primaryTable['name']); $sourceTableAlias = $sqlWalker->getSqlTableAlias($qComp['metadata']->primaryTable['name'], $dqlAlias); - $sql = "(SELECT COUNT($targetTableAlias." - . implode(", $targetTableAlias.", $targetAssoc->targetToSourceKeyColumns) - . ') FROM ' . $targetClass->primaryTable['name'] . ' ' . $targetTableAlias; - $whereSql = ''; + foreach ($targetAssoc->targetToSourceKeyColumns as $targetKeyColumn => $sourceKeyColumn) { - if ($whereSql == '') $whereSql = ' WHERE '; else $whereSql .= ' AND '; - $whereSql .= $targetTableAlias . '.' . $sourceKeyColumn . ' = ' . $sourceTableAlias . '.' . $targetKeyColumn; + $whereSql .= (($whereSql == '') ? ' WHERE ' : ' AND ') + . $targetTableAlias . '.' . $sourceKeyColumn . ' = ' + . $sourceTableAlias . '.' . $targetKeyColumn; } - $sql .= $whereSql . ')'; + $sql = '(SELECT COUNT(' + . "$targetTableAlias." . implode(", $targetTableAlias.", $targetAssoc->targetToSourceKeyColumns) + . ') FROM ' . $targetClass->primaryTable['name'] . ' ' . $targetTableAlias . $whereSql . ')'; + } else if ($assoc->isManyToMany()) { + // TODO + $targetTableAlias = $sqlWalker->getSqlTableAlias($assoc->joinTable['name']); + $sourceTableAlias = $sqlWalker->getSqlTableAlias($qComp['metadata']->primaryTable['name'], $dqlAlias); + + $whereSql = ''; + + foreach ($assoc->relationToSourceKeyColumns as $targetKeyColumn => $sourceKeyColumn) { + $whereSql .= (($whereSql == '') ? ' WHERE ' : ' AND ') + . $targetTableAlias . '.' . $targetKeyColumn . ' = ' + . $sourceTableAlias . '.' . $sourceKeyColumn; + } + + $sql = '(SELECT COUNT(' + . "$targetTableAlias." . implode(", $targetTableAlias.", $assoc->joinTableColumns) + . ') FROM ' . $assoc->joinTable['name'] . ' ' . $targetTableAlias . $whereSql . ')'; } return $sql; diff --git a/tests/Doctrine/Tests/ORM/Query/SelectSqlGenerationTest.php b/tests/Doctrine/Tests/ORM/Query/SelectSqlGenerationTest.php index 3fbb31ec6..37857e64d 100644 --- a/tests/Doctrine/Tests/ORM/Query/SelectSqlGenerationTest.php +++ b/tests/Doctrine/Tests/ORM/Query/SelectSqlGenerationTest.php @@ -395,6 +395,14 @@ class SelectSqlGenerationTest extends \Doctrine\Tests\OrmTestCase ); } + public function testSizeFunctionSupportsManyToMany() + { + $this->assertSqlGeneration( + "SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE SIZE(u.groups) > 1", + "SELECT c0_.id AS id0, c0_.status AS status1, c0_.username AS username2, c0_.name AS name3 FROM cms_users c0_ WHERE (SELECT COUNT(c1_.user_id, c1_.group_id) FROM cms_users_groups c1_ WHERE c1_.user_id = c0_.id) > 1" + ); + } + public function testEmptyCollectionComparisonExpression() { $this->assertSqlGeneration(