Commit b18b38da authored by zYne's avatar zYne

added custom join condition support for DQL

parent a6cf587c
...@@ -79,6 +79,11 @@ class Doctrine_Hook ...@@ -79,6 +79,11 @@ class Doctrine_Hook
$this->query = $query; $this->query = $query;
} }
} }
/**
* getQuery
*
* @return Doctrine_Query returns the query object associated with this hook
*/
public function getQuery() public function getQuery()
{ {
return $this->query; return $this->query;
......
...@@ -1110,6 +1110,16 @@ class Doctrine_Query extends Doctrine_Hydrate implements Countable { ...@@ -1110,6 +1110,16 @@ class Doctrine_Query extends Doctrine_Hydrate implements Countable {
*/ */
final public function load($path, $loadFields = true) 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); $tmp = explode(' ',$path);
$componentAlias = (count($tmp) > 1) ? end($tmp) : false; $componentAlias = (count($tmp) > 1) ? end($tmp) : false;
...@@ -1217,12 +1227,14 @@ class Doctrine_Query extends Doctrine_Hydrate implements Countable { ...@@ -1217,12 +1227,14 @@ class Doctrine_Query extends Doctrine_Hydrate implements Countable {
$this->parts["join"][$tname][$tname2] = $join . $aliasString . ' ON ' . $tname2 . '.' $this->parts["join"][$tname][$tname2] = $join . $aliasString . ' ON ' . $tname2 . '.'
. $fk->getTable()->getIdentifier() . ' = ' . $fk->getTable()->getIdentifier() . ' = '
. $assocTableName . '.' . $fk->getForeign(); . $assocTableName . '.' . $fk->getForeign()
. $joinCondition;
} else { } else {
$this->parts["join"][$tname][$tname2] = $join . $aliasString $this->parts["join"][$tname][$tname2] = $join . $aliasString
. ' ON ' . $tname . '.' . ' ON ' . $tname . '.'
. $fk->getLocal() . ' = ' . $tname2 . '.' . $fk->getForeign(); . $fk->getLocal() . ' = ' . $tname2 . '.' . $fk->getForeign()
. $joinCondition;
} }
......
...@@ -42,6 +42,7 @@ class Doctrine_Query_From extends Doctrine_Query_Part ...@@ -42,6 +42,7 @@ class Doctrine_Query_From extends Doctrine_Query_Part
*/ */
final public function parse($str) final public function parse($str)
{ {
$str = trim($str); $str = trim($str);
$parts = Doctrine_Query::bracketExplode($str, 'JOIN'); $parts = Doctrine_Query::bracketExplode($str, 'JOIN');
...@@ -77,6 +78,7 @@ class Doctrine_Query_From extends Doctrine_Query_Part ...@@ -77,6 +78,7 @@ class Doctrine_Query_From extends Doctrine_Query_Part
if ($operator) { if ($operator) {
$reference = array_shift($e) . $operator . implode('.', $e); $reference = array_shift($e) . $operator . implode('.', $e);
} }
$table = $this->query->load($reference); $table = $this->query->load($reference);
} }
......
<?php
/*
* $Id$
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information, see
* <http://www.phpdoctrine.com>.
*/
/**
* Doctrine_Query_Having_TestCase
*
* @package Doctrine
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @author Konsta Vesterinen <kvesteri@cc.hut.fi>
* @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;
}
*/
}
<?php
/*
* $Id$
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information, see
* <http://www.phpdoctrine.com>.
*/
/**
* Doctrine_Query_JoinCondition_TestCase
*
* @package Doctrine
* @author Konsta Vesterinen <kvesteri@cc.hut.fi>
* @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))");
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment