diff --git a/lib/Doctrine/Hook.php b/lib/Doctrine/Hook.php index 77af877d4..e25e2f83b 100644 --- a/lib/Doctrine/Hook.php +++ b/lib/Doctrine/Hook.php @@ -79,6 +79,11 @@ class Doctrine_Hook $this->query = $query; } } + /** + * getQuery + * + * @return Doctrine_Query returns the query object associated with this hook + */ public function getQuery() { return $this->query; diff --git a/lib/Doctrine/Query.php b/lib/Doctrine/Query.php index 2092d0690..305b35b03 100644 --- a/lib/Doctrine/Query.php +++ b/lib/Doctrine/Query.php @@ -1110,6 +1110,16 @@ class Doctrine_Query extends Doctrine_Hydrate implements Countable { */ final public function load($path, $loadFields = true) { + + // parse custom join conditions + $e = explode(' ON ', $path); + + $joinCondition = ''; + if(count($e) > 1) { + $joinCondition = ' AND ' . $e[1]; + $path = $e[0]; + } + $tmp = explode(' ',$path); $componentAlias = (count($tmp) > 1) ? end($tmp) : false; @@ -1217,12 +1227,14 @@ class Doctrine_Query extends Doctrine_Hydrate implements Countable { $this->parts["join"][$tname][$tname2] = $join . $aliasString . ' ON ' . $tname2 . '.' . $fk->getTable()->getIdentifier() . ' = ' - . $assocTableName . '.' . $fk->getForeign(); + . $assocTableName . '.' . $fk->getForeign() + . $joinCondition; } else { $this->parts["join"][$tname][$tname2] = $join . $aliasString . ' ON ' . $tname . '.' - . $fk->getLocal() . ' = ' . $tname2 . '.' . $fk->getForeign(); + . $fk->getLocal() . ' = ' . $tname2 . '.' . $fk->getForeign() + . $joinCondition; } diff --git a/lib/Doctrine/Query/From.php b/lib/Doctrine/Query/From.php index 65153c6ab..559e654de 100644 --- a/lib/Doctrine/Query/From.php +++ b/lib/Doctrine/Query/From.php @@ -42,6 +42,7 @@ class Doctrine_Query_From extends Doctrine_Query_Part */ final public function parse($str) { + $str = trim($str); $parts = Doctrine_Query::bracketExplode($str, 'JOIN'); @@ -77,6 +78,7 @@ class Doctrine_Query_From extends Doctrine_Query_Part if ($operator) { $reference = array_shift($e) . $operator . implode('.', $e); } + $table = $this->query->load($reference); } diff --git a/tests/Query/HavingTestCase.php b/tests/Query/HavingTestCase.php new file mode 100644 index 000000000..bfd12179c --- /dev/null +++ b/tests/Query/HavingTestCase.php @@ -0,0 +1,57 @@ +. + */ + +/** + * Doctrine_Query_Having_TestCase + * + * @package Doctrine + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @author Konsta Vesterinen + * @version $Revision$ + * @category Object Relational Mapping + * @link www.phpdoctrine.com + * @since 1.0 + */ +class Doctrine_Query_Having_TestCase extends Doctrine_UnitTestCase { + public function testAggregateFunctionsInHavingReturnValidSql() { + $q = new Doctrine_Query(); + + $q->parseQuery('SELECT u.name FROM User u LEFT JOIN u.Phonenumber p HAVING COUNT(p.id) > 2'); + + $this->assertEqual($q->getQuery(), 'SELECT e.id AS e__id, e.name AS e__name FROM entity e LEFT JOIN phonenumber p ON e.id = p.entity_id WHERE (e.type = 0) HAVING COUNT(p.id) > 2'); + } + public function testAggregateFunctionsInHavingReturnValidSql2() { + $q = new Doctrine_Query(); + + $q->parseQuery("SELECT u.name FROM User u LEFT JOIN u.Phonenumber p HAVING MAX(u.name) = 'zYne'"); + + $this->assertEqual($q->getQuery(), "SELECT e.id AS e__id, e.name AS e__name FROM entity e LEFT JOIN phonenumber p ON e.id = p.entity_id WHERE (e.type = 0) HAVING MAX(e.name) = 'zYne'"); + } + /** + public function testAggregateFunctionsInHavingSupportMultipleParameters() { + $q = new Doctrine_Query(); + + $q->parseQuery("SELECT CONCAT(u.name, u.loginname) name FROM User u LEFT JOIN u.Phonenumber p HAVING name = 'xx'"); + + print $q; + } + */ +} diff --git a/tests/Query/JoinConditionTestCase.php b/tests/Query/JoinConditionTestCase.php new file mode 100644 index 000000000..c9243ede9 --- /dev/null +++ b/tests/Query/JoinConditionTestCase.php @@ -0,0 +1,67 @@ +. + */ + +/** + * Doctrine_Query_JoinCondition_TestCase + * + * @package Doctrine + * @author Konsta Vesterinen + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @category Object Relational Mapping + * @link www.phpdoctrine.com + * @since 1.0 + * @version $Revision$ + */ +class Doctrine_Query_JoinCondition_TestCase extends Doctrine_UnitTestCase +{ + public function testJoinConditionsAreSupportedForOneToManyLeftJoins() + { + $q = new Doctrine_Query(); + + $q->parseQuery("SELECT u.name, p.id FROM User u LEFT JOIN u.Phonenumber p ON p.phonenumber = '123 123'"); + + $this->assertEqual($q->getQuery(), "SELECT e.id AS e__id, e.name AS e__name, p.id AS p__id FROM entity e LEFT JOIN phonenumber p ON e.id = p.entity_id AND p.phonenumber = '123 123' WHERE (e.type = 0)"); + } + public function testJoinConditionsAreSupportedForOneToManyInnerJoins() + { + $q = new Doctrine_Query(); + + $q->parseQuery("SELECT u.name, p.id FROM User u INNER JOIN u.Phonenumber p ON p.phonenumber = '123 123'"); + + $this->assertEqual($q->getQuery(), "SELECT e.id AS e__id, e.name AS e__name, p.id AS p__id FROM entity e INNER JOIN phonenumber p ON e.id = p.entity_id AND p.phonenumber = '123 123' WHERE (e.type = 0)"); + } + public function testJoinConditionsAreSupportedForManyToManyLeftJoins() + { + $q = new Doctrine_Query(); + + $q->parseQuery("SELECT u.name, g.id FROM User u LEFT JOIN u.Group g ON g.id > 2"); + + $this->assertEqual($q->getQuery(), "SELECT e.id AS e__id, e.name AS e__name, e2.id AS e2__id FROM entity e LEFT JOIN groupuser ON e.id = groupuser.user_id LEFT JOIN entity e2 ON e2.id = groupuser.group_id AND g.id > 2 WHERE (e.type = 0 AND (e2.type = 1 OR e2.type IS NULL))"); + } + public function testJoinConditionsAreSupportedForManyToManyInnerJoins() + { + $q = new Doctrine_Query(); + + $q->parseQuery("SELECT u.name, g.id FROM User u INNER JOIN u.Group g ON g.id > 2"); + + $this->assertEqual($q->getQuery(), "SELECT e.id AS e__id, e.name AS e__name, e2.id AS e2__id FROM entity e INNER JOIN groupuser ON e.id = groupuser.user_id INNER JOIN entity e2 ON e2.id = groupuser.group_id AND g.id > 2 WHERE (e.type = 0 AND (e2.type = 1 OR e2.type IS NULL))"); + } +}