added custom join condition support for DQL
This commit is contained in:
parent
a6cf587ce1
commit
b18b38da25
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
57
tests/Query/HavingTestCase.php
Normal file
57
tests/Query/HavingTestCase.php
Normal file
@ -0,0 +1,57 @@
|
||||
<?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;
|
||||
}
|
||||
*/
|
||||
}
|
67
tests/Query/JoinConditionTestCase.php
Normal file
67
tests/Query/JoinConditionTestCase.php
Normal file
@ -0,0 +1,67 @@
|
||||
<?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))");
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user