1
0
mirror of synced 2024-12-13 06:46:03 +03:00

[2.0][DDC-308] Implemented SIZE() function support to many2many relations

This commit is contained in:
guilhermeblanco 2010-02-10 02:31:55 +00:00
parent d642fb9642
commit 30f9403790
2 changed files with 36 additions and 10 deletions

View File

@ -44,10 +44,12 @@ class SizeFunction extends FunctionNode
public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker) public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker)
{ {
$dqlAlias = $this->collectionPathExpression->identificationVariable; $dqlAlias = $this->collectionPathExpression->identificationVariable;
$qComp = $sqlWalker->getQueryComponent($dqlAlias);
$parts = $this->collectionPathExpression->parts; $parts = $this->collectionPathExpression->parts;
$assocField = array_pop($parts);
$assoc = $qComp['metadata']->associationMappings[$parts[0]];
$qComp = $sqlWalker->getQueryComponent(implode('.', array_merge((array) $dqlAlias, $parts)));
$assoc = $qComp['metadata']->associationMappings[$assocField];
$sql = '';
if ($assoc->isOneToMany()) { if ($assoc->isOneToMany()) {
$targetClass = $sqlWalker->getEntityManager()->getClassMetadata($assoc->targetEntityName); $targetClass = $sqlWalker->getEntityManager()->getClassMetadata($assoc->targetEntityName);
@ -56,17 +58,33 @@ class SizeFunction extends FunctionNode
$targetTableAlias = $sqlWalker->getSqlTableAlias($targetClass->primaryTable['name']); $targetTableAlias = $sqlWalker->getSqlTableAlias($targetClass->primaryTable['name']);
$sourceTableAlias = $sqlWalker->getSqlTableAlias($qComp['metadata']->primaryTable['name'], $dqlAlias); $sourceTableAlias = $sqlWalker->getSqlTableAlias($qComp['metadata']->primaryTable['name'], $dqlAlias);
$sql = "(SELECT COUNT($targetTableAlias."
. implode(", $targetTableAlias.", $targetAssoc->targetToSourceKeyColumns)
. ') FROM ' . $targetClass->primaryTable['name'] . ' ' . $targetTableAlias;
$whereSql = ''; $whereSql = '';
foreach ($targetAssoc->targetToSourceKeyColumns as $targetKeyColumn => $sourceKeyColumn) { foreach ($targetAssoc->targetToSourceKeyColumns as $targetKeyColumn => $sourceKeyColumn) {
if ($whereSql == '') $whereSql = ' WHERE '; else $whereSql .= ' AND '; $whereSql .= (($whereSql == '') ? ' WHERE ' : ' AND ')
$whereSql .= $targetTableAlias . '.' . $sourceKeyColumn . ' = ' . $sourceTableAlias . '.' . $targetKeyColumn; . $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; return $sql;

View File

@ -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() public function testEmptyCollectionComparisonExpression()
{ {
$this->assertSqlGeneration( $this->assertSqlGeneration(