1
0
Fork 0
mirror of synced 2025-04-01 12:26:11 +03:00

[DDC-1067][DDC-1145] Fixed bug with multiple froms and inclusion of joins. Added support for index by in QueryBuilder. This break BC only if users are using base support (->add).

This commit is contained in:
Guilherme Blanco 2011-05-11 21:40:27 -03:00
parent 54a0109d5d
commit 905e05cd36
3 changed files with 108 additions and 21 deletions

View file

@ -45,20 +45,23 @@ class Join
private $_alias;
private $_conditionType;
private $_condition;
private $_indexBy;
public function __construct($joinType, $join, $alias = null, $conditionType = null, $condition = null)
public function __construct($joinType, $join, $alias = null, $conditionType = null, $condition = null, $indexBy = null)
{
$this->_joinType = $joinType;
$this->_join = $join;
$this->_alias = $alias;
$this->_joinType = $joinType;
$this->_join = $join;
$this->_alias = $alias;
$this->_conditionType = $conditionType;
$this->_condition = $condition;
$this->_condition = $condition;
$this->_indexBy = $indexBy;
}
public function __toString()
{
return strtoupper($this->_joinType) . ' JOIN ' . $this->_join
. ($this->_alias ? ' ' . $this->_alias : '')
. ($this->_condition ? ' ' . strtoupper($this->_conditionType) . ' ' . $this->_condition : '');
. ($this->_condition ? ' ' . strtoupper($this->_conditionType) . ' ' . $this->_condition : '')
. ($this->_indexBy ? ' INDEX BY ' . $this->_indexBy : '');
}
}

View file

@ -282,8 +282,13 @@ class QueryBuilder
*/
public function setParameters(array $params, array $types = array())
{
$this->_paramTypes = $types;
$this->_params = $params;
foreach ($params as $key => $value) {
if (isset($types[$key])) {
$this->setParameter($key, $value, $types[$key]);
} else {
$this->setParameter($key, $value);
}
}
return $this;
}
@ -370,7 +375,13 @@ class QueryBuilder
$isMultiple = is_array($this->_dqlParts[$dqlPartName]);
if ($append && $isMultiple) {
$this->_dqlParts[$dqlPartName][] = $dqlPart;
if (is_array($dqlPart)) {
$key = key($dqlPart);
$this->_dqlParts[$dqlPartName][$key][] = $dqlPart[$key];
} else {
$this->_dqlParts[$dqlPartName][] = $dqlPart;
}
} else {
$this->_dqlParts[$dqlPartName] = ($isMultiple) ? array($dqlPart) : $dqlPart;
}
@ -523,11 +534,12 @@ class QueryBuilder
* @param string $alias The alias of the join
* @param string $conditionType The condition type constant. Either ON or WITH.
* @param string $condition The condition for the join
* @param string $indexBy The index for the join
* @return QueryBuilder This QueryBuilder instance.
*/
public function join($join, $alias, $conditionType = null, $condition = null)
public function join($join, $alias, $conditionType = null, $condition = null, $indexBy = null)
{
return $this->innerJoin($join, $alias, $conditionType, $condition);
return $this->innerJoin($join, $alias, $conditionType, $condition, $indexBy);
}
/**
@ -547,12 +559,15 @@ class QueryBuilder
* @param string $alias The alias of the join
* @param string $conditionType The condition type constant. Either ON or WITH.
* @param string $condition The condition for the join
* @param string $indexBy The index for the join
* @return QueryBuilder This QueryBuilder instance.
*/
public function innerJoin($join, $alias, $conditionType = null, $condition = null)
public function innerJoin($join, $alias, $conditionType = null, $condition = null, $indexBy = null)
{
return $this->add('join', new Expr\Join(
Expr\Join::INNER_JOIN, $join, $alias, $conditionType, $condition
$rootAlias = substr($join, 0, strpos($join, '.'));
return $this->add('join', array(
$rootAlias => new Expr\Join(Expr\Join::INNER_JOIN, $join, $alias, $conditionType, $condition, $indexBy)
), true);
}
@ -574,12 +589,15 @@ class QueryBuilder
* @param string $alias The alias of the join
* @param string $conditionType The condition type constant. Either ON or WITH.
* @param string $condition The condition for the join
* @param string $indexBy The index for the join
* @return QueryBuilder This QueryBuilder instance.
*/
public function leftJoin($join, $alias, $conditionType = null, $condition = null)
public function leftJoin($join, $alias, $conditionType = null, $condition = null, $indexBy = null)
{
return $this->add('join', new Expr\Join(
Expr\Join::LEFT_JOIN, $join, $alias, $conditionType, $condition
$rootAlias = substr($join, 0, strpos($join, '.'));
return $this->add('join', array(
$rootAlias => new Expr\Join(Expr\Join::LEFT_JOIN, $join, $alias, $conditionType, $condition, $indexBy)
), true);
}
@ -865,14 +883,36 @@ class QueryBuilder
private function _getDQLForSelect()
{
return 'SELECT'
. $this->_getReducedDQLQueryPart('select', array('pre' => ' ', 'separator' => ', '))
. $this->_getReducedDQLQueryPart('from', array('pre' => ' FROM ', 'separator' => ', '))
. $this->_getReducedDQLQueryPart('join', array('pre' => ' ', 'separator' => ' '))
$dql = 'SELECT' . $this->_getReducedDQLQueryPart('select', array('pre' => ' ', 'separator' => ', '));
$fromParts = $this->getDQLPart('from');
$joinParts = $this->getDQLPart('join');
$fromClauses = array();
// Loop through all FROM clauses
if ( ! empty($fromParts)) {
$dql .= ' FROM ';
foreach ($fromParts as $from) {
$fromClause = (string) $from;
if (isset($joinParts[$from->getAlias()])) {
foreach ($joinParts[$from->getAlias()] as $join) {
$fromClause .= ' ' . ((string) $join);
}
}
$fromClauses[] = $fromClause;
}
}
$dql .= implode(', ', $fromClauses)
. $this->_getReducedDQLQueryPart('where', array('pre' => ' WHERE '))
. $this->_getReducedDQLQueryPart('groupBy', array('pre' => ' GROUP BY ', 'separator' => ', '))
. $this->_getReducedDQLQueryPart('having', array('pre' => ' HAVING '))
. $this->_getReducedDQLQueryPart('orderBy', array('pre' => ' ORDER BY ', 'separator' => ', '));
return $dql;
}
private function _getReducedDQLQueryPart($queryPartName, $options = array())

View file

@ -144,6 +144,50 @@ class QueryBuilderTest extends \Doctrine\Tests\OrmTestCase
$this->assertValidQueryBuilder($qb, 'SELECT u, a FROM Doctrine\Tests\Models\CMS\CmsUser u LEFT JOIN u.articles a');
}
public function testLeftJoinWithIndexBy()
{
$qb = $this->_em->createQueryBuilder()
->select('u', 'a')
->from('Doctrine\Tests\Models\CMS\CmsUser', 'u')
->leftJoin('u.articles', 'a', null, null, 'a.name');
$this->assertValidQueryBuilder($qb, 'SELECT u, a FROM Doctrine\Tests\Models\CMS\CmsUser u LEFT JOIN u.articles a INDEX BY a.name');
}
public function testMultipleFrom()
{
$qb = $this->_em->createQueryBuilder()
->select('u', 'g')
->from('Doctrine\Tests\Models\CMS\CmsUser', 'u')
->from('Doctrine\Tests\Models\CMS\CmsGroup', 'g');
$this->assertValidQueryBuilder($qb, 'SELECT u, g FROM Doctrine\Tests\Models\CMS\CmsUser u, Doctrine\Tests\Models\CMS\CmsGroup g');
}
public function testMultipleFromWithJoin()
{
$qb = $this->_em->createQueryBuilder()
->select('u', 'g')
->from('Doctrine\Tests\Models\CMS\CmsUser', 'u')
->from('Doctrine\Tests\Models\CMS\CmsGroup', 'g')
->innerJoin('u.articles', 'a', 'ON', 'u.id = a.author_id');
$this->assertValidQueryBuilder($qb, 'SELECT u, g FROM Doctrine\Tests\Models\CMS\CmsUser u INNER JOIN u.articles a ON u.id = a.author_id, Doctrine\Tests\Models\CMS\CmsGroup g');
}
public function testMultipleFromWithMultipleJoin()
{
$qb = $this->_em->createQueryBuilder()
->select('u', 'g')
->from('Doctrine\Tests\Models\CMS\CmsUser', 'u')
->from('Doctrine\Tests\Models\CMS\CmsArticle', 'a')
->innerJoin('u.groups', 'g')
->leftJoin('u.address', 'ad')
->innerJoin('a.comments', 'c');
$this->assertValidQueryBuilder($qb, 'SELECT u, g FROM Doctrine\Tests\Models\CMS\CmsUser u INNER JOIN u.groups g LEFT JOIN u.address ad, Doctrine\Tests\Models\CMS\CmsArticle a INNER JOIN a.comments c');
}
public function testWhere()
{
$qb = $this->_em->createQueryBuilder()