diff --git a/lib/Doctrine/ORM/Query/Expr/Andx.php b/lib/Doctrine/ORM/Query/Expr/Andx.php index 9f7d8a580..c26055c2a 100644 --- a/lib/Doctrine/ORM/Query/Expr/Andx.php +++ b/lib/Doctrine/ORM/Query/Expr/Andx.php @@ -32,9 +32,9 @@ namespace Doctrine\ORM\Query\Expr; * @author Jonathan Wage * @author Roman Borschel */ -class Andx extends Base +class Andx extends Composite { - protected $_separator = ') AND ('; + protected $_separator = ' AND '; protected $_allowedClasses = array( 'Doctrine\ORM\Query\Expr\Comparison', 'Doctrine\ORM\Query\Expr\Func', diff --git a/lib/Doctrine/ORM/Query/Expr/Base.php b/lib/Doctrine/ORM/Query/Expr/Base.php index 904b69bbe..93bca7507 100644 --- a/lib/Doctrine/ORM/Query/Expr/Base.php +++ b/lib/Doctrine/ORM/Query/Expr/Base.php @@ -39,7 +39,7 @@ abstract class Base protected $_postSeparator = ')'; protected $_allowedClasses = array(); - private $_parts = array(); + protected $_parts = array(); public function __construct($args = array()) { diff --git a/lib/Doctrine/ORM/Query/Expr/Composite.php b/lib/Doctrine/ORM/Query/Expr/Composite.php new file mode 100644 index 000000000..97c15e64b --- /dev/null +++ b/lib/Doctrine/ORM/Query/Expr/Composite.php @@ -0,0 +1,53 @@ +. + */ + +namespace Doctrine\ORM\Query\Expr; + +/** + * Expression class for building DQL and parts + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision$ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + */ +class Composite extends Base +{ + public function __toString() + { + if ($this->count() === 1) { + return (string) $this->_parts[0]; + } + + $components = array(); + + foreach ($this->_parts as $part) { + $components[] = (is_object($part) && $part instanceof self && $part->count() > 1) + ? $this->_preSeparator . ((string) $part) . $this->_postSeparator + : ((string) $part); + } + + return implode($this->_separator, $components); + } +} \ No newline at end of file diff --git a/lib/Doctrine/ORM/Query/Expr/Orx.php b/lib/Doctrine/ORM/Query/Expr/Orx.php index fe695f40d..7eb66535c 100644 --- a/lib/Doctrine/ORM/Query/Expr/Orx.php +++ b/lib/Doctrine/ORM/Query/Expr/Orx.php @@ -32,9 +32,9 @@ namespace Doctrine\ORM\Query\Expr; * @author Jonathan Wage * @author Roman Borschel */ -class Orx extends Base +class Orx extends Composite { - protected $_separator = ') OR ('; + protected $_separator = ' OR '; protected $_allowedClasses = array( 'Doctrine\ORM\Query\Expr\Andx', 'Doctrine\ORM\Query\Expr\Comparison', diff --git a/lib/Doctrine/ORM/QueryBuilder.php b/lib/Doctrine/ORM/QueryBuilder.php index 436522b69..eed9acf9d 100644 --- a/lib/Doctrine/ORM/QueryBuilder.php +++ b/lib/Doctrine/ORM/QueryBuilder.php @@ -629,7 +629,7 @@ class QueryBuilder */ public function where($predicates) { - if ( ! (func_num_args() == 1 && ($predicates instanceof Expr\Andx || $predicates instanceof Expr\Orx))) { + if ( ! (func_num_args() == 1 && $predicates instanceof Expr\Composite)) { $predicates = new Expr\Andx(func_get_args()); } diff --git a/lib/vendor/doctrine-common b/lib/vendor/doctrine-common index 076a03f8f..ba63ae0f0 160000 --- a/lib/vendor/doctrine-common +++ b/lib/vendor/doctrine-common @@ -1 +1 @@ -Subproject commit 076a03f8f40b6e08f0ae2f4ee2678474e64b6f59 +Subproject commit ba63ae0f0b6b62a2a8617f01386698730ff2b713 diff --git a/tests/Doctrine/Tests/ORM/Query/ExprTest.php b/tests/Doctrine/Tests/ORM/Query/ExprTest.php index 786eb1f0c..ccc033b2e 100644 --- a/tests/Doctrine/Tests/ORM/Query/ExprTest.php +++ b/tests/Doctrine/Tests/ORM/Query/ExprTest.php @@ -111,20 +111,20 @@ class ExprTest extends \Doctrine\Tests\OrmTestCase public function testAndExpr() { - $this->assertEquals('(1 = 1) AND (2 = 2)', (string) $this->_expr->andx((string) $this->_expr->eq(1, 1), (string) $this->_expr->eq(2, 2))); + $this->assertEquals('1 = 1 AND 2 = 2', (string) $this->_expr->andx((string) $this->_expr->eq(1, 1), (string) $this->_expr->eq(2, 2))); } public function testIntelligentParenthesisPreventionAndExpr() { $this->assertEquals( - '(1 = 1) AND (2 = 2)', + '1 = 1 AND 2 = 2', (string) $this->_expr->andx($this->_expr->orx($this->_expr->andx($this->_expr->eq(1, 1))), (string) $this->_expr->eq(2, 2)) ); } public function testOrExpr() { - $this->assertEquals('(1 = 1) OR (2 = 2)', (string) $this->_expr->orx((string) $this->_expr->eq(1, 1), (string) $this->_expr->eq(2, 2))); + $this->assertEquals('1 = 1 OR 2 = 2', (string) $this->_expr->orx((string) $this->_expr->eq(1, 1), (string) $this->_expr->eq(2, 2))); } public function testAbsExpr() @@ -296,7 +296,7 @@ class ExprTest extends \Doctrine\Tests\OrmTestCase $orExpr->add($andExpr); $orExpr->add($this->_expr->eq(1, 1)); - $this->assertEquals('((1 = 1) AND (1 < 5)) OR (1 = 1)', (string) $orExpr); + $this->assertEquals('(1 = 1 AND 1 < 5) OR 1 = 1', (string) $orExpr); } public function testOrxExpr() @@ -305,7 +305,7 @@ class ExprTest extends \Doctrine\Tests\OrmTestCase $orExpr->add($this->_expr->eq(1, 1)); $orExpr->add($this->_expr->lt(1, 5)); - $this->assertEquals('(1 = 1) OR (1 < 5)', (string) $orExpr); + $this->assertEquals('1 = 1 OR 1 < 5', (string) $orExpr); } public function testOrderByCountExpr() diff --git a/tests/Doctrine/Tests/ORM/QueryBuilderTest.php b/tests/Doctrine/Tests/ORM/QueryBuilderTest.php index f18516fc4..bc885afa5 100644 --- a/tests/Doctrine/Tests/ORM/QueryBuilderTest.php +++ b/tests/Doctrine/Tests/ORM/QueryBuilderTest.php @@ -162,7 +162,7 @@ class QueryBuilderTest extends \Doctrine\Tests\OrmTestCase ->where('u.id = :uid') ->andWhere('u.id = :uid2'); - $this->assertValidQueryBuilder($qb, 'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE (u.id = :uid) AND (u.id = :uid2)'); + $this->assertValidQueryBuilder($qb, 'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id = :uid AND u.id = :uid2'); } public function testOrWhere() @@ -173,7 +173,7 @@ class QueryBuilderTest extends \Doctrine\Tests\OrmTestCase ->where('u.id = :uid') ->orWhere('u.id = :uid2'); - $this->assertValidQueryBuilder($qb, 'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE (u.id = :uid) OR (u.id = :uid2)'); + $this->assertValidQueryBuilder($qb, 'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id = :uid OR u.id = :uid2'); } public function testComplexAndWhereOrWhereNesting() @@ -187,7 +187,7 @@ class QueryBuilderTest extends \Doctrine\Tests\OrmTestCase ->orWhere('u.name = :name1', 'u.name = :name2') ->andWhere('u.name <> :noname'); - $this->assertValidQueryBuilder($qb, 'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE ((((u.id = :uid) OR (u.id = :uid2)) AND (u.id = :uid3)) OR (u.name = :name1) OR (u.name = :name2)) AND (u.name <> :noname)'); + $this->assertValidQueryBuilder($qb, 'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE (((u.id = :uid OR u.id = :uid2) AND u.id = :uid3) OR u.name = :name1 OR u.name = :name2) AND u.name <> :noname'); } public function testAndWhereIn() @@ -198,7 +198,7 @@ class QueryBuilderTest extends \Doctrine\Tests\OrmTestCase ->where('u.id = :uid') ->andWhere($qb->expr()->in('u.id', array(1, 2, 3))); - $this->assertValidQueryBuilder($qb, 'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE (u.id = :uid) AND (u.id IN(1, 2, 3))'); + $this->assertValidQueryBuilder($qb, 'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id = :uid AND u.id IN(1, 2, 3)'); } public function testOrWhereIn() @@ -209,7 +209,7 @@ class QueryBuilderTest extends \Doctrine\Tests\OrmTestCase ->where('u.id = :uid') ->orWhere($qb->expr()->in('u.id', array(1, 2, 3))); - $this->assertValidQueryBuilder($qb, 'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE (u.id = :uid) OR (u.id IN(1, 2, 3))'); + $this->assertValidQueryBuilder($qb, 'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id = :uid OR u.id IN(1, 2, 3)'); } public function testAndWhereNotIn() @@ -220,7 +220,7 @@ class QueryBuilderTest extends \Doctrine\Tests\OrmTestCase ->where('u.id = :uid') ->andWhere($qb->expr()->notIn('u.id', array(1, 2, 3))); - $this->assertValidQueryBuilder($qb, 'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE (u.id = :uid) AND (u.id NOT IN(1, 2, 3))'); + $this->assertValidQueryBuilder($qb, 'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id = :uid AND u.id NOT IN(1, 2, 3)'); } public function testOrWhereNotIn() @@ -231,7 +231,7 @@ class QueryBuilderTest extends \Doctrine\Tests\OrmTestCase ->where('u.id = :uid') ->orWhere($qb->expr()->notIn('u.id', array(1, 2, 3))); - $this->assertValidQueryBuilder($qb, 'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE (u.id = :uid) OR (u.id NOT IN(1, 2, 3))'); + $this->assertValidQueryBuilder($qb, 'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id = :uid OR u.id NOT IN(1, 2, 3)'); } public function testGroupBy() @@ -265,7 +265,7 @@ class QueryBuilderTest extends \Doctrine\Tests\OrmTestCase ->having('COUNT(u.id) > 1') ->andHaving('COUNT(u.id) < 1'); - $this->assertValidQueryBuilder($qb, 'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u GROUP BY u.id HAVING (COUNT(u.id) > 1) AND (COUNT(u.id) < 1)'); + $this->assertValidQueryBuilder($qb, 'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u GROUP BY u.id HAVING COUNT(u.id) > 1 AND COUNT(u.id) < 1'); } public function testOrHaving() @@ -278,7 +278,7 @@ class QueryBuilderTest extends \Doctrine\Tests\OrmTestCase ->andHaving('COUNT(u.id) < 1') ->orHaving('COUNT(u.id) > 1'); - $this->assertValidQueryBuilder($qb, 'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u GROUP BY u.id HAVING ((COUNT(u.id) > 1) AND (COUNT(u.id) < 1)) OR (COUNT(u.id) > 1)'); + $this->assertValidQueryBuilder($qb, 'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u GROUP BY u.id HAVING (COUNT(u.id) > 1 AND COUNT(u.id) < 1) OR COUNT(u.id) > 1'); } public function testOrderBy() @@ -375,7 +375,7 @@ class QueryBuilderTest extends \Doctrine\Tests\OrmTestCase ->from('Doctrine\Tests\Models\CMS\CmsUser', 'u') ->where('u.id = :uid', 'u.id = :uid2'); - $this->assertValidQueryBuilder($qb, 'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE (u.id = :uid) AND (u.id = :uid2)'); + $this->assertValidQueryBuilder($qb, 'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id = :uid AND u.id = :uid2'); } public function testMultipleAndWhere() @@ -385,7 +385,7 @@ class QueryBuilderTest extends \Doctrine\Tests\OrmTestCase ->from('Doctrine\Tests\Models\CMS\CmsUser', 'u') ->andWhere('u.id = :uid', 'u.id = :uid2'); - $this->assertValidQueryBuilder($qb, 'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE (u.id = :uid) AND (u.id = :uid2)'); + $this->assertValidQueryBuilder($qb, 'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id = :uid AND u.id = :uid2'); } public function testMultipleOrWhere() @@ -395,7 +395,7 @@ class QueryBuilderTest extends \Doctrine\Tests\OrmTestCase ->from('Doctrine\Tests\Models\CMS\CmsUser', 'u') ->orWhere('u.id = :uid', $qb->expr()->eq('u.id', ':uid2')); - $this->assertValidQueryBuilder($qb, 'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE (u.id = :uid) OR (u.id = :uid2)'); + $this->assertValidQueryBuilder($qb, 'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id = :uid OR u.id = :uid2'); } public function testComplexWhere() @@ -409,7 +409,7 @@ class QueryBuilderTest extends \Doctrine\Tests\OrmTestCase ->from('Doctrine\Tests\Models\CMS\CmsUser', 'u') ->where($orExpr); - $this->assertValidQueryBuilder($qb, 'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE (u.id = :uid3) OR (u.id IN(1))'); + $this->assertValidQueryBuilder($qb, 'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id = :uid3 OR u.id IN(1)'); } public function testWhereInWithStringLiterals() @@ -453,7 +453,7 @@ class QueryBuilderTest extends \Doctrine\Tests\OrmTestCase ->from('Doctrine\Tests\Models\CMS\CmsUser', 'u') ->where($orExpr); - $this->assertValidQueryBuilder($qb, 'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE (u.id = :uid3) OR (NOT(u.id IN(1)))'); + $this->assertValidQueryBuilder($qb, 'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id = :uid3 OR NOT(u.id IN(1))'); } public function testSomeAllAny() @@ -490,7 +490,7 @@ class QueryBuilderTest extends \Doctrine\Tests\OrmTestCase $q2 = $qb->getQuery(); - $this->assertEquals('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE (u.name = :name) AND (u.id = :id)', $q2->getDql()); + $this->assertEquals('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.name = :name AND u.id = :id', $q2->getDql()); $this->assertTrue($q1 !== $q2); // two different, independent queries $this->assertEquals(2, count($q2->getParameters())); $this->assertEquals(1, count($q1->getParameters())); // $q1 unaffected