DQL Parser refactorings and enhancements. Finished basic drat of Join support.
This commit is contained in:
parent
d8b76a54d0
commit
efca79412d
@ -23,7 +23,7 @@
|
||||
|
||||
/**
|
||||
* Base class for all Entities (objects with persistent state in a RDBMS that are
|
||||
* managed by Doctrine). Kind of a Layer Suptertype.
|
||||
* managed by Doctrine). Kind of a Layer Supertype.
|
||||
*
|
||||
* NOTE: Methods that are intended for internal use only but must be public
|
||||
* are marked INTERNAL: and begin with an underscore "_" to indicate that they
|
||||
|
@ -123,7 +123,7 @@ abstract class Doctrine_Query_AbstractResult
|
||||
*/
|
||||
public function getQueryComponent($componentAlias)
|
||||
{
|
||||
if ( ! isset($this->_queryComponents[$componentAlias])) {
|
||||
if ( ! array_key_exists($componentAlias, $this->_queryComponents)) {
|
||||
throw new Doctrine_Query_Exception('Unknown query component ' . $componentAlias);
|
||||
}
|
||||
|
||||
|
@ -173,7 +173,9 @@ class Doctrine_Query_Parser
|
||||
|
||||
|
||||
/**
|
||||
* @todo [TODO] Document these!
|
||||
* Moves the parser scanner to next token
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function next()
|
||||
{
|
||||
|
@ -66,30 +66,20 @@ class Doctrine_Query_Production_BetweenExpression extends Doctrine_Query_Product
|
||||
. $this->_fromExpression->buildSql() . ' AND ' . $this->_toExpression->buildSql();
|
||||
}
|
||||
|
||||
/**
|
||||
* Visitor support.
|
||||
*
|
||||
* @param object $visitor
|
||||
*/
|
||||
public function accept($visitor)
|
||||
{
|
||||
$this->_fromExpression->accept($visitor);
|
||||
$this->_toExpression->accept($visitor);
|
||||
$visitor->visitBetweenExpression($this);
|
||||
}
|
||||
|
||||
/* Getters */
|
||||
|
||||
public function isNot()
|
||||
{
|
||||
return $this->_not;
|
||||
}
|
||||
|
||||
|
||||
public function getFromExpression()
|
||||
{
|
||||
return $this->_fromExpression;
|
||||
}
|
||||
|
||||
|
||||
public function getToExpression()
|
||||
{
|
||||
return $this->_toExpression;
|
||||
|
@ -24,6 +24,7 @@
|
||||
*
|
||||
* @package Doctrine
|
||||
* @subpackage Query
|
||||
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
|
||||
* @author Janne Vanhala <jpvanhal@cc.hut.fi>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link http://www.phpdoctrine.org
|
||||
@ -72,29 +73,20 @@ class Doctrine_Query_Production_ComparisonExpression extends Doctrine_Query_Prod
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Visitor support.
|
||||
*
|
||||
* @param object $visitor
|
||||
*/
|
||||
public function accept($visitor)
|
||||
{
|
||||
$this->_expression->accept($visitor);
|
||||
$visitor->visitComparisonExpression($this);
|
||||
}
|
||||
|
||||
/* Getters */
|
||||
|
||||
public function getOperator()
|
||||
{
|
||||
return $this->_operator;
|
||||
}
|
||||
|
||||
|
||||
public function getExpression()
|
||||
{
|
||||
return $this->_expression;
|
||||
}
|
||||
|
||||
|
||||
public function isSubselect()
|
||||
{
|
||||
return $this->_isSubselect;
|
||||
|
@ -24,6 +24,7 @@
|
||||
*
|
||||
* @package Doctrine
|
||||
* @subpackage Query
|
||||
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
|
||||
* @author Janne Vanhala <jpvanhal@cc.hut.fi>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link http://www.phpdoctrine.org
|
||||
@ -78,14 +79,4 @@ class Doctrine_Query_Production_ComparisonOperator extends Doctrine_Query_Produc
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Visitor support.
|
||||
*
|
||||
* @param object $visitor
|
||||
*/
|
||||
public function accept($visitor)
|
||||
{
|
||||
$visitor->visitComparisonOperator($this);
|
||||
}
|
||||
}
|
||||
|
@ -70,21 +70,8 @@ class Doctrine_Query_Production_ConditionalExpression extends Doctrine_Query_Pro
|
||||
return $value->buildSql();
|
||||
}
|
||||
|
||||
/**
|
||||
* Visitor support.
|
||||
*
|
||||
* @param object $visitor
|
||||
*/
|
||||
public function accept($visitor)
|
||||
{
|
||||
foreach ($this->_conditionalTerms as $term) {
|
||||
$term->accept($visitor);
|
||||
}
|
||||
$visitor->visitConditionalExpression($this);
|
||||
}
|
||||
|
||||
/* Getters */
|
||||
|
||||
public function getConditionalTerms()
|
||||
{
|
||||
return $this->_conditionalTerms;
|
||||
|
@ -61,19 +61,8 @@ class Doctrine_Query_Production_ConditionalFactor extends Doctrine_Query_Product
|
||||
return 'NOT ' . $this->_conditionalPrimary->buildSql();
|
||||
}
|
||||
|
||||
/**
|
||||
* Visitor support
|
||||
*
|
||||
* @param object $visitor
|
||||
*/
|
||||
public function accept($visitor)
|
||||
{
|
||||
$this->_conditionalPrimary->accept($visitor);
|
||||
$visitor->visitConditionalFactor($this);
|
||||
}
|
||||
|
||||
/* Getters */
|
||||
|
||||
public function getConditionalPrimary()
|
||||
{
|
||||
return $this->_conditionalPrimary;
|
||||
|
@ -99,9 +99,10 @@ class Doctrine_Query_Production_ConditionalPrimary extends Doctrine_Query_Produc
|
||||
return false;
|
||||
}
|
||||
|
||||
public function accept($visitor)
|
||||
|
||||
/* Getters */
|
||||
public function getConditionalExpression()
|
||||
{
|
||||
$this->_conditionalExpression->accept($visitor);
|
||||
$visitor->visitConditionalPrimary($this);
|
||||
return $this->_conditionalExpression;
|
||||
}
|
||||
}
|
||||
|
@ -70,21 +70,8 @@ class Doctrine_Query_Production_ConditionalTerm extends Doctrine_Query_Productio
|
||||
return $value->buildSql();
|
||||
}
|
||||
|
||||
/**
|
||||
* Visitor support
|
||||
*
|
||||
* @param object $visitor
|
||||
*/
|
||||
public function accept($visitor)
|
||||
{
|
||||
foreach ($this->_conditionalFactors as $factor) {
|
||||
$factor->accept($visitor);
|
||||
}
|
||||
$visitor->visitConditionalTerm($this);
|
||||
}
|
||||
|
||||
/* Getters */
|
||||
|
||||
public function getConditionalFactors()
|
||||
{
|
||||
return $this->_conditionalFactors;
|
||||
|
@ -52,19 +52,8 @@ class Doctrine_Query_Production_ExistsExpression extends Doctrine_Query_Producti
|
||||
return 'EXISTS (' . $this->_subselect->buildSql() . ')';
|
||||
}
|
||||
|
||||
/**
|
||||
* Visitor support
|
||||
*
|
||||
* @param object $visitor
|
||||
*/
|
||||
public function accept($visitor)
|
||||
{
|
||||
$this->_subselect->accept($visitor);
|
||||
$visitor->visitExistsExpression($this);
|
||||
}
|
||||
|
||||
/* Getters */
|
||||
|
||||
public function getSubselect()
|
||||
{
|
||||
return $this->_subselect;
|
||||
|
@ -87,21 +87,8 @@ class Doctrine_Query_Production_Expression extends Doctrine_Query_Production
|
||||
return (is_string($value) ? $value : $value->buildSql());
|
||||
}
|
||||
|
||||
/**
|
||||
* Visitor support
|
||||
*
|
||||
* @param object $visitor
|
||||
*/
|
||||
public function accept($visitor)
|
||||
{
|
||||
foreach ($this->_terms as $term) {
|
||||
$term->accept($visitor);
|
||||
}
|
||||
$visitor->visitExpression($this);
|
||||
}
|
||||
|
||||
/* Getters */
|
||||
|
||||
public function getTerms()
|
||||
{
|
||||
return $this->_terms;
|
||||
|
@ -24,6 +24,7 @@
|
||||
*
|
||||
* @package Doctrine
|
||||
* @subpackage Query
|
||||
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
|
||||
* @author Janne Vanhala <jpvanhal@cc.hut.fi>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link http://www.phpdoctrine.org
|
||||
@ -75,23 +76,14 @@ class Doctrine_Query_Production_FieldIdentificationVariable extends Doctrine_Que
|
||||
. Doctrine_Query_Production::SQLALIAS_SEPARATOR . $idx;
|
||||
}
|
||||
|
||||
/**
|
||||
* Visitor support
|
||||
*
|
||||
* @param object $visitor
|
||||
*/
|
||||
public function accept($visitor)
|
||||
{
|
||||
$visitor->visitFieldIdentificationVariable($this);
|
||||
}
|
||||
|
||||
/* Getters */
|
||||
|
||||
public function getFieldAlias()
|
||||
{
|
||||
return $this->_fieldAlias;
|
||||
}
|
||||
|
||||
|
||||
public function getColumnAlias()
|
||||
{
|
||||
return $this->_columnAlias;
|
||||
|
@ -72,21 +72,8 @@ class Doctrine_Query_Production_FromClause extends Doctrine_Query_Production
|
||||
return $value->buildSql();
|
||||
}
|
||||
|
||||
/**
|
||||
* Visitor support
|
||||
*
|
||||
* @param object $visitor
|
||||
*/
|
||||
public function accept($visitor)
|
||||
{
|
||||
foreach ($this->_identificationVariableDeclaration as $decl) {
|
||||
$decl->accept($visitor);
|
||||
}
|
||||
$visitor->visitFromClause($this);
|
||||
}
|
||||
|
||||
/* Getters */
|
||||
|
||||
public function getIdentificationVariableDeclarations()
|
||||
{
|
||||
return $this->_identificationVariableDeclaration;
|
||||
|
@ -62,21 +62,4 @@ class Doctrine_Query_Production_IdentificationVariable extends Doctrine_Query_Pr
|
||||
|
||||
return $this->_componentAlias;
|
||||
}
|
||||
|
||||
/**
|
||||
* Visitor support
|
||||
*
|
||||
* @param object $visitor
|
||||
*/
|
||||
public function accept($visitor)
|
||||
{
|
||||
$visitor->visitIdentificationVariable($this);
|
||||
}
|
||||
|
||||
/* Getters */
|
||||
|
||||
public function getComponentAlias()
|
||||
{
|
||||
return $this->_componentAlias;
|
||||
}
|
||||
}
|
||||
|
@ -20,7 +20,7 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* IdentificationVariableDeclaration = RangeVariableDeclaration [IndexBy] {Join [IndexBy]}
|
||||
* IdentificationVariableDeclaration = RangeVariableDeclaration [IndexBy] {JoinVariableDeclaration}
|
||||
*
|
||||
* @package Doctrine
|
||||
* @subpackage Query
|
||||
@ -37,7 +37,7 @@ class Doctrine_Query_Production_IdentificationVariableDeclaration extends Doctri
|
||||
|
||||
protected $_indexBy;
|
||||
|
||||
protected $_relations = array();
|
||||
protected $_joinVariableDeclarations = array();
|
||||
|
||||
|
||||
public function syntax($paramHolder)
|
||||
@ -45,7 +45,7 @@ class Doctrine_Query_Production_IdentificationVariableDeclaration extends Doctri
|
||||
$this->_rangeVariableDeclaration = $this->AST('RangeVariableDeclaration', $paramHolder);
|
||||
|
||||
if ($this->_isNextToken(Doctrine_Query_Token::T_INDEX)) {
|
||||
$paramHolder->set('componentAlias', $this->_rangeVariableDeclaration);
|
||||
$paramHolder->set('componentAlias', $this->_rangeVariableDeclaration->getIdentificationVariable());
|
||||
$this->_indexBy = $this->AST('IndexBy', $paramHolder);
|
||||
$paramHolder->remove('componentAlias');
|
||||
}
|
||||
@ -55,75 +55,38 @@ class Doctrine_Query_Production_IdentificationVariableDeclaration extends Doctri
|
||||
$this->_isNextToken(Doctrine_Query_Token::T_INNER) ||
|
||||
$this->_isNextToken(Doctrine_Query_Token::T_JOIN)
|
||||
) {
|
||||
$i = count($this->_relations);
|
||||
|
||||
$this->_relations[$i]['join'] = $this->AST('Join', $paramHolder);
|
||||
|
||||
if ($this->_isNextToken(Doctrine_Query_Token::T_INDEX)) {
|
||||
$paramHolder->set('componentAlias', $this->_relations[$i]['join']->getRangeVariableDeclaration());
|
||||
$this->_relations[$i]['indexBy'] = $this->AST('IndexBy', $paramHolder);
|
||||
$paramHolder->remove('componentAlias');
|
||||
}
|
||||
$this->_joinVariableDeclarations[] = $this->AST('JoinVariableDeclaration', $paramHolder);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public function buildSql()
|
||||
{
|
||||
// We need to bring the queryComponent and get things from there.
|
||||
$parserResult = $this->_parser->getParserResult();
|
||||
$queryComponent = $parserResult->getQueryComponent($this->_rangeVariableDeclaration);
|
||||
$str = $this->_rangeVariableDeclaration->buildSql();
|
||||
|
||||
// Retrieving connection
|
||||
$conn = $this->_em->getConnection();
|
||||
|
||||
$str = $conn->quoteIdentifier($queryComponent['metadata']->getTableName()) . ' '
|
||||
. $conn->quoteIdentifier($parserResult->getTableAliasFromComponentAlias($this->_rangeVariableDeclaration));
|
||||
|
||||
for ($i = 0, $l = count($this->_relations); $i < $l; $i++) {
|
||||
$str .= $this->_relations[$i]['join']->buildSql() . ' '
|
||||
. ((isset($this->_relations[$i]['indexby'])) ? $this->_relations[$i]['indexby']->buildSql() . ' ' : '');
|
||||
for ($i = 0, $l = count($this->_joinVariableDeclarations); $i < $l; $i++) {
|
||||
$str .= ' ' . $this->_joinVariableDeclarations[$i]->buildSql();
|
||||
}
|
||||
|
||||
return $str;
|
||||
}
|
||||
|
||||
/**
|
||||
* Visitor support
|
||||
*
|
||||
* @param object $visitor
|
||||
*/
|
||||
public function accept($visitor)
|
||||
{
|
||||
$this->_rangeVariableDeclaration->accept($visitor);
|
||||
if ($this->_indexBy) {
|
||||
$this->_indexBy->accept($visitor);
|
||||
}
|
||||
foreach ($this->_relations as $relation) {
|
||||
if ($relation['join']) {
|
||||
$relation['join']->accept($visitor);
|
||||
}
|
||||
if ($relation['indexby']) {
|
||||
$relation['indexby']->accept($visitor);
|
||||
}
|
||||
}
|
||||
$visitor->visitIdentificationVariable($this);
|
||||
}
|
||||
|
||||
/* Getters */
|
||||
|
||||
public function getRangeVariableDeclaration()
|
||||
{
|
||||
return $this->_rangeVariableDeclaration;
|
||||
}
|
||||
|
||||
|
||||
public function getIndexBy()
|
||||
{
|
||||
return $this->_indexBy;
|
||||
}
|
||||
|
||||
public function getRelations()
|
||||
|
||||
public function getJoinVariableDeclarations()
|
||||
{
|
||||
return $this->_relations;
|
||||
return $this->_joinVariableDeclarations;
|
||||
}
|
||||
}
|
||||
|
@ -88,35 +88,20 @@ class Doctrine_Query_Production_InExpression extends Doctrine_Query_Production
|
||||
return $value->buildSql();
|
||||
}
|
||||
|
||||
/**
|
||||
* Visitor support
|
||||
*
|
||||
* @param object $visitor
|
||||
*/
|
||||
public function accept($visitor)
|
||||
{
|
||||
if ($this->_subselect !== null) {
|
||||
$this->_subselect->accept($visitor);
|
||||
} else {
|
||||
foreach ($this->_atoms as $atom) {
|
||||
$atom->accept($visitor);
|
||||
}
|
||||
}
|
||||
$visitor->visitInExpression($this);
|
||||
}
|
||||
|
||||
/* Getters */
|
||||
|
||||
public function isNot()
|
||||
{
|
||||
return $this->_not;
|
||||
}
|
||||
|
||||
|
||||
public function getSubselect()
|
||||
{
|
||||
return $this->_subselect;
|
||||
}
|
||||
|
||||
|
||||
public function getAtoms()
|
||||
{
|
||||
return $this->_atoms;
|
||||
|
@ -24,6 +24,7 @@
|
||||
*
|
||||
* @package Doctrine
|
||||
* @subpackage Query
|
||||
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
|
||||
* @author Janne Vanhala <jpvanhal@cc.hut.fi>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link http://www.phpdoctrine.org
|
||||
@ -95,7 +96,6 @@ class Doctrine_Query_Production_IndexBy extends Doctrine_Query_Production
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
$queryComponent['map'] = $this->_fieldName;
|
||||
$parserResult->setQueryComponent($this->_componentAlias, $queryComponent);
|
||||
}
|
||||
@ -106,23 +106,14 @@ class Doctrine_Query_Production_IndexBy extends Doctrine_Query_Production
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Visitor support
|
||||
*
|
||||
* @param object $visitor
|
||||
*/
|
||||
public function accept($visitor)
|
||||
{
|
||||
$visitor->visitIndexBy($this);
|
||||
}
|
||||
|
||||
/* Getters */
|
||||
|
||||
public function getComponentAlias()
|
||||
{
|
||||
return $this->_componentAlias;
|
||||
}
|
||||
|
||||
|
||||
public function getFieldName()
|
||||
{
|
||||
return $this->_fieldName;
|
||||
|
@ -24,6 +24,7 @@
|
||||
*
|
||||
* @package Doctrine
|
||||
* @subpackage Query
|
||||
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
|
||||
* @author Janne Vanhala <jpvanhal@cc.hut.fi>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link http://www.phpdoctrine.org
|
||||
@ -74,36 +75,68 @@ class Doctrine_Query_Production_Join extends Doctrine_Query_Production
|
||||
|
||||
public function buildSql()
|
||||
{
|
||||
return '';
|
||||
$parserResult = $this->_parser->getParserResult();
|
||||
|
||||
// Get the connection for the component
|
||||
$conn = $this->_em->getConnection();
|
||||
|
||||
$sql = $this->_joinType . ' JOIN ' . $this->_rangeVariableDeclaration->buildSql();
|
||||
$conditionExpression = isset($this->_conditionExpression)
|
||||
? $this->_conditionExpression->buildSql() : '';
|
||||
|
||||
if ($this->_whereType == 'ON') {
|
||||
return $sql . ' ON ' . $conditionExpression;
|
||||
}
|
||||
|
||||
// We need to build the relationship conditions. Retrieving AssociationMapping
|
||||
$queryComponent = $this->_rangeVariableDeclaration->getQueryComponent();
|
||||
$relationColumns = $queryComponent['relation']->getSourceToTargetKeyColumns();
|
||||
$relationConditionExpression = '';
|
||||
|
||||
// We have an array('localColumn' => 'foreignColumn', ...) here
|
||||
foreach ($relationColumns as $localColumn => $foreignColumn) {
|
||||
// leftExpression = rightExpression
|
||||
|
||||
// Defining leftExpression
|
||||
$leftExpression = $conn->quoteIdentifier(
|
||||
$parserResult->getTableAliasFromComponentAlias($queryComponent['parent']) . '.' . $localColumn
|
||||
);
|
||||
|
||||
// Defining rightExpression
|
||||
$rightExpression = $conn->quoteIdentifier(
|
||||
$parserResult->getTableAliasFromComponentAlias(
|
||||
$this->_rangeVariableDeclaration->getIdentificationVariable()
|
||||
) . '.' . $foreignColumn
|
||||
);
|
||||
|
||||
// Building the relation
|
||||
$relationConditionExpression .= (($relationConditionExpression != '') ? ' AND ' : '')
|
||||
. $leftExpression . ' = ' . $rightExpression;
|
||||
}
|
||||
|
||||
return $sql . ' ON ' . $relationConditionExpression . ' AND (' . $conditionExpression . ')';
|
||||
}
|
||||
|
||||
/**
|
||||
* Visitor support
|
||||
*
|
||||
* @param object $visitor
|
||||
*/
|
||||
public function accept($visitor)
|
||||
{
|
||||
$visitor->visitJoin($this);
|
||||
}
|
||||
|
||||
/* Getters */
|
||||
|
||||
public function getJoinType()
|
||||
{
|
||||
return $this->_joinType;
|
||||
}
|
||||
|
||||
|
||||
public function getRangeVariableDeclaration()
|
||||
{
|
||||
return $this->_rangeVariableDeclaration;
|
||||
}
|
||||
|
||||
|
||||
public function getWhereType()
|
||||
{
|
||||
return $this->_whereType;
|
||||
}
|
||||
|
||||
|
||||
public function getConditionalExpression()
|
||||
{
|
||||
return $this->_conditionalExpression;
|
||||
|
70
lib/Doctrine/Query/Production/JoinVariableDeclaration.php
Executable file
70
lib/Doctrine/Query/Production/JoinVariableDeclaration.php
Executable file
@ -0,0 +1,70 @@
|
||||
<?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.org>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* JoinVariableDeclaration = Join [IndexBy]
|
||||
*
|
||||
* @package Doctrine
|
||||
* @subpackage Query
|
||||
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
|
||||
* @author Janne Vanhala <jpvanhal@cc.hut.fi>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link http://www.phpdoctrine.org
|
||||
* @since 2.0
|
||||
* @version $Revision$
|
||||
*/
|
||||
class Doctrine_Query_Production_JoinVariableDeclaration extends Doctrine_Query_Production
|
||||
{
|
||||
protected $_join;
|
||||
|
||||
protected $_indexBy;
|
||||
|
||||
|
||||
public function syntax($paramHolder)
|
||||
{
|
||||
$this->_join = $this->AST('Join', $paramHolder);
|
||||
|
||||
if ($this->_isNextToken(Doctrine_Query_Token::T_INDEX)) {
|
||||
$paramHolder->set('componentAlias', $this->_join->getRangeVariableDeclaration()->getIdentificationVariable());
|
||||
$this->_indexBy = $this->AST('IndexBy', $paramHolder);
|
||||
$paramHolder->remove('componentAlias');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public function buildSql()
|
||||
{
|
||||
return $this->_join->buildSql() . ' ' . (isset($this->_indexby) ? $this->_indexby->buildSql() . ' ' : '');
|
||||
}
|
||||
|
||||
|
||||
/* Getters */
|
||||
public function getJoin()
|
||||
{
|
||||
return $this->_join;
|
||||
}
|
||||
|
||||
|
||||
public function getIndexBy()
|
||||
{
|
||||
return $this->_indexBy;
|
||||
}
|
||||
}
|
@ -70,29 +70,20 @@ class Doctrine_Query_Production_LikeExpression extends Doctrine_Query_Production
|
||||
. (($this->_escapeString !== null) ? ' ESCAPE ' . $this->_escapeString : '');
|
||||
}
|
||||
|
||||
/**
|
||||
* Visitor support
|
||||
*
|
||||
* @param object $visitor
|
||||
*/
|
||||
public function accept($visitor)
|
||||
{
|
||||
$this->_expression->accept($visitor);
|
||||
$visitor->visitLikeExpression($this);
|
||||
}
|
||||
|
||||
/* Getters */
|
||||
|
||||
public function isNot()
|
||||
{
|
||||
return $this->_not;
|
||||
}
|
||||
|
||||
|
||||
public function getExpression()
|
||||
{
|
||||
return $this->_expression;
|
||||
}
|
||||
|
||||
|
||||
public function getEscapeString()
|
||||
{
|
||||
return $this->_escapeString;
|
||||
|
@ -56,18 +56,8 @@ class Doctrine_Query_Production_NullComparisonExpression extends Doctrine_Query_
|
||||
return 'IS ' . (($this->_not) ? 'NOT ' : '') . 'NULL';
|
||||
}
|
||||
|
||||
/**
|
||||
* Visitor support
|
||||
*
|
||||
* @param object $visitor
|
||||
*/
|
||||
public function accept($visitor)
|
||||
{
|
||||
$visitor->visitNullComparisonExpression($this);
|
||||
}
|
||||
|
||||
/* Getters */
|
||||
|
||||
public function isNot()
|
||||
{
|
||||
return $this->_not;
|
||||
|
@ -154,23 +154,14 @@ class Doctrine_Query_Production_PathExpressionEndingWithAsterisk extends Doctrin
|
||||
return $str;
|
||||
}
|
||||
|
||||
/**
|
||||
* Visitor support
|
||||
*
|
||||
* @param object $visitor
|
||||
*/
|
||||
public function accept($visitor)
|
||||
{
|
||||
$visitor->visitPathExpressionEndingWithAsterisk($this);
|
||||
}
|
||||
|
||||
/* Getters */
|
||||
|
||||
public function getIdentifiers()
|
||||
{
|
||||
return $this->_identifiers;
|
||||
}
|
||||
|
||||
|
||||
public function getQueryComponent()
|
||||
{
|
||||
return $this->_queryComponent;
|
||||
|
@ -70,24 +70,14 @@ class Doctrine_Query_Production_QuantifiedExpression extends Doctrine_Query_Prod
|
||||
return $this->_type . ' (' . $this->_subselect->buildSql() . ')';
|
||||
}
|
||||
|
||||
/**
|
||||
* Visitor support
|
||||
*
|
||||
* @param object $visitor
|
||||
*/
|
||||
public function accept($visitor)
|
||||
{
|
||||
$this->_subselect->accept($visitor);
|
||||
$visitor->visitQuantifiedExpression($this);
|
||||
}
|
||||
|
||||
/* Getters */
|
||||
|
||||
public function getType()
|
||||
{
|
||||
return $this->_type;
|
||||
}
|
||||
|
||||
|
||||
public function getSubselect()
|
||||
{
|
||||
return $this->_subselect;
|
||||
|
@ -35,6 +35,8 @@ class Doctrine_Query_Production_RangeVariableDeclaration extends Doctrine_Query_
|
||||
{
|
||||
protected $_identifiers = array();
|
||||
|
||||
protected $_queryComponent;
|
||||
|
||||
protected $_identificationVariable;
|
||||
|
||||
|
||||
@ -99,14 +101,19 @@ class Doctrine_Query_Production_RangeVariableDeclaration extends Doctrine_Query_
|
||||
$this->_semanticalWithSingleIdentifier();
|
||||
}
|
||||
}
|
||||
|
||||
return $this->_identificationVariable;
|
||||
}
|
||||
|
||||
|
||||
public function buildSql()
|
||||
{
|
||||
return '';
|
||||
// We need to bring the queryComponent and get things from there.
|
||||
$parserResult = $this->_parser->getParserResult();
|
||||
|
||||
// Retrieving connection
|
||||
$conn = $this->_em->getConnection();
|
||||
|
||||
return $conn->quoteIdentifier($this->_queryComponent['metadata']->getTableName()) . ' '
|
||||
. $conn->quoteIdentifier($parserResult->getTableAliasFromComponentAlias($this->_identificationVariable));
|
||||
}
|
||||
|
||||
|
||||
@ -123,7 +130,7 @@ class Doctrine_Query_Production_RangeVariableDeclaration extends Doctrine_Query_
|
||||
$classMetadata = $this->_em->getClassMetadata($componentName);
|
||||
|
||||
// Building queryComponent
|
||||
$queryComponent = array(
|
||||
$this->_queryComponent = array(
|
||||
'metadata' => $classMetadata,
|
||||
'parent' => null,
|
||||
'relation' => null,
|
||||
@ -144,7 +151,7 @@ class Doctrine_Query_Production_RangeVariableDeclaration extends Doctrine_Query_
|
||||
//echo "Identification Variable: " .$this->_identificationVariable . "\n";
|
||||
|
||||
$tableAlias = $parserResult->generateTableAlias($classMetadata->getClassName());
|
||||
$parserResult->setQueryComponent($this->_identificationVariable, $queryComponent);
|
||||
$parserResult->setQueryComponent($this->_identificationVariable, $this->_queryComponent);
|
||||
$parserResult->setTableAlias($tableAlias, $this->_identificationVariable);
|
||||
}
|
||||
|
||||
@ -158,8 +165,8 @@ class Doctrine_Query_Production_RangeVariableDeclaration extends Doctrine_Query_
|
||||
|
||||
// Retrieve the base component
|
||||
try {
|
||||
$queryComponent = $parserResult->getQueryComponent($this->_identifiers[0]);
|
||||
$classMetadata = $queryComponent['metadata'];
|
||||
$this->_queryComponent = $parserResult->getQueryComponent($this->_identifiers[0]);
|
||||
$classMetadata = $this->_queryComponent['metadata'];
|
||||
$className = $classMetadata->getClassName();
|
||||
$parent = $path = $this->_identifiers[0];
|
||||
} catch (Doctrine_Exception $e) {
|
||||
@ -175,8 +182,8 @@ class Doctrine_Query_Production_RangeVariableDeclaration extends Doctrine_Query_
|
||||
|
||||
if ($parserResult->hasQueryComponent($path)) {
|
||||
// We already have the query component on hands, get it
|
||||
$queryComponent = $parserResult->getQueryComponent($path);
|
||||
$classMetadata = $queryComponent['metadata'];
|
||||
$this->_queryComponent = $parserResult->getQueryComponent($path);
|
||||
$classMetadata = $this->_queryComponent['metadata'];
|
||||
|
||||
// If we are in our last check and identification variable is null, we throw semantical error
|
||||
if ($i == $l - 1 && $this->_identificationVariable === null) {
|
||||
@ -204,7 +211,7 @@ class Doctrine_Query_Production_RangeVariableDeclaration extends Doctrine_Query_
|
||||
$relation = $classMetadata->getAssociationMapping($relationName);
|
||||
$targetClassMetadata = $this->_em->getClassMetadata($relation->getTargetEntityName());
|
||||
|
||||
$queryComponent = array(
|
||||
$this->_queryComponent = array(
|
||||
'metadata' => $targetClassMetadata,
|
||||
'parent' => $parent,
|
||||
'relation' => $relation,
|
||||
@ -228,29 +235,24 @@ class Doctrine_Query_Production_RangeVariableDeclaration extends Doctrine_Query_
|
||||
|
||||
$tableAlias = $parserResult->generateTableAlias($targetClassMetadata->getClassName());
|
||||
|
||||
//echo "Table alias: " . $tableAlias . "\n";
|
||||
|
||||
$parserResult->setQueryComponent($this->_identificationVariable, $queryComponent);
|
||||
$parserResult->setQueryComponent($this->_identificationVariable, $this->_queryComponent);
|
||||
$parserResult->setTableAlias($tableAlias, $this->_identificationVariable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Visitor support
|
||||
*
|
||||
* @param object $visitor
|
||||
*/
|
||||
public function accept($visitor)
|
||||
{
|
||||
$visitor->visitRangeVariableDeclaration($this);
|
||||
}
|
||||
|
||||
/* Getters */
|
||||
|
||||
public function getIdentifiers()
|
||||
{
|
||||
return $this->_identifiers;
|
||||
}
|
||||
|
||||
|
||||
public function getQueryComponent()
|
||||
{
|
||||
return $this->_queryComponent;
|
||||
}
|
||||
|
||||
|
||||
public function getIdentificationVariable()
|
||||
{
|
||||
return $this->_identificationVariable;
|
||||
|
@ -86,26 +86,14 @@ class Doctrine_Query_Production_SelectClause extends Doctrine_Query_Production
|
||||
return $value->buildSql();
|
||||
}
|
||||
|
||||
/**
|
||||
* Visitor support
|
||||
*
|
||||
* @param object $visitor
|
||||
*/
|
||||
public function accept($visitor)
|
||||
{
|
||||
foreach ($this->_selectExpressions as $expression) {
|
||||
$expression->accept($visitor);
|
||||
}
|
||||
$visitor->visitSelectClause($this);
|
||||
}
|
||||
|
||||
/* Getters */
|
||||
|
||||
public function isDistinct()
|
||||
{
|
||||
return $this->_isDistinct;
|
||||
}
|
||||
|
||||
|
||||
public function getSelectExpressions()
|
||||
{
|
||||
return $this->_selectExpressions;
|
||||
|
@ -190,4 +190,23 @@ class Doctrine_Query_Production_SelectExpression extends Doctrine_Query_Producti
|
||||
{
|
||||
return ! is_string($value);
|
||||
}
|
||||
|
||||
|
||||
/* Getters */
|
||||
public function getLeftExpression()
|
||||
{
|
||||
return $this->_leftExpression;
|
||||
}
|
||||
|
||||
|
||||
public function isSubselect()
|
||||
{
|
||||
return $this->_isSubselect;
|
||||
}
|
||||
|
||||
|
||||
public function getFieldIdentificationVariable()
|
||||
{
|
||||
return $this->_fieldIdentificationVariable;
|
||||
}
|
||||
}
|
||||
|
@ -94,57 +94,38 @@ class Doctrine_Query_Production_SelectStatement extends Doctrine_Query_Productio
|
||||
. (($this->_orderByClause !== null) ? ' ' . $this->_orderByClause->buildSql() : '');
|
||||
}
|
||||
|
||||
/**
|
||||
* Visitor support
|
||||
*
|
||||
* @param object $visitor
|
||||
*/
|
||||
public function accept($visitor)
|
||||
{
|
||||
$this->_selectClause->accept($visitor);
|
||||
$this->_fromClause->accept($visitor);
|
||||
if ($this->_whereClause) {
|
||||
$this->_whereClause->accept($visitor);
|
||||
}
|
||||
if ($this->_groupByClause) {
|
||||
$this->_groupByClause->accept($visitor);
|
||||
}
|
||||
if ($this->_havingClause) {
|
||||
$this->_havingClause->accept($visitor);
|
||||
}
|
||||
if ($this->_orderByClause) {
|
||||
$this->_orderByClause->accept($visitor);
|
||||
}
|
||||
$visitor->visitSelectStatement($this);
|
||||
}
|
||||
|
||||
/* Getters */
|
||||
|
||||
public function getSelectClause()
|
||||
{
|
||||
return $this->_selectClause;
|
||||
}
|
||||
|
||||
|
||||
public function getFromClause()
|
||||
{
|
||||
return $this->_fromClause;
|
||||
}
|
||||
|
||||
|
||||
public function getWhereClause()
|
||||
{
|
||||
return $this->_whereClause;
|
||||
}
|
||||
|
||||
|
||||
public function getGroupByClause()
|
||||
{
|
||||
return $this->_groupByClause;
|
||||
}
|
||||
|
||||
|
||||
public function getHavingClause()
|
||||
{
|
||||
return $this->_havingClause;
|
||||
}
|
||||
|
||||
|
||||
public function getOrderByClause()
|
||||
{
|
||||
return $this->_orderByClause;
|
||||
|
@ -107,25 +107,14 @@ class Doctrine_Query_Production_SimpleConditionalExpression extends Doctrine_Que
|
||||
return $token['type'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Visitor support
|
||||
*
|
||||
* @param object $visitor
|
||||
*/
|
||||
public function accept($visitor)
|
||||
{
|
||||
$this->_leftExpression->accept($visitor);
|
||||
$this->_rightExpression->accept($visitor);
|
||||
$visitor->visitSimpleConditionalExpression($this);
|
||||
}
|
||||
|
||||
/* Getters */
|
||||
|
||||
public function getLeftExpression()
|
||||
{
|
||||
return $this->_leftExpression;
|
||||
}
|
||||
|
||||
|
||||
public function getRightExpression()
|
||||
{
|
||||
return $this->_rightExpression;
|
||||
|
@ -50,17 +50,8 @@ class Doctrine_Query_Production_WhereClause extends Doctrine_Query_Production
|
||||
return 'WHERE ' . $this->_conditionalExpression->buildSql();
|
||||
}
|
||||
|
||||
/**
|
||||
* Visitor support.
|
||||
*/
|
||||
public function accept($visitor)
|
||||
{
|
||||
$this->_conditionalExpression->accept($visitor);
|
||||
$visitor->visitWhereClause($this);
|
||||
}
|
||||
|
||||
/* Getters */
|
||||
|
||||
public function getConditionalExpression()
|
||||
{
|
||||
return $this->_conditionalExpression;
|
||||
|
@ -37,7 +37,8 @@ OrderByItem = Expression ["ASC" | "DESC"]
|
||||
GroupByItem = PathExpression
|
||||
UpdateItem = PathExpression "=" (Expression | "NULL")
|
||||
|
||||
IdentificationVariableDeclaration = RangeVariableDeclaration [IndexBy] {Join [IndexBy]}
|
||||
IdentificationVariableDeclaration = RangeVariableDeclaration [IndexBy] {JoinVariableDeclaration}
|
||||
JoinVariableDeclaration = Join [IndexBy]
|
||||
RangeVariableDeclaration = identifier {"." identifier} [["AS"] IdentificationVariable]
|
||||
VariableDeclaration = identifier [["AS"] IdentificationVariable]
|
||||
IdentificationVariable = identifier
|
||||
|
@ -167,4 +167,13 @@ class Orm_Query_SelectSqlGenerationTest extends Doctrine_OrmTestCase
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
public function testPlainJoinWithoutClause()
|
||||
{
|
||||
$this->assertSqlGeneration(
|
||||
'SELECT u.id, a.id FROM CmsUser u LEFT JOIN u.articles a',
|
||||
'SELECT cu.id AS cu__id, ca.id AS ca__id FROM cms_user cu LEFT JOIN cms_article ca ON ca.user_id = cu.id WHERE 1 = 1'
|
||||
);
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user