From 33fc28ffbda6b2a933565426e8f5dee1b7c03bf5 Mon Sep 17 00:00:00 2001 From: guilhermeblanco Date: Thu, 6 Aug 2009 21:42:07 +0000 Subject: [PATCH] [2.0] Updated AST nodes to use public properties instead of setter/getter methods. --- .../DBAL/Platforms/AbstractPlatform.php | 11 +- lib/Doctrine/ORM/AbstractQuery.php | 2 + .../ORM/Query/AST/ArithmeticFactor.php | 57 +- lib/Doctrine/ORM/Query/AST/ArithmeticTerm.php | 38 +- .../ORM/Query/AST/BetweenExpression.php | 70 +- .../Query/AST/CollectionMemberExpression.php | 34 +- .../ORM/Query/AST/ComparisonExpression.php | 35 +- .../ORM/Query/AST/ComparisonOperator.php | 42 - .../ORM/Query/AST/ConditionalExpression.php | 38 +- .../ORM/Query/AST/ConditionalFactor.php | 48 +- .../ORM/Query/AST/ConditionalPrimary.php | 57 +- .../ORM/Query/AST/ConditionalTerm.php | 38 +- lib/Doctrine/ORM/Query/AST/DeleteClause.php | 29 +- .../ORM/Query/AST/DeleteStatement.php | 33 +- .../EmptyCollectionComparisonExpression.php | 50 +- .../ORM/Query/AST/ExistsExpression.php | 50 +- lib/Doctrine/ORM/Query/AST/FromClause.php | 24 +- .../ORM/Query/AST/Functions/AbsFunction.php | 43 +- .../Query/AST/Functions/ConcatFunction.php | 51 +- .../AST/Functions/CurrentDateFunction.php | 29 +- .../AST/Functions/CurrentTimeFunction.php | 29 +- .../ORM/Query/AST/Functions/FunctionNode.php | 19 +- .../Query/AST/Functions/LengthFunction.php | 43 +- .../Query/AST/Functions/LocateFunction.php | 78 +- .../ORM/Query/AST/Functions/LowerFunction.php | 43 +- .../ORM/Query/AST/Functions/ModFunction.php | 62 +- .../ORM/Query/AST/Functions/SizeFunction.php | 29 +- .../ORM/Query/AST/Functions/SqrtFunction.php | 43 +- .../Query/AST/Functions/SubstringFunction.php | 75 +- .../ORM/Query/AST/Functions/TrimFunction.php | 118 +- .../ORM/Query/AST/Functions/UpperFunction.php | 43 +- lib/Doctrine/ORM/Query/AST/GroupByClause.php | 38 +- lib/Doctrine/ORM/Query/AST/HavingClause.php | 38 +- .../AST/IdentificationVariableDeclaration.php | 44 +- lib/Doctrine/ORM/Query/AST/InExpression.php | 74 +- lib/Doctrine/ORM/Query/AST/IndexBy.php | 22 +- lib/Doctrine/ORM/Query/AST/InputParameter.php | 62 +- lib/Doctrine/ORM/Query/AST/Join.php | 66 +- .../AST/JoinAssociationPathExpression.php | 50 +- .../ORM/Query/AST/JoinVariableDeclaration.php | 31 +- lib/Doctrine/ORM/Query/AST/LikeExpression.php | 66 +- lib/Doctrine/ORM/Query/AST/Node.php | 14 +- .../Query/AST/NullComparisonExpression.php | 52 +- lib/Doctrine/ORM/Query/AST/OrderByClause.php | 38 +- lib/Doctrine/ORM/Query/AST/OrderByItem.php | 42 +- lib/Doctrine/ORM/Query/AST/PathExpression.php | 88 +- .../ORM/Query/AST/QuantifiedExpression.php | 58 +- .../Query/AST/RangeVariableDeclaration.php | 40 +- lib/Doctrine/ORM/Query/AST/SelectClause.php | 49 +- .../ORM/Query/AST/SelectExpression.php | 31 +- .../ORM/Query/AST/SelectStatement.php | 66 +- .../Query/AST/SimpleArithmeticExpression.php | 38 +- .../ORM/Query/AST/SimpleSelectClause.php | 37 +- .../ORM/Query/AST/SimpleSelectExpression.php | 35 +- lib/Doctrine/ORM/Query/AST/Subselect.php | 79 +- .../ORM/Query/AST/SubselectFromClause.php | 22 +- lib/Doctrine/ORM/Query/AST/UpdateClause.php | 59 +- lib/Doctrine/ORM/Query/AST/UpdateItem.php | 39 +- .../ORM/Query/AST/UpdateStatement.php | 33 +- lib/Doctrine/ORM/Query/AST/WhereClause.php | 40 +- .../Query/Exec/MultiTableDeleteExecutor.php | 8 +- .../Query/Exec/MultiTableUpdateExecutor.php | 25 +- lib/Doctrine/ORM/Query/Parser.php | 244 +- lib/Doctrine/ORM/Query/SqlWalker.php | 2573 +++++++++-------- 64 files changed, 2788 insertions(+), 2774 deletions(-) delete mode 100644 lib/Doctrine/ORM/Query/AST/ComparisonOperator.php diff --git a/lib/Doctrine/DBAL/Platforms/AbstractPlatform.php b/lib/Doctrine/DBAL/Platforms/AbstractPlatform.php index 15600cefc..2c74be603 100644 --- a/lib/Doctrine/DBAL/Platforms/AbstractPlatform.php +++ b/lib/Doctrine/DBAL/Platforms/AbstractPlatform.php @@ -30,9 +30,14 @@ use Doctrine\DBAL\Types; * point of abstraction of platform-specific behaviors, features and SQL dialects. * They are a passive source of information. * - * @since 2.0 - * @author Roman Borschel - * @author Lukas Smith (PEAR MDB2 library) + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision: 3938 $ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + * @author Lukas Smith (PEAR MDB2 library) */ abstract class AbstractPlatform { diff --git a/lib/Doctrine/ORM/AbstractQuery.php b/lib/Doctrine/ORM/AbstractQuery.php index 84b0203f0..d69ff989b 100644 --- a/lib/Doctrine/ORM/AbstractQuery.php +++ b/lib/Doctrine/ORM/AbstractQuery.php @@ -21,6 +21,8 @@ namespace Doctrine\ORM; +use Doctrine\ORM\Query\QueryException; + /** * Base class for Query and NativeQuery. * diff --git a/lib/Doctrine/ORM/Query/AST/ArithmeticFactor.php b/lib/Doctrine/ORM/Query/AST/ArithmeticFactor.php index 9fcaef76d..b559e4a30 100644 --- a/lib/Doctrine/ORM/Query/AST/ArithmeticFactor.php +++ b/lib/Doctrine/ORM/Query/AST/ArithmeticFactor.php @@ -1,7 +1,22 @@ . */ namespace Doctrine\ORM\Query\AST; @@ -9,34 +24,40 @@ namespace Doctrine\ORM\Query\AST; /** * ArithmeticFactor ::= [("+" | "-")] ArithmeticPrimary * - * @author robo + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision: 3938 $ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel */ class ArithmeticFactor extends Node { - private $_arithmeticPrimary; - private $_pSigned; - private $_nSigned; + /** + * @var ArithmeticPrimary + */ + public $arithmeticPrimary; + + /** + * @var null|boolean NULL represents no sign, TRUE means positive and FALSE means negative sign + */ + public $sign; - public function __construct($arithmeticPrimary, $pSigned = false, $nSigned = false) + public function __construct($arithmeticPrimary, $sign = null) { - $this->_arithmeticPrimary = $arithmeticPrimary; - $this->_pSigned = $pSigned; - $this->_nSigned = $nSigned; - } - - public function getArithmeticPrimary() - { - return $this->_arithmeticPrimary; + $this->arithmeticPrimary = $arithmeticPrimary; + $this->sign = $sign; } public function isPositiveSigned() { - return $this->_pSigned; + return $this->sign === true; } public function isNegativeSigned() { - return $this->_nSigned; + return $this->sign === false; } public function dispatch($sqlWalker) diff --git a/lib/Doctrine/ORM/Query/AST/ArithmeticTerm.php b/lib/Doctrine/ORM/Query/AST/ArithmeticTerm.php index 1d2c18363..a233e0560 100644 --- a/lib/Doctrine/ORM/Query/AST/ArithmeticTerm.php +++ b/lib/Doctrine/ORM/Query/AST/ArithmeticTerm.php @@ -1,7 +1,22 @@ . */ namespace Doctrine\ORM\Query\AST; @@ -9,20 +24,21 @@ namespace Doctrine\ORM\Query\AST; /** * ArithmeticTerm ::= ArithmeticFactor {("*" | "/") ArithmeticFactor}* * - * @author robo + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision: 3938 $ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel */ class ArithmeticTerm extends Node { - private $_factors; + public $arithmeticFactors; public function __construct(array $arithmeticFactors) { - $this->_factors = $arithmeticFactors; - } - - public function getArithmeticFactors() - { - return $this->_factors; + $this->arithmeticFactors = $arithmeticFactors; } public function dispatch($sqlWalker) diff --git a/lib/Doctrine/ORM/Query/AST/BetweenExpression.php b/lib/Doctrine/ORM/Query/AST/BetweenExpression.php index 0b69eb281..c00bca4e6 100644 --- a/lib/Doctrine/ORM/Query/AST/BetweenExpression.php +++ b/lib/Doctrine/ORM/Query/AST/BetweenExpression.php @@ -1,7 +1,22 @@ . */ namespace Doctrine\ORM\Query\AST; @@ -9,45 +24,26 @@ namespace Doctrine\ORM\Query\AST; /** * Description of BetweenExpression * - * @author robo + @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision: 3938 $ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel */ class BetweenExpression extends Node { - private $_baseExpression; - private $_leftBetweenExpression; - private $_rightBetweenExpression; - private $_not; + public $expression; + public $leftBetweenExpression; + public $rightBetweenExpression; + public $not; - public function __construct($baseExpr, $leftExpr, $rightExpr) + public function __construct($expr, $leftExpr, $rightExpr) { - $this->_baseExpression = $baseExpr; - $this->_leftBetweenExpression = $leftExpr; - $this->_rightBetweenExpression = $rightExpr; - } - - public function getBaseExpression() - { - return $this->_baseExpression; - } - - public function getLeftBetweenExpression() - { - return $this->_leftBetweenExpression; - } - - public function getRightBetweenExpression() - { - return $this->_rightBetweenExpression; - } - - public function setNot($bool) - { - $this->_not = $bool; - } - - public function getNot() - { - return $this->_not; + $this->expression = $expr; + $this->leftBetweenExpression = $leftExpr; + $this->rightBetweenExpression = $rightExpr; } public function dispatch($sqlWalker) diff --git a/lib/Doctrine/ORM/Query/AST/CollectionMemberExpression.php b/lib/Doctrine/ORM/Query/AST/CollectionMemberExpression.php index 49bef8a79..ea252de08 100644 --- a/lib/Doctrine/ORM/Query/AST/CollectionMemberExpression.php +++ b/lib/Doctrine/ORM/Query/AST/CollectionMemberExpression.php @@ -1,23 +1,47 @@ . + */ + namespace Doctrine\ORM\Query\AST; /** * CollectionMemberExpression ::= EntityExpression ["NOT"] "MEMBER" ["OF"] CollectionValuedPathExpression * - * @author Roman Borschel + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision: 3938 $ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel */ class CollectionMemberExpression extends Node { public $entityExpression; public $collectionValuedPathExpression; - public $isNot; + public $not; - public function __construct($entityExpr, $collValuedPathExpr, $isNot) + public function __construct($entityExpr, $collValuedPathExpr) { $this->entityExpression = $entityExpr; $this->collectionValuedPathExpression = $collValuedPathExpr; - $this->isNot = $isNot; } public function dispatch($walker) diff --git a/lib/Doctrine/ORM/Query/AST/ComparisonExpression.php b/lib/Doctrine/ORM/Query/AST/ComparisonExpression.php index 915ddd0ad..a13ae2659 100644 --- a/lib/Doctrine/ORM/Query/AST/ComparisonExpression.php +++ b/lib/Doctrine/ORM/Query/AST/ComparisonExpression.php @@ -29,34 +29,25 @@ namespace Doctrine\ORM\Query\AST; * DatetimeExpression ComparisonOperator (DatetimeExpression | QuantifiedExpression) | * EntityExpression ("=" | "<>") (EntityExpression | QuantifiedExpression) * - * @author robo + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision: 3938 $ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel */ class ComparisonExpression extends Node { - private $_leftExpr; - private $_rightExpr; - private $_operator; + public $leftExpression; + public $rightExpression; + public $operator; public function __construct($leftExpr, $operator, $rightExpr) { - $this->_leftExpr = $leftExpr; - $this->_rightExpr = $rightExpr; - $this->_operator = $operator; - } - - public function getLeftExpression() - { - return $this->_leftExpr; - } - - public function getRightExpression() - { - return $this->_rightExpr; - } - - public function getOperator() - { - return $this->_operator; + $this->leftExpression = $leftExpr; + $this->rightExpression = $rightExpr; + $this->operator = $operator; } public function dispatch($sqlWalker) diff --git a/lib/Doctrine/ORM/Query/AST/ComparisonOperator.php b/lib/Doctrine/ORM/Query/AST/ComparisonOperator.php deleted file mode 100644 index 780f0f10b..000000000 --- a/lib/Doctrine/ORM/Query/AST/ComparisonOperator.php +++ /dev/null @@ -1,42 +0,0 @@ -. - */ - -namespace Doctrine\ORM\Query\AST; - -/** - * ComparisonOperator = "=" | "<" | "<=" | "<>" | ">" | ">=" | "!=" - * - * @package Doctrine - * @subpackage Query - * @author Guilherme Blanco - * @author Janne Vanhala - * @license http://www.opensource.org/licenses/lgpl-license.php LGPL - * @link http://www.phpdoctrine.org - * @since 2.0 - * @version $Revision$ - */ -class ComparisonOperator extends Node -{ - public function dispatch($sqlWalker) - { - ; - } -} \ No newline at end of file diff --git a/lib/Doctrine/ORM/Query/AST/ConditionalExpression.php b/lib/Doctrine/ORM/Query/AST/ConditionalExpression.php index ad2d57059..d2e776203 100644 --- a/lib/Doctrine/ORM/Query/AST/ConditionalExpression.php +++ b/lib/Doctrine/ORM/Query/AST/ConditionalExpression.php @@ -1,7 +1,22 @@ . */ namespace Doctrine\ORM\Query\AST; @@ -9,20 +24,21 @@ namespace Doctrine\ORM\Query\AST; /** * ConditionalExpression ::= ConditionalTerm {"OR" ConditionalTerm}* * - * @author robo + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision: 3938 $ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel */ class ConditionalExpression extends Node { - private $_conditionalTerms = array(); + public $conditionalTerms = array(); public function __construct(array $conditionalTerms) { - $this->_conditionalTerms = $conditionalTerms; - } - - public function getConditionalTerms() - { - return $this->_conditionalTerms; + $this->conditionalTerms = $conditionalTerms; } public function dispatch($sqlWalker) diff --git a/lib/Doctrine/ORM/Query/AST/ConditionalFactor.php b/lib/Doctrine/ORM/Query/AST/ConditionalFactor.php index b300b130c..f0b165bf6 100644 --- a/lib/Doctrine/ORM/Query/AST/ConditionalFactor.php +++ b/lib/Doctrine/ORM/Query/AST/ConditionalFactor.php @@ -1,7 +1,22 @@ . */ namespace Doctrine\ORM\Query\AST; @@ -9,27 +24,22 @@ namespace Doctrine\ORM\Query\AST; /** * ConditionalFactor ::= ["NOT"] ConditionalPrimary * - * @author robo + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision: 3938 $ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel */ class ConditionalFactor extends Node { - private $_not = false; - private $_conditionalPrimary; + public $not = false; + public $conditionalPrimary; - public function __construct($conditionalPrimary, $not = false) + public function __construct($conditionalPrimary) { - $this->_conditionalPrimary = $conditionalPrimary; - $this->_not = $not; - } - - public function isNot() - { - return $this->_not; - } - - public function getConditionalPrimary() - { - return $this->_conditionalPrimary; + $this->conditionalPrimary = $conditionalPrimary; } public function dispatch($sqlWalker) diff --git a/lib/Doctrine/ORM/Query/AST/ConditionalPrimary.php b/lib/Doctrine/ORM/Query/AST/ConditionalPrimary.php index 4d9e8b48a..0e3f12704 100644 --- a/lib/Doctrine/ORM/Query/AST/ConditionalPrimary.php +++ b/lib/Doctrine/ORM/Query/AST/ConditionalPrimary.php @@ -1,7 +1,22 @@ . */ namespace Doctrine\ORM\Query\AST; @@ -9,41 +24,27 @@ namespace Doctrine\ORM\Query\AST; /** * ConditionalPrimary ::= SimpleConditionalExpression | "(" ConditionalExpression ")" * - * @author robo + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision: 3938 $ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel */ class ConditionalPrimary extends Node { - private $_simpleConditionalExpression; - private $_conditionalExpression; - - public function setSimpleConditionalExpression($simpleConditionalExpr) - { - $this->_simpleConditionalExpression = $simpleConditionalExpr; - } - - public function setConditionalExpression($conditionalExpr) - { - $this->_conditionalExpression = $conditionalExpr; - } - - public function getSimpleConditionalExpression() - { - return $this->_simpleConditionalExpression; - } - - public function getConditionalExpression() - { - return $this->_conditionalExpression; - } + public $simpleConditionalExpression; + public $conditionalExpression; public function isSimpleConditionalExpression() { - return (bool) $this->_simpleConditionalExpression; + return (bool) $this->simpleConditionalExpression; } public function isConditionalExpression() { - return (bool) $this->_conditionalExpression; + return (bool) $this->conditionalExpression; } public function dispatch($sqlWalker) diff --git a/lib/Doctrine/ORM/Query/AST/ConditionalTerm.php b/lib/Doctrine/ORM/Query/AST/ConditionalTerm.php index 05e3c2cab..78ba6a2cd 100644 --- a/lib/Doctrine/ORM/Query/AST/ConditionalTerm.php +++ b/lib/Doctrine/ORM/Query/AST/ConditionalTerm.php @@ -1,7 +1,22 @@ . */ namespace Doctrine\ORM\Query\AST; @@ -9,20 +24,21 @@ namespace Doctrine\ORM\Query\AST; /** * ConditionalTerm ::= ConditionalFactor {"AND" ConditionalFactor}* * - * @author robo + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision: 3938 $ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel */ class ConditionalTerm extends Node { - private $_conditionalFactors = array(); + public $conditionalFactors = array(); public function __construct(array $conditionalFactors) { - $this->_conditionalFactors = $conditionalFactors; - } - - public function getConditionalFactors() - { - return $this->_conditionalFactors; + $this->conditionalFactors = $conditionalFactors; } public function dispatch($sqlWalker) diff --git a/lib/Doctrine/ORM/Query/AST/DeleteClause.php b/lib/Doctrine/ORM/Query/AST/DeleteClause.php index ef051665c..4acf49c77 100644 --- a/lib/Doctrine/ORM/Query/AST/DeleteClause.php +++ b/lib/Doctrine/ORM/Query/AST/DeleteClause.php @@ -23,30 +23,23 @@ namespace Doctrine\ORM\Query\AST; /** * DeleteClause ::= "DELETE" ["FROM"] AbstractSchemaName [["AS"] AliasIdentificationVariable] + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision: 3938 $ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel */ class DeleteClause extends Node { - private $_abstractSchemaName; - private $_aliasIdentificationVariable; + public $abstractSchemaName; + public $aliasIdentificationVariable; public function __construct($abstractSchemaName) { - $this->_abstractSchemaName = $abstractSchemaName; - } - - public function getAbstractSchemaName() - { - return $this->_abstractSchemaName; - } - - public function getAliasIdentificationVariable() - { - return $this->_aliasIdentificationVariable; - } - - public function setAliasIdentificationVariable($alias) - { - $this->_aliasIdentificationVariable = $alias; + $this->abstractSchemaName = $abstractSchemaName; } public function dispatch($sqlWalker) diff --git a/lib/Doctrine/ORM/Query/AST/DeleteStatement.php b/lib/Doctrine/ORM/Query/AST/DeleteStatement.php index 9afaad74b..de807abaa 100644 --- a/lib/Doctrine/ORM/Query/AST/DeleteStatement.php +++ b/lib/Doctrine/ORM/Query/AST/DeleteStatement.php @@ -24,37 +24,24 @@ namespace Doctrine\ORM\Query\AST; /** * DeleteStatement = DeleteClause [WhereClause] * - * @author Guilherme Blanco - * @license http://www.opensource.org/licenses/lgpl-license.php LGPL - * @link http://www.phpdoctrine.org - * @since 2.0 - * @version $Revision$ + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision: 3938 $ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel */ class DeleteStatement extends Node { - private $_deleteClause; - private $_whereClause; + public $deleteClause; + public $whereClause; public function __construct($deleteClause) { - $this->_deleteClause = $deleteClause; + $this->deleteClause = $deleteClause; } - public function setWhereClause($whereClause) - { - $this->_whereClause = $whereClause; - } - - public function getDeleteClause() - { - return $this->_deleteClause; - } - - public function getWhereClause() - { - return $this->_whereClause; - } - public function dispatch($sqlWalker) { return $sqlWalker->walkDeleteStatement($this); diff --git a/lib/Doctrine/ORM/Query/AST/EmptyCollectionComparisonExpression.php b/lib/Doctrine/ORM/Query/AST/EmptyCollectionComparisonExpression.php index 21c151b43..271d304dc 100644 --- a/lib/Doctrine/ORM/Query/AST/EmptyCollectionComparisonExpression.php +++ b/lib/Doctrine/ORM/Query/AST/EmptyCollectionComparisonExpression.php @@ -1,35 +1,45 @@ . + */ + namespace Doctrine\ORM\Query\AST; /** * EmptyCollectionComparisonExpression ::= CollectionValuedPathExpression "IS" ["NOT"] "EMPTY" * - * @author Guilherme Blanco + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision: 3938 $ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel */ class EmptyCollectionComparisonExpression extends Node { - private $_expression; - private $_not; + public $expression; + public $not; public function __construct($expression) { - $this->_expression = $expression; - } - - public function getExpression() - { - return $this->_expression; - } - - public function setNot($bool) - { - $this->_not = $bool; - } - - public function isNot() - { - return $this->_not; + $this->expression = $expression; } public function dispatch($sqlWalker) diff --git a/lib/Doctrine/ORM/Query/AST/ExistsExpression.php b/lib/Doctrine/ORM/Query/AST/ExistsExpression.php index 6b4374b5c..3d9ad2057 100644 --- a/lib/Doctrine/ORM/Query/AST/ExistsExpression.php +++ b/lib/Doctrine/ORM/Query/AST/ExistsExpression.php @@ -1,7 +1,22 @@ . */ namespace Doctrine\ORM\Query\AST; @@ -9,31 +24,22 @@ namespace Doctrine\ORM\Query\AST; /** * ExistsExpression ::= ["NOT"] "EXISTS" "(" Subselect ")" * - * @author robo + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision: 3938 $ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel */ class ExistsExpression extends Node { - private $_not = false; - private $_subselect; + public $not; + public $subselect; public function __construct($subselect) { - $this->_subselect = $subselect; - } - - public function setNot($bool) - { - $this->_not = $bool; - } - - public function isNot() - { - return $this->_not; - } - - public function getSubselect() - { - return $this->_subselect; + $this->subselect = $subselect; } public function dispatch($sqlWalker) diff --git a/lib/Doctrine/ORM/Query/AST/FromClause.php b/lib/Doctrine/ORM/Query/AST/FromClause.php index 10cb58216..5325ea795 100644 --- a/lib/Doctrine/ORM/Query/AST/FromClause.php +++ b/lib/Doctrine/ORM/Query/AST/FromClause.php @@ -16,7 +16,7 @@ * * This software consists of voluntary contributions made by many individuals * and is licensed under the LGPL. For more information, see - * . + * . */ namespace Doctrine\ORM\Query\AST; @@ -24,27 +24,23 @@ namespace Doctrine\ORM\Query\AST; /** * FromClause ::= "FROM" IdentificationVariableDeclaration {"," IdentificationVariableDeclaration} * - * @author Guilherme Blanco - * @license http://www.opensource.org/licenses/lgpl-license.php LGPL - * @link http://www.phpdoctrine.org - * @since 2.0 - * @version $Revision$ + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision: 3938 $ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel */ class FromClause extends Node { - protected $_identificationVariableDeclarations = array(); + public $identificationVariableDeclarations = array(); public function __construct(array $identificationVariableDeclarations) { - $this->_identificationVariableDeclarations = $identificationVariableDeclarations; + $this->identificationVariableDeclarations = $identificationVariableDeclarations; } - /* Getters */ - public function getIdentificationVariableDeclarations() - { - return $this->_identificationVariableDeclarations; - } - public function dispatch($sqlWalker) { return $sqlWalker->walkFromClause($this); diff --git a/lib/Doctrine/ORM/Query/AST/Functions/AbsFunction.php b/lib/Doctrine/ORM/Query/AST/Functions/AbsFunction.php index 7b36b0b2e..862eb0737 100644 --- a/lib/Doctrine/ORM/Query/AST/Functions/AbsFunction.php +++ b/lib/Doctrine/ORM/Query/AST/Functions/AbsFunction.php @@ -1,7 +1,22 @@ . */ namespace Doctrine\ORM\Query\AST\Functions; @@ -9,24 +24,26 @@ namespace Doctrine\ORM\Query\AST\Functions; /** * "ABS" "(" SimpleArithmeticExpression ")" * - * @author Roman Borschel + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision: 3938 $ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel */ class AbsFunction extends FunctionNode { - private $_simpleArithmeticExpression; - - public function getSimpleArithmeticExpression() - { - return $this->_simpleArithmeticExpression; - } + public $simpleArithmeticExpression; /** * @override */ public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker) { - //TODO: Use platform to get SQL - return 'ABS(' . $sqlWalker->walkSimpleArithmeticExpression($this->_simpleArithmeticExpression) . ')'; + return 'ABS(' . $sqlWalker->walkSimpleArithmeticExpression( + $this->simpleArithmeticExpression + ) . ')'; } /** @@ -37,7 +54,7 @@ class AbsFunction extends FunctionNode $lexer = $parser->getLexer(); $parser->match($lexer->lookahead['value']); $parser->match('('); - $this->_simpleArithmeticExpression = $parser->SimpleArithmeticExpression(); + $this->simpleArithmeticExpression = $parser->SimpleArithmeticExpression(); $parser->match(')'); } } diff --git a/lib/Doctrine/ORM/Query/AST/Functions/ConcatFunction.php b/lib/Doctrine/ORM/Query/AST/Functions/ConcatFunction.php index a6918cddb..48261ecab 100644 --- a/lib/Doctrine/ORM/Query/AST/Functions/ConcatFunction.php +++ b/lib/Doctrine/ORM/Query/AST/Functions/ConcatFunction.php @@ -1,7 +1,22 @@ . */ namespace Doctrine\ORM\Query\AST\Functions; @@ -9,22 +24,18 @@ namespace Doctrine\ORM\Query\AST\Functions; /** * "CONCAT" "(" StringPrimary "," StringPrimary ")" * - * @author Roman Borschel + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision: 3938 $ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel */ class ConcatFunction extends FunctionNode { - private $_firstStringPrimary; - private $_secondStringPriamry; - - public function getFirstStringPrimary() - { - return $this->_firstStringPrimary; - } - - public function getSecondStringPrimary() - { - return $this->_secondStringPrimary; - } + public $firstStringPrimary; + public $secondStringPriamry; /** * @override @@ -33,8 +44,8 @@ class ConcatFunction extends FunctionNode { $platform = $sqlWalker->getConnection()->getDatabasePlatform(); return $platform->getConcatExpression( - $sqlWalker->walkStringPrimary($this->_firstStringPrimary), - $sqlWalker->walkStringPrimary($this->_secondStringPrimary) + $sqlWalker->walkStringPrimary($this->firstStringPrimary), + $sqlWalker->walkStringPrimary($this->secondStringPrimary) ); } @@ -47,9 +58,9 @@ class ConcatFunction extends FunctionNode $parser->match($lexer->lookahead['value']); $parser->match('('); - $this->_firstStringPrimary = $parser->StringPrimary(); + $this->firstStringPrimary = $parser->StringPrimary(); $parser->match(','); - $this->_secondStringPrimary = $parser->StringPrimary(); + $this->secondStringPrimary = $parser->StringPrimary(); $parser->match(')'); } diff --git a/lib/Doctrine/ORM/Query/AST/Functions/CurrentDateFunction.php b/lib/Doctrine/ORM/Query/AST/Functions/CurrentDateFunction.php index ec886e5ec..9d23a7a24 100644 --- a/lib/Doctrine/ORM/Query/AST/Functions/CurrentDateFunction.php +++ b/lib/Doctrine/ORM/Query/AST/Functions/CurrentDateFunction.php @@ -1,11 +1,36 @@ . + */ + namespace Doctrine\ORM\Query\AST\Functions; /** * "CURRENT_DATE" * - * @author robo + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision: 3938 $ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel */ class CurrentDateFunction extends FunctionNode { diff --git a/lib/Doctrine/ORM/Query/AST/Functions/CurrentTimeFunction.php b/lib/Doctrine/ORM/Query/AST/Functions/CurrentTimeFunction.php index e7a732ce2..be9b9725c 100644 --- a/lib/Doctrine/ORM/Query/AST/Functions/CurrentTimeFunction.php +++ b/lib/Doctrine/ORM/Query/AST/Functions/CurrentTimeFunction.php @@ -1,7 +1,22 @@ . */ namespace Doctrine\ORM\Query\AST\Functions; @@ -9,7 +24,13 @@ namespace Doctrine\ORM\Query\AST\Functions; /** * "CURRENT_TIME" * - * @author robo + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision: 3938 $ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel */ class CurrentTimeFunction extends FunctionNode { diff --git a/lib/Doctrine/ORM/Query/AST/Functions/FunctionNode.php b/lib/Doctrine/ORM/Query/AST/Functions/FunctionNode.php index 26801a368..825415a7f 100644 --- a/lib/Doctrine/ORM/Query/AST/Functions/FunctionNode.php +++ b/lib/Doctrine/ORM/Query/AST/Functions/FunctionNode.php @@ -24,22 +24,23 @@ namespace Doctrine\ORM\Query\AST\Functions; use Doctrine\ORM\Query\AST\Node; /** - * Description of Function + * Abtract Function Node. * - * @author robo + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision: 3938 $ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel */ abstract class FunctionNode extends Node { - private $_name; + public $name; public function __construct($name) { - $this->_name = $name; - } - - public function getName() - { - return $this->_name; + $this->name = $name; } abstract public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker); diff --git a/lib/Doctrine/ORM/Query/AST/Functions/LengthFunction.php b/lib/Doctrine/ORM/Query/AST/Functions/LengthFunction.php index f6c806de5..ba932c963 100644 --- a/lib/Doctrine/ORM/Query/AST/Functions/LengthFunction.php +++ b/lib/Doctrine/ORM/Query/AST/Functions/LengthFunction.php @@ -1,7 +1,22 @@ . */ namespace Doctrine\ORM\Query\AST\Functions; @@ -9,16 +24,17 @@ namespace Doctrine\ORM\Query\AST\Functions; /** * "LENGTH" "(" StringPrimary ")" * - * @author Roman Borschel + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision: 3938 $ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel */ class LengthFunction extends FunctionNode { - private $_stringPrimary; - - public function getStringPrimary() - { - return $this->_stringPrimary; - } + public $stringPrimary; /** * @override @@ -26,7 +42,7 @@ class LengthFunction extends FunctionNode public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker) { //TODO: Use platform to get SQL - return 'LENGTH(' . $sqlWalker->walkStringPrimary($this->_stringPrimary) . ')'; + return 'LENGTH(' . $sqlWalker->walkStringPrimary($this->stringPrimary) . ')'; } /** @@ -35,9 +51,12 @@ class LengthFunction extends FunctionNode public function parse(\Doctrine\ORM\Query\Parser $parser) { $lexer = $parser->getLexer(); + $parser->match($lexer->lookahead['value']); $parser->match('('); - $this->_stringPrimary = $parser->StringPrimary(); + + $this->stringPrimary = $parser->StringPrimary(); + $parser->match(')'); } } diff --git a/lib/Doctrine/ORM/Query/AST/Functions/LocateFunction.php b/lib/Doctrine/ORM/Query/AST/Functions/LocateFunction.php index 1b53acfef..dcc5c5229 100644 --- a/lib/Doctrine/ORM/Query/AST/Functions/LocateFunction.php +++ b/lib/Doctrine/ORM/Query/AST/Functions/LocateFunction.php @@ -1,7 +1,22 @@ . */ namespace Doctrine\ORM\Query\AST\Functions; @@ -9,28 +24,19 @@ namespace Doctrine\ORM\Query\AST\Functions; /** * "LOCATE" "(" StringPrimary "," StringPrimary ["," SimpleArithmeticExpression]")" * - * @author robo + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision: 3938 $ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel */ class LocateFunction extends FunctionNode { - private $_firstStringPrimary; - private $_secondStringPrimary; - private $_simpleArithmeticExpression; - - public function getFirstStringPrimary() - { - return $this->_firstStringPrimary; - } - - public function getSecondStringPrimary() - { - return $this->_secondStringPrimary; - } - - public function getSimpleArithmeticExpression() - { - return $this->_simpleArithmeticExpression; - } + public $firstStringPrimary; + public $secondStringPrimary; + public $simpleArithmeticExpression; /** * @override @@ -38,15 +44,12 @@ class LocateFunction extends FunctionNode public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker) { //TODO: Use platform to get SQL - $sql = 'LOCATE(' . - $sqlWalker->walkStringPrimary($this->_firstStringPrimary) - . ', ' . - $sqlWalker->walkStringPrimary($this->_secondStringPrimary); - - if ($this->_simpleArithmeticExpression) { - $sql .= ', ' . $sqlWalker->walkSimpleArithmeticExpression($this->_simpleArithmeticExpression); - } - return $sql . ')'; + return 'LOCATE(' . $sqlWalker->walkStringPrimary($this->firstStringPrimary) . ', ' + . $sqlWalker->walkStringPrimary($this->secondStringPrimary) + . (($this->simpleArithmeticExpression) + ? ', ' . $sqlWalker->walkSimpleArithmeticExpression($this->simpleArithmeticExpression) + : '' + ) . ')'; } /** @@ -55,15 +58,22 @@ class LocateFunction extends FunctionNode public function parse(\Doctrine\ORM\Query\Parser $parser) { $lexer = $parser->getLexer(); + $parser->match($lexer->lookahead['value']); $parser->match('('); - $this->_firstStringPrimary = $parser->StringPrimary(); + + $this->firstStringPrimary = $parser->StringPrimary(); + $parser->match(','); - $this->_secondStringPrimary = $parser->StringPrimary(); + + $this->secondStringPrimary = $parser->StringPrimary(); + if ($lexer->isNextToken(',')) { $parser->match(','); - $this->_simpleArithmeticExpression = $parser->SimpleArithmeticExpression(); + + $this->simpleArithmeticExpression = $parser->SimpleArithmeticExpression(); } + $parser->match(')'); } } diff --git a/lib/Doctrine/ORM/Query/AST/Functions/LowerFunction.php b/lib/Doctrine/ORM/Query/AST/Functions/LowerFunction.php index 6b47704db..77db9959b 100644 --- a/lib/Doctrine/ORM/Query/AST/Functions/LowerFunction.php +++ b/lib/Doctrine/ORM/Query/AST/Functions/LowerFunction.php @@ -1,7 +1,22 @@ . */ namespace Doctrine\ORM\Query\AST\Functions; @@ -9,16 +24,17 @@ namespace Doctrine\ORM\Query\AST\Functions; /** * "LOWER" "(" StringPrimary ")" * - * @author robo + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision: 3938 $ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel */ class LowerFunction extends FunctionNode { - private $_stringPrimary; - - public function getStringPrimary() - { - return $this->_stringPrimary; - } + public $stringPrimary; /** * @override @@ -26,7 +42,7 @@ class LowerFunction extends FunctionNode public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker) { //TODO: Use platform to get SQL - return 'LOWER(' . $sqlWalker->walkStringPrimary($this->_stringPrimary) . ')'; + return 'LOWER(' . $sqlWalker->walkStringPrimary($this->stringPrimary) . ')'; } /** @@ -35,9 +51,12 @@ class LowerFunction extends FunctionNode public function parse(\Doctrine\ORM\Query\Parser $parser) { $lexer = $parser->getLexer(); + $parser->match($lexer->lookahead['value']); $parser->match('('); - $this->_stringPrimary = $parser->StringPrimary(); + + $this->stringPrimary = $parser->StringPrimary(); + $parser->match(')'); } } diff --git a/lib/Doctrine/ORM/Query/AST/Functions/ModFunction.php b/lib/Doctrine/ORM/Query/AST/Functions/ModFunction.php index 8a9f565fa..7b60f013f 100644 --- a/lib/Doctrine/ORM/Query/AST/Functions/ModFunction.php +++ b/lib/Doctrine/ORM/Query/AST/Functions/ModFunction.php @@ -1,7 +1,22 @@ . */ namespace Doctrine\ORM\Query\AST\Functions; @@ -9,22 +24,18 @@ namespace Doctrine\ORM\Query\AST\Functions; /** * "MOD" "(" SimpleArithmeticExpression "," SimpleArithmeticExpression ")" * - * @author robo + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision: 3938 $ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel */ class ModFunction extends FunctionNode { - private $_firstSimpleArithmeticExpression; - private $_secondSimpleArithmeticExpression; - - public function getFirstSimpleArithmeticExpression() - { - return $this->_firstSimpleArithmeticExpression; - } - - public function getSecondSimpleArithmeticExpression() - { - return $this->_secondSimpleArithmeticExpression; - } + public $firstSimpleArithmeticExpression; + public $secondSimpleArithmeticExpression; /** * @override @@ -32,11 +43,11 @@ class ModFunction extends FunctionNode public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker) { //TODO: Use platform to get SQL - return 'SQRT(' . - $sqlWalker->walkSimpleArithmeticExpression($this->_firstSimpleArithmeticExpression) - . ', ' . - $sqlWalker->walkSimpleArithmeticExpression($this->_secondSimpleArithmeticExpression) - . ')'; + return 'SQRT(' + . $sqlWalker->walkSimpleArithmeticExpression($this->_firstSimpleArithmeticExpression) + . ', ' + . $sqlWalker->walkSimpleArithmeticExpression($this->_secondSimpleArithmeticExpression) + . ')'; } /** @@ -45,11 +56,16 @@ class ModFunction extends FunctionNode public function parse(\Doctrine\ORM\Query\Parser $parser) { $lexer = $parser->getLexer(); + $parser->match($lexer->lookahead['value']); $parser->match('('); - $this->_firstSimpleArithmeticExpression = $parser->SimpleArithmeticExpression(); + + $this->firstSimpleArithmeticExpression = $parser->SimpleArithmeticExpression(); + $parser->match(','); - $this->_secondSimpleArithmeticExpression = $parser->SimpleArithmeticExpression(); + + $this->secondSimpleArithmeticExpression = $parser->SimpleArithmeticExpression(); + $parser->match(')'); } } diff --git a/lib/Doctrine/ORM/Query/AST/Functions/SizeFunction.php b/lib/Doctrine/ORM/Query/AST/Functions/SizeFunction.php index 9da4c4c4b..13603822b 100644 --- a/lib/Doctrine/ORM/Query/AST/Functions/SizeFunction.php +++ b/lib/Doctrine/ORM/Query/AST/Functions/SizeFunction.php @@ -24,30 +24,26 @@ namespace Doctrine\ORM\Query\AST\Functions; /** * "SIZE" "(" CollectionValuedPathExpression ")" * - * @author Roman Borschel + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision: 3938 $ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel */ class SizeFunction extends FunctionNode { - private $_collectionPathExpression; - - public function getCollectionPathExpression() - { - return $this->_collectionPathExpression; - } - - public function setCollectionPathExpression($collPathExpr) - { - $this->_collectionPathExpression = $collPathExpr; - } + public $collectionPathExpression; /** * @override */ public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker) { - $dqlAlias = $this->_collectionPathExpression->getIdentificationVariable(); + $dqlAlias = $this->collectionPathExpression->identificationVariable; $qComp = $sqlWalker->getQueryComponent($dqlAlias); - $parts = $this->_collectionPathExpression->getParts(); + $parts = $this->collectionPathExpression->parts; $assoc = $qComp['metadata']->associationMappings[$parts[0]]; @@ -80,9 +76,12 @@ class SizeFunction extends FunctionNode public function parse(\Doctrine\ORM\Query\Parser $parser) { $lexer = $parser->getLexer(); + $parser->match($lexer->lookahead['value']); $parser->match('('); - $this->_collectionPathExpression = $parser->CollectionValuedPathExpression(); + + $this->collectionPathExpression = $parser->CollectionValuedPathExpression(); + $parser->match(')'); } } diff --git a/lib/Doctrine/ORM/Query/AST/Functions/SqrtFunction.php b/lib/Doctrine/ORM/Query/AST/Functions/SqrtFunction.php index a2614fab4..4ddb8a1cd 100644 --- a/lib/Doctrine/ORM/Query/AST/Functions/SqrtFunction.php +++ b/lib/Doctrine/ORM/Query/AST/Functions/SqrtFunction.php @@ -1,7 +1,22 @@ . */ namespace Doctrine\ORM\Query\AST\Functions; @@ -9,16 +24,17 @@ namespace Doctrine\ORM\Query\AST\Functions; /** * "SQRT" "(" SimpleArithmeticExpression ")" * - * @author Roman Borschel + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision: 3938 $ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel */ class SqrtFunction extends FunctionNode { - private $_simpleArithmeticExpression; - - public function getSimpleArithmeticExpression() - { - return $this->_simpleArithmeticExpression; - } + public $simpleArithmeticExpression; /** * @override @@ -26,7 +42,7 @@ class SqrtFunction extends FunctionNode public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker) { //TODO: Use platform to get SQL - return 'SQRT(' . $sqlWalker->walkSimpleArithmeticExpression($this->_simpleArithmeticExpression) . ')'; + return 'SQRT(' . $sqlWalker->walkSimpleArithmeticExpression($this->simpleArithmeticExpression) . ')'; } /** @@ -35,9 +51,12 @@ class SqrtFunction extends FunctionNode public function parse(\Doctrine\ORM\Query\Parser $parser) { $lexer = $parser->getLexer(); + $parser->match($lexer->lookahead['value']); $parser->match('('); - $this->_simpleArithmeticExpression = $parser->SimpleArithmeticExpression(); + + $this->simpleArithmeticExpression = $parser->SimpleArithmeticExpression(); + $parser->match(')'); } } diff --git a/lib/Doctrine/ORM/Query/AST/Functions/SubstringFunction.php b/lib/Doctrine/ORM/Query/AST/Functions/SubstringFunction.php index 97d5d7312..903076504 100644 --- a/lib/Doctrine/ORM/Query/AST/Functions/SubstringFunction.php +++ b/lib/Doctrine/ORM/Query/AST/Functions/SubstringFunction.php @@ -1,7 +1,22 @@ . */ namespace Doctrine\ORM\Query\AST\Functions; @@ -9,28 +24,19 @@ namespace Doctrine\ORM\Query\AST\Functions; /** * "SUBSTRING" "(" StringPrimary "," SimpleArithmeticExpression "," SimpleArithmeticExpression ")" * - * @author robo + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision: 3938 $ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel */ class SubstringFunction extends FunctionNode { - private $_stringPrimary; - private $_firstSimpleArithmeticExpression; - private $_secondSimpleArithmeticExpression; - - public function geStringPrimary() - { - return $this->_stringPrimary; - } - - public function getSecondSimpleArithmeticExpression() - { - return $this->_secondSimpleArithmeticExpression; - } - - public function getFirstSimpleArithmeticExpression() - { - return $this->_firstSimpleArithmeticExpression; - } + public $stringPrimary; + public $firstSimpleArithmeticExpression; + public $secondSimpleArithmeticExpression; /** * @override @@ -38,14 +44,13 @@ class SubstringFunction extends FunctionNode public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker) { //TODO: Use platform to get SQL - $sql = 'SUBSTRING(' . - $sqlWalker->walkStringPrimary($this->_stringPrimary) - . ', ' . - $sqlWalker->walkSimpleArithmeticExpression($this->_firstSimpleArithmeticExpression) - . ', ' . - $sqlWalker->walkSimpleArithmeticExpression($this->_secondSimpleArithmeticExpression) - . ')'; - return $sql; + return 'SUBSTRING(' + . $sqlWalker->walkStringPrimary($this->stringPrimary) + . ', ' + . $sqlWalker->walkSimpleArithmeticExpression($this->firstSimpleArithmeticExpression) + . ', ' + . $sqlWalker->walkSimpleArithmeticExpression($this->secondSimpleArithmeticExpression) + . ')'; } /** @@ -54,14 +59,18 @@ class SubstringFunction extends FunctionNode public function parse(\Doctrine\ORM\Query\Parser $parser) { $lexer = $parser->getLexer(); + $parser->match($lexer->lookahead['value']); $parser->match('('); - $this->_stringPrimary = $parser->StringPrimary(); + $this->stringPrimary = $parser->StringPrimary(); + $parser->match(','); - $this->_firstSimpleArithmeticExpression = $parser->SimpleArithmeticExpression(); + + $this->firstSimpleArithmeticExpression = $parser->SimpleArithmeticExpression(); $parser->match(','); - $this->_secondSimpleArithmeticExpression = $parser->SimpleArithmeticExpression(); + + $this->secondSimpleArithmeticExpression = $parser->SimpleArithmeticExpression(); $parser->match(')'); } diff --git a/lib/Doctrine/ORM/Query/AST/Functions/TrimFunction.php b/lib/Doctrine/ORM/Query/AST/Functions/TrimFunction.php index e003a74fa..16d3c6d1c 100644 --- a/lib/Doctrine/ORM/Query/AST/Functions/TrimFunction.php +++ b/lib/Doctrine/ORM/Query/AST/Functions/TrimFunction.php @@ -1,7 +1,22 @@ . */ namespace Doctrine\ORM\Query\AST\Functions; @@ -11,60 +26,21 @@ use Doctrine\ORM\Query\Lexer; /** * "TRIM" "(" [["LEADING" | "TRAILING" | "BOTH"] [char] "FROM"] StringPrimary ")" * - * @author robo + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision: 3938 $ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel */ class TrimFunction extends FunctionNode { - private $_leading; - private $_trailing; - private $_both; - private $_trimChar; - private $_stringPrimary; - - public function getStringPrimary() - { - return $this->_stringPrimary; - } - - public function isLeading() - { - return $this->_leading; - } - - public function setLeading($bool) - { - $this->_leading = $bool; - } - - public function isTrailing() - { - return $this->_trailing; - } - - public function setTrailing($bool) - { - $this->_trailing = $bool; - } - - public function isBoth() - { - return $this->_both; - } - - public function setBoth($bool) - { - $this->_both = $bool; - } - - public function getTrimChar() - { - return $this->_trimChar; - } - - public function setTrimChar($trimChar) - { - $this->_trimChar = $trimChar; - } + public $leading; + public $trailing; + public $both; + public $trimChar; + public $stringPrimary; /** * @override @@ -72,13 +48,20 @@ class TrimFunction extends FunctionNode public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker) { $sql = 'TRIM('; - if ($this->_leading) $sql .= 'LEADING '; - else if ($this->_trailing) $sql .= 'TRAILING '; - else if ($this->_both) $sql .= 'BOTH '; - if ($this->_trimChar) $sql .= $sqlWalker->getConnection()->quote($this->_trimChar) . ' '; - $sql .= 'FROM ' . $sqlWalker->walkStringPrimary($this->_stringPrimary); - $sql .= ')'; - return $sql; + + if ($this->leading) { + $sql .= 'LEADING '; + } else if ($this->trailing) { + $sql .= 'TRAILING '; + } else if ($this->both) { + $sql .= 'BOTH '; + } + + if ($this->trimChar) { + $sql .= $sqlWalker->getConnection()->quote($this->trimChar) . ' '; + } + + return $sql . 'FROM ' . $sqlWalker->walkStringPrimary($this->stringPrimary) . ')'; } /** @@ -87,30 +70,31 @@ class TrimFunction extends FunctionNode public function parse(\Doctrine\ORM\Query\Parser $parser) { $lexer = $parser->getLexer(); + $parser->match($lexer->lookahead['value']); $parser->match('('); if (strcasecmp('leading', $lexer->lookahead['value']) === 0) { $parser->match($lexer->lookahead['value']); - $this->_leading = true; + $this->leading = true; } else if (strcasecmp('trailing', $lexer->lookahead['value']) === 0) { $parser->match($lexer->lookahead['value']); - $this->_trailing = true; + $this->trailing = true; } else if (strcasecmp('both', $lexer->lookahead['value']) === 0) { $parser->match($lexer->lookahead['value']); - $this->_both = true; + $this->both = true; } if ($lexer->isNextToken(Lexer::T_STRING)) { $parser->match(Lexer::T_STRING); - $this->_trimChar = $lexer->token['value']; + $this->trimChar = $lexer->token['value']; } - if ($this->_leading || $this->_trailing || $this->_both || $this->_trimChar) { + if ($this->leading || $this->trailing || $this->both || $this->trimChar) { $parser->match(Lexer::T_FROM); } - $this->_stringPrimary = $parser->StringPrimary(); + $this->stringPrimary = $parser->StringPrimary(); $parser->match(')'); } diff --git a/lib/Doctrine/ORM/Query/AST/Functions/UpperFunction.php b/lib/Doctrine/ORM/Query/AST/Functions/UpperFunction.php index 8cf66b6a5..f91a36259 100644 --- a/lib/Doctrine/ORM/Query/AST/Functions/UpperFunction.php +++ b/lib/Doctrine/ORM/Query/AST/Functions/UpperFunction.php @@ -1,7 +1,22 @@ . */ namespace Doctrine\ORM\Query\AST\Functions; @@ -9,16 +24,17 @@ namespace Doctrine\ORM\Query\AST\Functions; /** * "UPPER" "(" StringPrimary ")" * - * @author robo + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision: 3938 $ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel */ class UpperFunction extends FunctionNode { - private $_stringPrimary; - - public function getStringPrimary() - { - return $this->_stringPrimary; - } + public $stringPrimary; /** * @override @@ -26,7 +42,7 @@ class UpperFunction extends FunctionNode public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker) { //TODO: Use platform to get SQL - return 'UPPER(' . $sqlWalker->walkStringPrimary($this->_stringPrimary) . ')'; + return 'UPPER(' . $sqlWalker->walkStringPrimary($this->stringPrimary) . ')'; } /** @@ -35,9 +51,12 @@ class UpperFunction extends FunctionNode public function parse(\Doctrine\ORM\Query\Parser $parser) { $lexer = $parser->getLexer(); + $parser->match($lexer->lookahead['value']); $parser->match('('); - $this->_stringPrimary = $parser->StringPrimary(); + + $this->stringPrimary = $parser->StringPrimary(); + $parser->match(')'); } } diff --git a/lib/Doctrine/ORM/Query/AST/GroupByClause.php b/lib/Doctrine/ORM/Query/AST/GroupByClause.php index 58e7d0db3..d5ae72fcd 100644 --- a/lib/Doctrine/ORM/Query/AST/GroupByClause.php +++ b/lib/Doctrine/ORM/Query/AST/GroupByClause.php @@ -1,7 +1,22 @@ . */ namespace Doctrine\ORM\Query\AST; @@ -9,20 +24,21 @@ namespace Doctrine\ORM\Query\AST; /** * Description of GroupByClause * - * @author robo + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision: 3938 $ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel */ class GroupByClause extends Node { - private $_groupByItems = array(); + public $groupByItems = array(); public function __construct(array $groupByItems) { - $this->_groupByItems = $groupByItems; - } - - public function getGroupByItems() - { - return $this->_groupByItems; + $this->groupByItems = $groupByItems; } public function dispatch($sqlWalker) diff --git a/lib/Doctrine/ORM/Query/AST/HavingClause.php b/lib/Doctrine/ORM/Query/AST/HavingClause.php index aaf74b4c8..08912b0b4 100644 --- a/lib/Doctrine/ORM/Query/AST/HavingClause.php +++ b/lib/Doctrine/ORM/Query/AST/HavingClause.php @@ -1,7 +1,22 @@ . */ namespace Doctrine\ORM\Query\AST; @@ -9,20 +24,21 @@ namespace Doctrine\ORM\Query\AST; /** * Description of HavingClause * - * @author robo + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision: 3938 $ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel */ class HavingClause extends Node { - private $_conditionalExpression; + public $conditionalExpression; public function __construct($conditionalExpression) { - $this->_conditionalExpression = $conditionalExpression; - } - - public function getConditionalExpression() - { - return $this->_conditionalExpression; + $this->conditionalExpression = $conditionalExpression; } public function dispatch($sqlWalker) diff --git a/lib/Doctrine/ORM/Query/AST/IdentificationVariableDeclaration.php b/lib/Doctrine/ORM/Query/AST/IdentificationVariableDeclaration.php index e829a52b0..bf168c34b 100644 --- a/lib/Doctrine/ORM/Query/AST/IdentificationVariableDeclaration.php +++ b/lib/Doctrine/ORM/Query/AST/IdentificationVariableDeclaration.php @@ -24,45 +24,27 @@ namespace Doctrine\ORM\Query\AST; /** * IdentificationVariableDeclaration ::= RangeVariableDeclaration [IndexBy] {JoinVariableDeclaration}* * - * @author Guilherme Blanco - * @license http://www.opensource.org/licenses/lgpl-license.php LGPL - * @link http://www.doctrine-project.org - * @since 2.0 - * @version $Revision$ + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision: 3938 $ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel */ class IdentificationVariableDeclaration extends Node { - protected $_rangeVariableDeclaration = null; - - protected $_indexBy = null; - - protected $_joinVariableDeclarations = array(); + public $rangeVariableDeclaration = null; + public $indexBy = null; + public $joinVariableDeclarations = array(); public function __construct($rangeVariableDecl, $indexBy, array $joinVariableDecls) { - $this->_rangeVariableDeclaration = $rangeVariableDecl; - $this->_indexBy = $indexBy; - $this->_joinVariableDeclarations = $joinVariableDecls; + $this->rangeVariableDeclaration = $rangeVariableDecl; + $this->indexBy = $indexBy; + $this->joinVariableDeclarations = $joinVariableDecls; } - /* Getters */ - public function getRangeVariableDeclaration() - { - return $this->_rangeVariableDeclaration; - } - - - public function getIndexBy() - { - return $this->_indexBy; - } - - - public function getJoinVariableDeclarations() - { - return $this->_joinVariableDeclarations; - } - public function dispatch($sqlWalker) { return $sqlWalker->walkIdentificationVariableDeclaration($this); diff --git a/lib/Doctrine/ORM/Query/AST/InExpression.php b/lib/Doctrine/ORM/Query/AST/InExpression.php index 6654791f6..b1da40156 100644 --- a/lib/Doctrine/ORM/Query/AST/InExpression.php +++ b/lib/Doctrine/ORM/Query/AST/InExpression.php @@ -1,7 +1,22 @@ . */ namespace Doctrine\ORM\Query\AST; @@ -9,53 +24,24 @@ namespace Doctrine\ORM\Query\AST; /** * InExpression ::= StateFieldPathExpression ["NOT"] "IN" "(" (Literal {"," Literal}* | Subselect) ")" * - * @author robo + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision: 3938 $ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel */ class InExpression extends Node { - private $_pathExpression; - private $_not = false; - private $_literals = array(); - private $_subselect; + public $not; + public $pathExpression; + public $literals = array(); + public $subselect; public function __construct($pathExpression) { - $this->_pathExpression = $pathExpression; - } - - public function setLiterals(array $literals) - { - $this->_literals = $literals; - } - - public function getLiterals() - { - return $this->_literals; - } - - public function setSubselect($subselect) - { - $this->_subselect = $subselect; - } - - public function getSubselect() - { - return $this->_subselect; - } - - public function setNot($bool) - { - $this->_not = $bool; - } - - public function isNot() - { - return $this->_not; - } - - public function getPathExpression() - { - return $this->_pathExpression; + $this->pathExpression = $pathExpression; } public function dispatch($sqlWalker) diff --git a/lib/Doctrine/ORM/Query/AST/IndexBy.php b/lib/Doctrine/ORM/Query/AST/IndexBy.php index c2be040df..b657be70f 100644 --- a/lib/Doctrine/ORM/Query/AST/IndexBy.php +++ b/lib/Doctrine/ORM/Query/AST/IndexBy.php @@ -24,27 +24,23 @@ namespace Doctrine\ORM\Query\AST; /** * IndexBy ::= "INDEX" "BY" SimpleStateFieldPathExpression * - * @author Guilherme Blanco - * @license http://www.opensource.org/licenses/lgpl-license.php LGPL - * @link http://www.doctrine-project.org - * @since 2.0 - * @version $Revision$ + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision: 3938 $ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel */ class IndexBy extends Node { - protected $_simpleStateFieldPathExpression = null; + public $simpleStateFieldPathExpression = null; public function __construct($simpleStateFieldPathExpression) { - $this->_simpleStateFieldPathExpression = $simpleStateFieldPathExpression; + $this->simpleStateFieldPathExpression = $simpleStateFieldPathExpression; } - /* Getters */ - public function getSimpleStateFieldPathExpression() - { - return $this->_simpleStateFieldPathExpression; - } - public function dispatch($sqlWalker) { return $sqlWalker->walkIndexBy($this); diff --git a/lib/Doctrine/ORM/Query/AST/InputParameter.php b/lib/Doctrine/ORM/Query/AST/InputParameter.php index b703d304c..c750c5119 100644 --- a/lib/Doctrine/ORM/Query/AST/InputParameter.php +++ b/lib/Doctrine/ORM/Query/AST/InputParameter.php @@ -1,7 +1,22 @@ . */ namespace Doctrine\ORM\Query\AST; @@ -9,13 +24,18 @@ namespace Doctrine\ORM\Query\AST; /** * Description of InputParameter * - * @author robo + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision: 3938 $ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel */ class InputParameter extends Node { - private $_isNamed; - private $_position; - private $_name; + public $isNamed; + public $name; public function __construct($value) { @@ -24,32 +44,8 @@ class InputParameter extends Node } $param = substr($value, 1); - $this->_isNamed = ! is_numeric($param); - if ($this->_isNamed) { - $this->_name = $param; - } else { - $this->_position = $param; - } - } - - public function isNamed() - { - return $this->_isNamed; - } - - public function isPositional() - { - return ! $this->_isNamed; - } - - public function getName() - { - return $this->_name; - } - - public function getPosition() - { - return $this->_position; + $this->isNamed = ! is_numeric($param); + $this->name = $param; } public function dispatch($sqlWalker) diff --git a/lib/Doctrine/ORM/Query/AST/Join.php b/lib/Doctrine/ORM/Query/AST/Join.php index 3fab1791d..2071cd16c 100644 --- a/lib/Doctrine/ORM/Query/AST/Join.php +++ b/lib/Doctrine/ORM/Query/AST/Join.php @@ -25,11 +25,13 @@ namespace Doctrine\ORM\Query\AST; * Join ::= ["LEFT" ["OUTER"] | "INNER"] "JOIN" JoinAssociationPathExpression * ["AS"] AliasIdentificationVariable [("ON" | "WITH") ConditionalExpression] * - * @author Guilherme Blanco - * @license http://www.opensource.org/licenses/lgpl-license.php LGPL - * @link http://www.phpdoctrine.org - * @since 2.0 - * @version $Revision$ + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision: 3938 $ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel */ class Join extends Node { @@ -39,57 +41,19 @@ class Join extends Node const JOIN_WHERE_ON = 1; const JOIN_WHERE_WITH = 2; - protected $_joinType = self::JOIN_TYPE_INNER; - protected $_joinAssociationPathExpression = null; - protected $_aliasIdentificationVariable = null; - protected $_whereType = self::JOIN_WHERE_WITH; - protected $_conditionalExpression = null; + public $joinType = self::JOIN_TYPE_INNER; + public $joinAssociationPathExpression = null; + public $aliasIdentificationVariable = null; + public $whereType = self::JOIN_WHERE_WITH; + public $conditionalExpression = null; public function __construct($joinType, $joinAssocPathExpr, $aliasIdentVar) { - $this->_joinType = $joinType; - $this->_joinAssociationPathExpression = $joinAssocPathExpr; - $this->_aliasIdentificationVariable = $aliasIdentVar; + $this->joinType = $joinType; + $this->joinAssociationPathExpression = $joinAssocPathExpr; + $this->aliasIdentificationVariable = $aliasIdentVar; } - /* Setters */ - - public function setWhereType($whereType) - { - $this->_whereType = $whereType; - } - - public function setConditionalExpression($conditionalExpression) - { - $this->_conditionalExpression = $conditionalExpression; - } - - /* Getters */ - public function getJoinType() - { - return $this->_joinType; - } - - public function getJoinAssociationPathExpression() - { - return $this->_joinAssociationPathExpression; - } - - public function getAliasIdentificationVariable() - { - return $this->_aliasIdentificationVariable; - } - - public function getWhereType() - { - return $this->_whereType; - } - - public function getConditionalExpression() - { - return $this->_conditionalExpression; - } - public function dispatch($sqlWalker) { return $sqlWalker->walkJoin($this); diff --git a/lib/Doctrine/ORM/Query/AST/JoinAssociationPathExpression.php b/lib/Doctrine/ORM/Query/AST/JoinAssociationPathExpression.php index 7aab445a3..7f87e52f8 100644 --- a/lib/Doctrine/ORM/Query/AST/JoinAssociationPathExpression.php +++ b/lib/Doctrine/ORM/Query/AST/JoinAssociationPathExpression.php @@ -1,32 +1,46 @@ . + */ + namespace Doctrine\ORM\Query\AST; /** * JoinAssociationPathExpression ::= IdentificationVariable "." (SingleValuedAssociationField | CollectionValuedAssociationField) * - * @author Guilherme Blanco - * @author Roman Borschel + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision: 3938 $ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel */ class JoinAssociationPathExpression extends Node { - private $_identificationVariable; - private $_assocField; + public $identificationVariable; + public $associationField; - public function __construct($identificationVariable, $assocField) + public function __construct($identificationVariable, $associationField) { - $this->_identificationVariable = $identificationVariable; - $this->_assocField = $assocField; - } - - public function getIdentificationVariable() - { - return $this->_identificationVariable; - } - - public function getAssociationField() - { - return $this->_assocField; + $this->identificationVariable = $identificationVariable; + $this->associationField = $associationField; } public function dispatch($sqlWalker) diff --git a/lib/Doctrine/ORM/Query/AST/JoinVariableDeclaration.php b/lib/Doctrine/ORM/Query/AST/JoinVariableDeclaration.php index 7d2bf9d29..687eba38d 100644 --- a/lib/Doctrine/ORM/Query/AST/JoinVariableDeclaration.php +++ b/lib/Doctrine/ORM/Query/AST/JoinVariableDeclaration.php @@ -24,34 +24,25 @@ namespace Doctrine\ORM\Query\AST; /** * JoinVariableDeclaration ::= Join [IndexBy] * - * @author Guilherme Blanco - * @license http://www.opensource.org/licenses/lgpl-license.php LGPL - * @link http://www.phpdoctrine.org - * @since 2.0 - * @version $Revision$ + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision: 3938 $ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel */ class JoinVariableDeclaration extends Node { - protected $_join = null; - protected $_indexBy = null; + public $join = null; + public $indexBy = null; public function __construct($join, $indexBy) { - $this->_join = $join; - $this->_indexBy = $indexBy; + $this->join = $join; + $this->indexBy = $indexBy; } - /* Getters */ - public function getJoin() - { - return $this->_join; - } - - public function getIndexBy() - { - return $this->_indexBy; - } - public function dispatch($sqlWalker) { return $sqlWalker->walkJoinVariableDeclaration($this); diff --git a/lib/Doctrine/ORM/Query/AST/LikeExpression.php b/lib/Doctrine/ORM/Query/AST/LikeExpression.php index e87d5f437..7985be437 100644 --- a/lib/Doctrine/ORM/Query/AST/LikeExpression.php +++ b/lib/Doctrine/ORM/Query/AST/LikeExpression.php @@ -1,7 +1,22 @@ . */ namespace Doctrine\ORM\Query\AST; @@ -9,41 +24,26 @@ namespace Doctrine\ORM\Query\AST; /** * LikeExpression ::= StringExpression ["NOT"] "LIKE" string ["ESCAPE" char] * - * @author robo + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision: 3938 $ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel */ class LikeExpression extends Node { - private $_stringExpr; - private $_isNot; - private $_stringPattern; - private $_escapeChar; + public $not; + public $stringExpression; + public $stringPattern; + public $escapeChar; - public function __construct($stringExpr, $stringPattern, $isNot = false, $escapeChar = null) + public function __construct($stringExpression, $stringPattern, $escapeChar = null) { - $this->_stringExpr = $stringExpr; - $this->_stringPattern = $stringPattern; - $this->_isNot = $isNot; - $this->_escapeChar = $escapeChar; - } - - public function isNot() - { - return $this->_isNot; - } - - public function getStringExpression() - { - return $this->_stringExpr; - } - - public function getStringPattern() - { - return $this->_stringPattern; - } - - public function getEscapeChar() - { - return $this->_escapeChar; + $this->stringExpression = $stringExpression; + $this->stringPattern = $stringPattern; + $this->escapeChar = $escapeChar; } public function dispatch($sqlWalker) diff --git a/lib/Doctrine/ORM/Query/AST/Node.php b/lib/Doctrine/ORM/Query/AST/Node.php index 8d5777787..dec961977 100644 --- a/lib/Doctrine/ORM/Query/AST/Node.php +++ b/lib/Doctrine/ORM/Query/AST/Node.php @@ -24,13 +24,13 @@ namespace Doctrine\ORM\Query\AST; /** * Abstract class of an AST node * - * @author Guilherme Blanco - * @author Janne Vanhala - * @author Roman Borschel - * @license http://www.opensource.org/licenses/lgpl-license.php LGPL - * @link http://www.doctrine-project.org - * @since 2.0 - * @version $Revision$ + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision: 3938 $ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel */ abstract class Node { diff --git a/lib/Doctrine/ORM/Query/AST/NullComparisonExpression.php b/lib/Doctrine/ORM/Query/AST/NullComparisonExpression.php index ffac4ba61..aa205b712 100644 --- a/lib/Doctrine/ORM/Query/AST/NullComparisonExpression.php +++ b/lib/Doctrine/ORM/Query/AST/NullComparisonExpression.php @@ -1,7 +1,22 @@ . */ namespace Doctrine\ORM\Query\AST; @@ -9,31 +24,22 @@ namespace Doctrine\ORM\Query\AST; /** * NullComparisonExpression ::= (SingleValuedPathExpression | InputParameter) "IS" ["NOT"] "NULL" * - * @author robo + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision: 3938 $ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel */ class NullComparisonExpression extends Node { - private $_expression; - private $_not; - + public $not; + public $expression; + public function __construct($expression) { - $this->_expression = $expression; - } - - public function getExpression() - { - return $this->_expression; - } - - public function setNot($bool) - { - $this->_not = $bool; - } - - public function isNot() - { - return $this->_not; + $this->expression = $expression; } public function dispatch($sqlWalker) diff --git a/lib/Doctrine/ORM/Query/AST/OrderByClause.php b/lib/Doctrine/ORM/Query/AST/OrderByClause.php index b38ad7e88..7e2305906 100644 --- a/lib/Doctrine/ORM/Query/AST/OrderByClause.php +++ b/lib/Doctrine/ORM/Query/AST/OrderByClause.php @@ -1,7 +1,22 @@ . */ namespace Doctrine\ORM\Query\AST; @@ -9,20 +24,21 @@ namespace Doctrine\ORM\Query\AST; /** * OrderByClause ::= "ORDER" "BY" OrderByItem {"," OrderByItem}* * - * @author robo + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision: 3938 $ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel */ class OrderByClause extends Node { - private $_orderByItems = array(); + public $orderByItems = array(); public function __construct(array $orderByItems) { - $this->_orderByItems = $orderByItems; - } - - public function getOrderByItems() - { - return $this->_orderByItems; + $this->orderByItems = $orderByItems; } public function dispatch($sqlWalker) diff --git a/lib/Doctrine/ORM/Query/AST/OrderByItem.php b/lib/Doctrine/ORM/Query/AST/OrderByItem.php index 94ded8ad1..a05bac32b 100644 --- a/lib/Doctrine/ORM/Query/AST/OrderByItem.php +++ b/lib/Doctrine/ORM/Query/AST/OrderByItem.php @@ -22,48 +22,34 @@ namespace Doctrine\ORM\Query\AST; /** - * AST node for the following grammar rule: - * * OrderByItem ::= (ResultVariable | StateFieldPathExpression) ["ASC" | "DESC"] * - * @author Guilherme Blanco - * @author Roman Borschel - * @since 2.0 + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision: 3938 $ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel */ class OrderByItem extends Node { - private $_expr; - private $_asc; - private $_desc; - - public function __construct($expr) + public $expression; + public $type; + + public function __construct($expression) { - $this->_expr = $expr; - } - - public function getExpression() - { - return $this->_expr; - } - - public function setAsc($bool) - { - $this->_asc = $bool; + $this->expression = $expression; } public function isAsc() { - return $this->_asc; - } - - public function setDesc($bool) - { - $this->_desc = $bool; + return strtoupper($this->type) == 'ASC'; } public function isDesc() { - return $this->_desc; + return strtoupper($this->type) == 'DESC'; } public function dispatch($sqlWalker) diff --git a/lib/Doctrine/ORM/Query/AST/PathExpression.php b/lib/Doctrine/ORM/Query/AST/PathExpression.php index d7404fac1..076f4400a 100644 --- a/lib/Doctrine/ORM/Query/AST/PathExpression.php +++ b/lib/Doctrine/ORM/Query/AST/PathExpression.php @@ -1,28 +1,43 @@ . + */ + namespace Doctrine\ORM\Query\AST; /** - * AST node for the following path expressions: - * * AssociationPathExpression ::= CollectionValuedPathExpression | SingleValuedAssociationPathExpression - * * SingleValuedPathExpression ::= StateFieldPathExpression | SingleValuedAssociationPathExpression - * * StateFieldPathExpression ::= SimpleStateFieldPathExpression | SimpleStateFieldAssociationPathExpression - * * SingleValuedAssociationPathExpression ::= IdentificationVariable "." {SingleValuedAssociationField "."}* SingleValuedAssociationField - * * CollectionValuedPathExpression ::= IdentificationVariable "." {SingleValuedAssociationField "."}* CollectionValuedAssociationField - * * StateField ::= {EmbeddedClassStateField "."}* SimpleStateField - * * SimpleStateFieldPathExpression ::= IdentificationVariable "." StateField - * * SimpleStateFieldAssociationPathExpression ::= SingleValuedAssociationPathExpression "." StateField * - * @author Roman Borschel - * @since 2.0 + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision: 3938 $ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel */ class PathExpression extends Node { @@ -30,54 +45,21 @@ class PathExpression extends Node const TYPE_SINGLE_VALUED_ASSOCIATION = 4; const TYPE_STATE_FIELD = 8; - private $_type; - private $_expectedType; - private $_identificationVariable; - private $_parts; + public $type; + public $expectedType; + public $identificationVariable; + public $parts; public function __construct($expectedType, $identificationVariable, array $parts) { - $this->_expectedType = $expectedType; - $this->_identificationVariable = $identificationVariable; - $this->_parts = $parts; - } - - public function getIdentificationVariable() - { - return $this->_identificationVariable; - } - - public function getParts() - { - return $this->_parts; - } - - public function setExpectedType($type) - { - $this->_expectedType; - } - - public function getExpectedType() - { - return $this->_expectedType; - } - - /** - * INTERNAL - */ - public function setType($type) - { - $this->_type = $type; - } - - public function getType() - { - return $this->_type; + $this->expectedType = $expectedType; + $this->identificationVariable = $identificationVariable; + $this->parts = $parts; } public function dispatch($walker) { - switch ($this->_type) { + switch ($this->type) { case self::TYPE_STATE_FIELD: return $walker->walkStateFieldPathExpression($this); case self::TYPE_SINGLE_VALUED_ASSOCIATION: diff --git a/lib/Doctrine/ORM/Query/AST/QuantifiedExpression.php b/lib/Doctrine/ORM/Query/AST/QuantifiedExpression.php index 0c5a3a2ff..b26e2c4f1 100644 --- a/lib/Doctrine/ORM/Query/AST/QuantifiedExpression.php +++ b/lib/Doctrine/ORM/Query/AST/QuantifiedExpression.php @@ -1,7 +1,22 @@ . */ namespace Doctrine\ORM\Query\AST; @@ -9,18 +24,22 @@ namespace Doctrine\ORM\Query\AST; /** * QuantifiedExpression ::= ("ALL" | "ANY" | "SOME") "(" Subselect ")" * - * @author robo + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision: 3938 $ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel */ class QuantifiedExpression extends Node { - private $_all; - private $_any; - private $_some; - private $_subselect; + public $type; + public $subselect; public function __construct($subselect) { - $this->_subselect = $subselect; + $this->subselect = $subselect; } public function getSubselect() @@ -30,32 +49,17 @@ class QuantifiedExpression extends Node public function isAll() { - return $this->_all; + return strtoupper($this->type) == 'ALL'; } public function isAny() { - return $this->_any; + return strtoupper($this->type) == 'ANY'; } public function isSome() { - return $this->_some; - } - - public function setAll($bool) - { - $this->_all = $bool; - } - - public function setAny($bool) - { - $this->_any = $bool; - } - - public function setSome($bool) - { - $this->_some = $bool; + return strtoupper($this->type) == 'SOME'; } /** diff --git a/lib/Doctrine/ORM/Query/AST/RangeVariableDeclaration.php b/lib/Doctrine/ORM/Query/AST/RangeVariableDeclaration.php index 8064f9d62..60ccf5532 100644 --- a/lib/Doctrine/ORM/Query/AST/RangeVariableDeclaration.php +++ b/lib/Doctrine/ORM/Query/AST/RangeVariableDeclaration.php @@ -24,41 +24,27 @@ namespace Doctrine\ORM\Query\AST; /** * RangeVariableDeclaration ::= AbstractSchemaName ["AS"] AliasIdentificationVariable * - * @author Guilherme Blanco - * @license http://www.opensource.org/licenses/lgpl-license.php LGPL - * @link http://www.doctrine-project.org - * @since 2.0 - * @version $Revision$ + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision: 3938 $ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel */ class RangeVariableDeclaration extends Node { - private $_classMetadata; - private $_abstractSchemaName; - private $_aliasIdentificationVariable; + public $classMetadata; + public $abstractSchemaName; + public $aliasIdentificationVariable; public function __construct($classMetadata, $aliasIdentificationVar) { - $this->_classMetadata = $classMetadata; - $this->_abstractSchemaName = $classMetadata->name; - $this->_aliasIdentificationVariable = $aliasIdentificationVar; + $this->classMetadata = $classMetadata; + $this->abstractSchemaName = $classMetadata->name; + $this->aliasIdentificationVariable = $aliasIdentificationVar; } - /* Getters */ - public function getAbstractSchemaName() - { - return $this->_abstractSchemaName; - } - - public function getAliasIdentificationVariable() - { - return $this->_aliasIdentificationVariable; - } - - public function getClassMetadata() - { - return $this->_classMetadata; - } - public function dispatch($walker) { return $walker->walkRangeVariableDeclaration($this); diff --git a/lib/Doctrine/ORM/Query/AST/SelectClause.php b/lib/Doctrine/ORM/Query/AST/SelectClause.php index be4a0163e..ed9fbaa34 100644 --- a/lib/Doctrine/ORM/Query/AST/SelectClause.php +++ b/lib/Doctrine/ORM/Query/AST/SelectClause.php @@ -24,52 +24,25 @@ namespace Doctrine\ORM\Query\AST; /** * SelectClause = "SELECT" ["DISTINCT"] SelectExpression {"," SelectExpression} * - * @author Guilherme Blanco - * @license http://www.opensource.org/licenses/lgpl-license.php LGPL - * @link http://www.doctrine-project.org - * @since 2.0 - * @version $Revision$ + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision: 3938 $ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel */ class SelectClause extends Node { - protected $_isDistinct; - - protected $_selectExpressions = array(); + public $isDistinct; + public $selectExpressions = array(); public function __construct(array $selectExpressions, $isDistinct) { - $this->_isDistinct = $isDistinct; - $this->_selectExpressions = $selectExpressions; + $this->isDistinct = $isDistinct; + $this->selectExpressions = $selectExpressions; } - /* Getters */ - public function isDistinct() - { - return $this->_isDistinct; - } - - public function getSelectExpressions() - { - return $this->_selectExpressions; - } - - /* REMOVE ME LATER. COPIED METHODS FROM SPLIT OF PRODUCTION INTO "AST" AND "PARSER" */ - public function buildSql() - { - return 'SELECT ' . (($this->_isDistinct) ? 'DISTINCT ' : '') - . implode(', ', $this->_mapSelectExpressions()); - } - - protected function _mapSelectExpressions() - { - return array_map(array(&$this, '_mapSelectExpression'), $this->_selectExpressions); - } - - protected function _mapSelectExpression($value) - { - return is_object($value) ? $value->buildSql() : $value; - } - public function dispatch($sqlWalker) { return $sqlWalker->walkSelectClause($this); diff --git a/lib/Doctrine/ORM/Query/AST/SelectExpression.php b/lib/Doctrine/ORM/Query/AST/SelectExpression.php index 3b12bc4f1..f1793f0c4 100644 --- a/lib/Doctrine/ORM/Query/AST/SelectExpression.php +++ b/lib/Doctrine/ORM/Query/AST/SelectExpression.php @@ -25,34 +25,25 @@ namespace Doctrine\ORM\Query\AST; * SelectExpression ::= IdentificationVariable ["." "*"] | StateFieldPathExpression | * (AggregateExpression | "(" Subselect ")") [["AS"] FieldAliasIdentificationVariable] * - * @author Guilherme Blanco - * @license http://www.opensource.org/licenses/lgpl-license.php LGPL - * @link http://www.phpdoctrine.org - * @since 2.0 - * @version $Revision$ + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision: 3938 $ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel */ class SelectExpression extends Node { - protected $_expression; - protected $_fieldIdentificationVariable; + public $expression; + public $fieldIdentificationVariable; public function __construct($expression, $fieldIdentificationVariable) { - $this->_expression = $expression; - $this->_fieldIdentificationVariable = $fieldIdentificationVariable; + $this->expression = $expression; + $this->fieldIdentificationVariable = $fieldIdentificationVariable; } - /* Getters */ - public function getExpression() - { - return $this->_expression; - } - - public function getFieldIdentificationVariable() - { - return $this->_fieldIdentificationVariable; - } - public function dispatch($sqlWalker) { return $sqlWalker->walkSelectExpression($this); diff --git a/lib/Doctrine/ORM/Query/AST/SelectStatement.php b/lib/Doctrine/ORM/Query/AST/SelectStatement.php index 3e8c61498..01eed37d0 100644 --- a/lib/Doctrine/ORM/Query/AST/SelectStatement.php +++ b/lib/Doctrine/ORM/Query/AST/SelectStatement.php @@ -24,62 +24,28 @@ namespace Doctrine\ORM\Query\AST; /** * SelectStatement = SelectClause FromClause [WhereClause] [GroupByClause] [HavingClause] [OrderByClause] * - * @author Guilherme Blanco - * @license http://www.opensource.org/licenses/lgpl-license.php LGPL - * @link http://www.phpdoctrine.org - * @since 2.0 - * @version $Revision$ + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision: 3938 $ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel */ class SelectStatement extends Node { - protected $_selectClause; - protected $_fromClause; - protected $_whereClause; - protected $_groupByClause; - protected $_havingClause; - protected $_orderByClause; + public $selectClause; + public $fromClause; + public $whereClause; + public $groupByClause; + public $havingClause; + public $orderByClause; - public function __construct($selectClause, $fromClause, $whereClause, $groupByClause, - $havingClause, $orderByClause) { - $this->_selectClause = $selectClause; - $this->_fromClause = $fromClause; - $this->_whereClause = $whereClause; - $this->_groupByClause = $groupByClause; - $this->_havingClause = $havingClause; - $this->_orderByClause = $orderByClause; + public function __construct($selectClause, $fromClause) { + $this->selectClause = $selectClause; + $this->fromClause = $fromClause; } - /* 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; - } - public function dispatch($sqlWalker) { return $sqlWalker->walkSelectStatement($this); diff --git a/lib/Doctrine/ORM/Query/AST/SimpleArithmeticExpression.php b/lib/Doctrine/ORM/Query/AST/SimpleArithmeticExpression.php index 13dd77045..3fb6f0529 100644 --- a/lib/Doctrine/ORM/Query/AST/SimpleArithmeticExpression.php +++ b/lib/Doctrine/ORM/Query/AST/SimpleArithmeticExpression.php @@ -1,7 +1,22 @@ . */ namespace Doctrine\ORM\Query\AST; @@ -9,20 +24,21 @@ namespace Doctrine\ORM\Query\AST; /** * SimpleArithmeticExpression ::= ArithmeticTerm {("+" | "-") ArithmeticTerm}* * - * @author robo + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision: 3938 $ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel */ class SimpleArithmeticExpression extends Node { - private $_terms; + public $arithmeticTerms = array(); public function __construct(array $arithmeticTerms) { - $this->_terms = $arithmeticTerms; - } - - public function getArithmeticTerms() - { - return $this->_terms; + $this->arithmeticTerms = $arithmeticTerms; } public function dispatch($sqlWalker) diff --git a/lib/Doctrine/ORM/Query/AST/SimpleSelectClause.php b/lib/Doctrine/ORM/Query/AST/SimpleSelectClause.php index 7e03127bb..e3b93e7f6 100644 --- a/lib/Doctrine/ORM/Query/AST/SimpleSelectClause.php +++ b/lib/Doctrine/ORM/Query/AST/SimpleSelectClause.php @@ -24,38 +24,25 @@ namespace Doctrine\ORM\Query\AST; /** * SimpleSelectClause ::= "SELECT" ["DISTINCT"] SimpleSelectExpression * - * @author Guilherme Blanco - * @license http://www.opensource.org/licenses/lgpl-license.php LGPL - * @link http://www.doctrine-project.org - * @since 2.0 - * @version $Revision$ + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision: 3938 $ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel */ class SimpleSelectClause extends Node { - private $_isDistinct = false; - private $_simpleSelectExpression; + public $isDistinct = false; + public $simpleSelectExpression; - public function __construct($simpleSelectExpression) + public function __construct($simpleSelectExpression, $isDistinct) { - $this->_simpleSelectExpression = $simpleSelectExpression; + $this->simpleSelectExpression = $simpleSelectExpression; + $this->isDistinct = $isDistinct; } - /* Getters */ - public function isDistinct() - { - return $this->_isDistinct; - } - - public function setDistinct($bool) - { - $this->_isDistinct = $bool; - } - - public function getSimpleSelectExpression() - { - return $this->_simpleSelectExpression; - } - public function dispatch($sqlWalker) { return $sqlWalker->walkSimpleSelectClause($this); diff --git a/lib/Doctrine/ORM/Query/AST/SimpleSelectExpression.php b/lib/Doctrine/ORM/Query/AST/SimpleSelectExpression.php index 5ebe42ed8..e25d38bfc 100644 --- a/lib/Doctrine/ORM/Query/AST/SimpleSelectExpression.php +++ b/lib/Doctrine/ORM/Query/AST/SimpleSelectExpression.php @@ -23,39 +23,26 @@ namespace Doctrine\ORM\Query\AST; /** * SimpleSelectExpression ::= StateFieldPathExpression | IdentificationVariable - * | (AggregateExpression [["AS"] FieldAliasIdentificationVariable]) + * | (AggregateExpression [["AS"] FieldAliasIdentificationVariable]) * - * @author Guilherme Blanco - * @license http://www.opensource.org/licenses/lgpl-license.php LGPL - * @link http://www.doctrine-project.org - * @since 2.0 - * @version $Revision$ + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision: 3938 $ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel */ class SimpleSelectExpression extends Node { - private $_expression; - private $_fieldIdentificationVariable; + public $expression; + public $fieldIdentificationVariable; public function __construct($expression) { - $this->_expression = $expression; + $this->expression = $expression; } - public function getExpression() - { - return $this->_expression; - } - - public function getFieldIdentificationVariable() - { - return $this->_fieldIdentificationVariable; - } - - public function setFieldIdentificationVariable($fieldAlias) - { - $this->_fieldIdentificationVariable = $fieldAlias; - } - public function dispatch($sqlWalker) { return $sqlWalker->walkSimpleSelectExpression($this); diff --git a/lib/Doctrine/ORM/Query/AST/Subselect.php b/lib/Doctrine/ORM/Query/AST/Subselect.php index 05b635b7d..fa5d3356a 100644 --- a/lib/Doctrine/ORM/Query/AST/Subselect.php +++ b/lib/Doctrine/ORM/Query/AST/Subselect.php @@ -24,78 +24,29 @@ namespace Doctrine\ORM\Query\AST; /** * Subselect ::= SimpleSelectClause SubselectFromClause [WhereClause] [GroupByClause] [HavingClause] [OrderByClause] * - * @author Guilherme Blanco - * @license http://www.opensource.org/licenses/lgpl-license.php LGPL - * @link http://www.doctrine-project.org - * @since 2.0 - * @version $Revision$ + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision: 3938 $ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel */ class Subselect extends Node { - private $_simpleSelectClause; - private $_subselectFromClause; - private $_whereClause; - private $_groupByClause; - private $_havingClause; - private $_orderByClause; + public $simpleSelectClause; + public $subselectFromClause; + public $whereClause; + public $groupByClause; + public $havingClause; + public $orderByClause; public function __construct($simpleSelectClause, $subselectFromClause) { - $this->_simpleSelectClause = $simpleSelectClause; - $this->_subselectFromClause = $subselectFromClause; + $this->simpleSelectClause = $simpleSelectClause; + $this->subselectFromClause = $subselectFromClause; } - /* Getters */ - public function getSimpleSelectClause() - { - return $this->_simpleSelectClause; - } - - public function getSubselectFromClause() - { - return $this->_subselectFromClause; - } - - public function getWhereClause() - { - return $this->_whereClause; - } - - public function setWhereClause($whereClause) - { - $this->_whereClause = $whereClause; - } - - public function getGroupByClause() - { - return $this->_groupByClause; - } - - public function setGroupByClause($groupByClause) - { - $this->_groupByClause = $groupByClause; - } - - public function getHavingClause() - { - return $this->_havingClause; - } - - public function setHavingClause($havingClause) - { - $this->_havingClause = $havingClause; - } - - public function getOrderByClause() - { - return $this->_orderByClause; - } - - public function setOrderByClause($orderByClause) - { - $this->_orderByClause = $orderByClause; - } - public function dispatch($sqlWalker) { return $sqlWalker->walkSubselect($this); diff --git a/lib/Doctrine/ORM/Query/AST/SubselectFromClause.php b/lib/Doctrine/ORM/Query/AST/SubselectFromClause.php index 07d0d7745..44d2b5988 100644 --- a/lib/Doctrine/ORM/Query/AST/SubselectFromClause.php +++ b/lib/Doctrine/ORM/Query/AST/SubselectFromClause.php @@ -24,27 +24,23 @@ namespace Doctrine\ORM\Query\AST; /** * SubselectFromClause ::= "FROM" SubselectIdentificationVariableDeclaration {"," SubselectIdentificationVariableDeclaration}* * - * @author Guilherme Blanco - * @license http://www.opensource.org/licenses/lgpl-license.php LGPL - * @link http://www.doctrine-project.org - * @since 2.0 - * @version $Revision$ + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision: 3938 $ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel */ class SubselectFromClause extends Node { - private $_identificationVariableDeclarations = array(); + public $identificationVariableDeclarations = array(); public function __construct(array $identificationVariableDeclarations) { - $this->_identificationVariableDeclarations = $identificationVariableDeclarations; + $this->identificationVariableDeclarations = $identificationVariableDeclarations; } - /* Getters */ - public function getSubselectIdentificationVariableDeclarations() - { - return $this->_identificationVariableDeclarations; - } - public function dispatch($sqlWalker) { return $sqlWalker->walkSubselectFromClause($this); diff --git a/lib/Doctrine/ORM/Query/AST/UpdateClause.php b/lib/Doctrine/ORM/Query/AST/UpdateClause.php index 2dadabfac..158cf2484 100644 --- a/lib/Doctrine/ORM/Query/AST/UpdateClause.php +++ b/lib/Doctrine/ORM/Query/AST/UpdateClause.php @@ -1,44 +1,47 @@ . */ namespace Doctrine\ORM\Query\AST; /** * UpdateClause ::= "UPDATE" AbstractSchemaName [["AS"] AliasIdentificationVariable] "SET" UpdateItem {"," UpdateItem}* + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision: 3938 $ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel */ class UpdateClause extends Node { - private $_abstractSchemaName; - private $_aliasIdentificationVariable; - private $_updateItems = array(); + public $abstractSchemaName; + public $aliasIdentificationVariable; + public $updateItems = array(); public function __construct($abstractSchemaName, array $updateItems) { - $this->_abstractSchemaName = $abstractSchemaName; - $this->_updateItems = $updateItems; - } - - public function getAbstractSchemaName() - { - return $this->_abstractSchemaName; - } - - public function getAliasIdentificationVariable() - { - return $this->_aliasIdentificationVariable; - } - - public function setAliasIdentificationVariable($alias) - { - $this->_aliasIdentificationVariable = $alias; - } - - public function getUpdateItems() - { - return $this->_updateItems; + $this->abstractSchemaName = $abstractSchemaName; + $this->updateItems = $updateItems; } public function dispatch($sqlWalker) diff --git a/lib/Doctrine/ORM/Query/AST/UpdateItem.php b/lib/Doctrine/ORM/Query/AST/UpdateItem.php index a0e828823..929149897 100644 --- a/lib/Doctrine/ORM/Query/AST/UpdateItem.php +++ b/lib/Doctrine/ORM/Query/AST/UpdateItem.php @@ -26,39 +26,24 @@ namespace Doctrine\ORM\Query\AST; * NewValue ::= SimpleArithmeticExpression | StringPrimary | DatetimePrimary | BooleanPrimary | * EnumPrimary | SimpleEntityExpression | "NULL" * - * @author Roman Borschel - * @since 2.0 + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision: 3938 $ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel */ class UpdateItem extends Node { - private $_identificationVariable; - private $_field; - private $_newValue; + public $identificationVariable; + public $field; + public $newValue; public function __construct($field, $newValue) { - $this->_field = $field; - $this->_newValue = $newValue; - } - - public function setIdentificationVariable($identVar) - { - $this->_identificationVariable = $identVar; - } - - public function getIdentificationVariable() - { - return $this->_identificationVariable; - } - - public function getField() - { - return $this->_field; - } - - public function getNewValue() - { - return $this->_newValue; + $this->field = $field; + $this->newValue = $newValue; } public function dispatch($sqlWalker) diff --git a/lib/Doctrine/ORM/Query/AST/UpdateStatement.php b/lib/Doctrine/ORM/Query/AST/UpdateStatement.php index 32b8871b6..7bf40bbc6 100644 --- a/lib/Doctrine/ORM/Query/AST/UpdateStatement.php +++ b/lib/Doctrine/ORM/Query/AST/UpdateStatement.php @@ -24,35 +24,22 @@ namespace Doctrine\ORM\Query\AST; /** * UpdateStatement = UpdateClause [WhereClause] * - * @author Guilherme Blanco - * @license http://www.opensource.org/licenses/lgpl-license.php LGPL - * @link http://www.doctrine-project.org - * @since 2.0 - * @version $Revision$ + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision: 3938 $ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel */ class UpdateStatement extends Node { - private $_updateClause; - private $_whereClause; + public $updateClause; + public $whereClause; public function __construct($updateClause) { - $this->_updateClause = $updateClause; - } - - public function setWhereClause($whereClause) - { - $this->_whereClause = $whereClause; - } - - public function getUpdateClause() - { - return $this->_updateClause; - } - - public function getWhereClause() - { - return $this->_whereClause; + $this->updateClause = $updateClause; } public function dispatch($sqlWalker) diff --git a/lib/Doctrine/ORM/Query/AST/WhereClause.php b/lib/Doctrine/ORM/Query/AST/WhereClause.php index 33db272af..5d3f9c94e 100644 --- a/lib/Doctrine/ORM/Query/AST/WhereClause.php +++ b/lib/Doctrine/ORM/Query/AST/WhereClause.php @@ -1,28 +1,44 @@ . */ namespace Doctrine\ORM\Query\AST; /** - * Description of WhereClause + * WhereClause ::= "WHERE" ConditionalExpression * - * @author robo + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision: 3938 $ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel */ class WhereClause extends Node { - private $_conditionalExpression; + public $conditionalExpression; public function __construct($conditionalExpression) { - $this->_conditionalExpression = $conditionalExpression; - } - - public function getConditionalExpression() - { - return $this->_conditionalExpression; + $this->conditionalExpression = $conditionalExpression; } public function dispatch($sqlWalker) diff --git a/lib/Doctrine/ORM/Query/Exec/MultiTableDeleteExecutor.php b/lib/Doctrine/ORM/Query/Exec/MultiTableDeleteExecutor.php index 3b53d5404..c97256591 100644 --- a/lib/Doctrine/ORM/Query/Exec/MultiTableDeleteExecutor.php +++ b/lib/Doctrine/ORM/Query/Exec/MultiTableDeleteExecutor.php @@ -53,9 +53,9 @@ class MultiTableDeleteExecutor extends AbstractSqlExecutor $conn = $em->getConnection(); $primaryClass = $sqlWalker->getEntityManager()->getClassMetadata( - $AST->getDeleteClause()->getAbstractSchemaName() + $AST->deleteClause->abstractSchemaName ); - $primaryDqlAlias = $AST->getDeleteClause()->getAliasIdentificationVariable(); + $primaryDqlAlias = $AST->deleteClause->aliasIdentificationVariable; $rootClass = $em->getClassMetadata($primaryClass->rootEntityName); $tempTable = $rootClass->getTemporaryIdTableName(); @@ -71,8 +71,8 @@ class MultiTableDeleteExecutor extends AbstractSqlExecutor $this->_insertSql .= $sqlWalker->walkFromClause($fromClause); // Append WHERE clause, if there is one. - if ($AST->getWhereClause()) { - $this->_insertSql .= $sqlWalker->walkWhereClause($AST->getWhereClause()); + if ($AST->whereClause) { + $this->_insertSql .= $sqlWalker->walkWhereClause($AST->whereClause); } // 2. Create ID subselect statement used in DELETE .... WHERE ... IN (subselect) diff --git a/lib/Doctrine/ORM/Query/Exec/MultiTableUpdateExecutor.php b/lib/Doctrine/ORM/Query/Exec/MultiTableUpdateExecutor.php index 12c630587..0138540b9 100644 --- a/lib/Doctrine/ORM/Query/Exec/MultiTableUpdateExecutor.php +++ b/lib/Doctrine/ORM/Query/Exec/MultiTableUpdateExecutor.php @@ -53,13 +53,12 @@ class MultiTableUpdateExecutor extends AbstractSqlExecutor { $em = $sqlWalker->getEntityManager(); $conn = $em->getConnection(); + $updateClause = $AST->updateClause; - $primaryClass = $sqlWalker->getEntityManager()->getClassMetadata( - $AST->getUpdateClause()->getAbstractSchemaName() - ); + $primaryClass = $sqlWalker->getEntityManager()->getClassMetadata($updateClause->abstractSchemaName); $rootClass = $em->getClassMetadata($primaryClass->rootEntityName); - $updateItems = $AST->getUpdateClause()->getUpdateItems(); + $updateItems = $updateClause->updateItems; $tempTable = $rootClass->getTemporaryIdTableName(); $idColumnNames = $rootClass->getIdentifierColumnNames(); @@ -68,8 +67,8 @@ class MultiTableUpdateExecutor extends AbstractSqlExecutor // 1. Create an INSERT INTO temptable ... SELECT identifiers WHERE $AST->getWhereClause() $this->_insertSql = 'INSERT INTO ' . $tempTable . ' (' . $idColumnList . ')' . ' SELECT t0.' . implode(', t0.', $idColumnNames); - $sqlWalker->setSqlTableAlias($primaryClass->primaryTable['name'] . $AST->getUpdateClause()->getAliasIdentificationVariable(), 't0'); - $rangeDecl = new AST\RangeVariableDeclaration($primaryClass, $AST->getUpdateClause()->getAliasIdentificationVariable()); + $sqlWalker->setSqlTableAlias($primaryClass->primaryTable['name'] . $updateClause->aliasIdentificationVariable, 't0'); + $rangeDecl = new AST\RangeVariableDeclaration($primaryClass, $updateClause->aliasIdentificationVariable); $fromClause = new AST\FromClause(array(new AST\IdentificationVariableDeclaration($rangeDecl, null, array()))); $this->_insertSql .= $sqlWalker->walkFromClause($fromClause); @@ -79,6 +78,7 @@ class MultiTableUpdateExecutor extends AbstractSqlExecutor // 3. Create and store UPDATE statements $classNames = array_merge($primaryClass->parentClasses, array($primaryClass->name), $primaryClass->subClasses); $i = -1; + foreach (array_reverse($classNames) as $className) { $affected = false; $class = $em->getClassMetadata($className); @@ -86,19 +86,22 @@ class MultiTableUpdateExecutor extends AbstractSqlExecutor $updateSql = 'UPDATE ' . $conn->quoteIdentifier($tableName) . ' SET '; foreach ($updateItems as $updateItem) { - $field = $updateItem->getField(); + $field = $updateItem->field; if (isset($class->fieldMappings[$field]) && ! isset($class->fieldMappings[$field]['inherited'])) { - $newValue = $updateItem->getNewValue(); + $newValue = $updateItem->newValue; + if ( ! $affected) { $affected = true; ++$i; } else { $updateSql .= ', '; } + $updateSql .= $sqlWalker->walkUpdateItem($updateItem); + //FIXME: parameters can be more deeply nested. traverse the tree. if ($newValue instanceof AST\InputParameter) { - $paramKey = $newValue->isNamed() ? $newValue->getName() : $newValue->getPosition(); + $paramKey = $newValue->name; $this->_sqlParameters[$i][] = $sqlWalker->getQuery()->getParameter($paramKey); ++$this->_numParametersInUpdateClause; } @@ -111,8 +114,8 @@ class MultiTableUpdateExecutor extends AbstractSqlExecutor } // Append WHERE clause to insertSql, if there is one. - if ($AST->getWhereClause()) { - $this->_insertSql .= $sqlWalker->walkWhereClause($AST->getWhereClause()); + if ($AST->whereClause) { + $this->_insertSql .= $sqlWalker->walkWhereClause($AST->whereClause); } // 4. Store DDL for temporary identifier table. diff --git a/lib/Doctrine/ORM/Query/Parser.php b/lib/Doctrine/ORM/Query/Parser.php index 04f1582c3..d4058ed8a 100644 --- a/lib/Doctrine/ORM/Query/Parser.php +++ b/lib/Doctrine/ORM/Query/Parser.php @@ -30,13 +30,14 @@ use Doctrine\Common\DoctrineException, * An LL(*) parser for the context-free grammar of the Doctrine Query Language. * Parses a DQL query, reports any errors in it, and generates an AST. * - * @author Guilherme Blanco - * @author Janne Vanhala - * @author Roman Borschel - * @license http://www.opensource.org/licenses/lgpl-license.php LGPL - * @link http://www.doctrine-project.org - * @since 2.0 - * @version $Revision$ + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @version $Revision: 3938 $ + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + * @author Janne Vanhala */ class Parser { @@ -482,16 +483,16 @@ class Parser */ private function _validatePathExpression(AST\PathExpression $pathExpression, $nestingLevel = null, $token = null) { - $identificationVariable = $pathExpression->getIdentificationVariable(); + $identVariable = $pathExpression->identificationVariable; $nestingLevel = ($nestingLevel !== null) ?: $this->_nestingLevel; $token = ($token) ?: $this->_lexer->lookahead; - $this->_validateIdentificationVariable($identificationVariable, $nestingLevel, $token); + $this->_validateIdentificationVariable($identVariable, $nestingLevel, $token); - $class = $this->_queryComponents[$identificationVariable]['metadata']; + $class = $this->_queryComponents[$identVariable]['metadata']; $stateField = $collectionField = null; - foreach ($pathExpression->getParts() as $field) { + foreach ($pathExpression->parts as $field) { // Check if it is not in a state field if ($stateField !== null) { $this->semanticalError( @@ -535,7 +536,7 @@ class Parser } // Validate if PathExpression is one of the expected types - $expectedType = $pathExpression->getExpectedType(); + $expectedType = $pathExpression->expectedType; if ( ! ($expectedType & $expressionType)) { // We need to recognize which was expected type(s) @@ -569,7 +570,7 @@ class Parser } // We need to force the type in PathExpression - $pathExpression->setType($expressionType); + $pathExpression->type = $expressionType; return $expressionType; } @@ -578,33 +579,33 @@ class Parser * Validates that the given IdentificationVariable is a semantically correct. * It must exist in query components list. * - * @param string $idVariable + * @param string $identVariable * @param integer $nestingLevel * @param array $token * @return array Query Component */ - private function _validateIdentificationVariable($idVariable, $nestingLevel = null, $token = null) + private function _validateIdentificationVariable($identVariable, $nestingLevel = null, $token = null) { $nestingLevel = ($nestingLevel !== null) ?: $this->_nestingLevel; $token = ($token) ?: $this->_lexer->lookahead; - if ( ! isset($this->_queryComponents[$idVariable])) { + if ( ! isset($this->_queryComponents[$identVariable])) { echo '[Query Components: ' . var_export($this->_queryComponents, true) . ']'; $this->semanticalError( - "Could not find '$idVariable' in query components", $token + "Could not find '$identVariable' in query components", $token ); } // Validate if identification variable nesting level is lower or equal than the current one - if ($this->_queryComponents[$idVariable]['nestingLevel'] > $nestingLevel) { + if ($this->_queryComponents[$identVariable]['nestingLevel'] > $nestingLevel) { $this->semanticalError( - "Query component '$idVariable' is not in the same nesting level of its declaration", + "Query component '$identVariable' is not in the same nesting level of its declaration", $token ); } - return $this->_queryComponents[$idVariable]; + return $this->_queryComponents[$identVariable]; } @@ -647,27 +648,24 @@ class Parser // since we do not have any IdentificationVariable yet $this->_beginDeferredPathExpressionStack(); - $selectClause = $this->SelectClause(); - $fromClause = $this->FromClause(); + $selectStatement = new AST\SelectStatement($this->SelectClause(), $this->FromClause()); // Activate semantical checks after this point. Process all deferred checks in pipeline $this->_processDeferredPathExpressionStack(); - $whereClause = $this->_lexer->isNextToken(Lexer::T_WHERE) + $selectStatement->whereClause = $this->_lexer->isNextToken(Lexer::T_WHERE) ? $this->WhereClause() : null; - $groupByClause = $this->_lexer->isNextToken(Lexer::T_GROUP) + $selectStatement->groupByClause = $this->_lexer->isNextToken(Lexer::T_GROUP) ? $this->GroupByClause() : null; - $havingClause = $this->_lexer->isNextToken(Lexer::T_HAVING) + $selectStatement->havingClause = $this->_lexer->isNextToken(Lexer::T_HAVING) ? $this->HavingClause() : null; - $orderByClause = $this->_lexer->isNextToken(Lexer::T_ORDER) + $selectStatement->orderByClause = $this->_lexer->isNextToken(Lexer::T_ORDER) ? $this->OrderByClause() : null; - return new AST\SelectStatement( - $selectClause, $fromClause, $whereClause, $groupByClause, $havingClause, $orderByClause - ); + return $selectStatement; } /** @@ -678,9 +676,8 @@ class Parser public function UpdateStatement() { $updateStatement = new AST\UpdateStatement($this->UpdateClause()); - $updateStatement->setWhereClause( - $this->_lexer->isNextToken(Lexer::T_WHERE) ? $this->WhereClause() : null - ); + $updateStatement->whereClause = $this->_lexer->isNextToken(Lexer::T_WHERE) + ? $this->WhereClause() : null; return $updateStatement; } @@ -693,9 +690,8 @@ class Parser public function DeleteStatement() { $deleteStatement = new AST\DeleteStatement($this->DeleteClause()); - $deleteStatement->setWhereClause( - $this->_lexer->isNextToken(Lexer::T_WHERE) ? $this->WhereClause() : null - ); + $deleteStatement->whereClause = $this->_lexer->isNextToken(Lexer::T_WHERE) + ? $this->WhereClause() : null; return $deleteStatement; } @@ -758,22 +754,22 @@ class Parser public function JoinAssociationPathExpression() { $token = $this->_lexer->lookahead; - $identificationVariable = $this->IdentificationVariable(); + $identVariable = $this->IdentificationVariable(); $this->match('.'); $this->match(Lexer::T_IDENTIFIER); $field = $this->_lexer->token['value']; // Validating IdentificationVariable (it was already defined previously) - $this->_validateIdentificationVariable($identificationVariable, null, $token); + $this->_validateIdentificationVariable($identVariable, null, $token); // Validating association field (*-to-one or *-to-many) - $class = $this->_queryComponents[$identificationVariable]['metadata']; + $class = $this->_queryComponents[$identVariable]['metadata']; if ( ! isset($class->associationMappings[$field])) { $this->semanticalError('Class ' . $class->name . ' has no field named ' . $field); } - return new AST\JoinAssociationPathExpression($identificationVariable, $field); + return new AST\JoinAssociationPathExpression($identVariable, $field); } /** @@ -788,7 +784,7 @@ class Parser public function PathExpression($expectedType) { $token = $this->_lexer->lookahead; - $identificationVariable = $this->IdentificationVariable(); + $identVariable = $this->IdentificationVariable(); $parts = array(); do { @@ -799,7 +795,7 @@ class Parser } while ($this->_lexer->isNextToken('.')); // Creating AST node - $pathExpr = new AST\PathExpression($expectedType, $identificationVariable, $parts); + $pathExpr = new AST\PathExpression($expectedType, $identVariable, $parts); // Defer PathExpression validation if requested to be defered if ( ! empty($this->_deferredPathExpressionStacks)) { @@ -884,7 +880,7 @@ class Parser public function SimpleStateFieldPathExpression() { $pathExpression = $this->PathExpression(AST\PathExpression::TYPE_STATE_FIELD); - $parts = $pathExpression->getParts(); + $parts = $pathExpression->parts; if (count($parts) > 1) { $this->semanticalError( @@ -932,18 +928,15 @@ class Parser */ public function SimpleSelectClause() { - $distinct = false; + $isDistinct = false; $this->match(Lexer::T_SELECT); if ($this->_lexer->isNextToken(Lexer::T_DISTINCT)) { $this->match(Lexer::T_DISTINCT); - $distinct = true; + $isDistinct = true; } - $simpleSelectClause = new AST\SimpleSelectClause($this->SimpleSelectExpression()); - $simpleSelectClause->setDistinct($distinct); - - return $simpleSelectClause; + return new AST\SimpleSelectClause($this->SimpleSelectExpression(), $isDistinct); } /** @@ -992,7 +985,7 @@ class Parser } $updateClause = new AST\UpdateClause($abstractSchemaName, $updateItems); - $updateClause->setAliasIdentificationVariable($aliasIdentificationVariable); + $updateClause->aliasIdentificationVariable = $aliasIdentificationVariable; return $updateClause; } @@ -1022,11 +1015,11 @@ class Parser $token = $this->_lexer->lookahead; $aliasIdentificationVariable = $this->AliasIdentificationVariable(); } else { - $aliasIdentificationVariable = $deleteClause->getAbstractSchemaName(); + $aliasIdentificationVariable = $deleteClause->abstractSchemaName; } - $deleteClause->setAliasIdentificationVariable($aliasIdentificationVariable); - $class = $this->_em->getClassMetadata($deleteClause->getAbstractSchemaName()); + $deleteClause->aliasIdentificationVariable = $aliasIdentificationVariable; + $class = $this->_em->getClassMetadata($deleteClause->abstractSchemaName); // Building queryComponent $queryComponent = array( @@ -1156,25 +1149,23 @@ class Parser $this->_nestingLevel++; $this->_beginDeferredPathExpressionStack(); + $subselect = new AST\Subselect($this->SimpleSelectClause(), $this->SubselectFromClause()); + $this->_processDeferredPathExpressionStack(); - $subselect->setWhereClause( - $this->_lexer->isNextToken(Lexer::T_WHERE) ? $this->WhereClause() : null - ); - - $subselect->setGroupByClause( - $this->_lexer->isNextToken(Lexer::T_GROUP) ? $this->GroupByClause() : null - ); - - $subselect->setHavingClause( - $this->_lexer->isNextToken(Lexer::T_HAVING) ? $this->HavingClause() : null - ); - - $subselect->setOrderByClause( - $this->_lexer->isNextToken(Lexer::T_ORDER) ? $this->OrderByClause() : null - ); - + $subselect->whereClause = $this->_lexer->isNextToken(Lexer::T_WHERE) + ? $this->WhereClause() : null; + + $subselect->groupByClause = $this->_lexer->isNextToken(Lexer::T_GROUP) + ? $this->GroupByClause() : null; + + $subselect->havingClause = $this->_lexer->isNextToken(Lexer::T_HAVING) + ? $this->HavingClause() : null; + + $subselect->orderByClause = $this->_lexer->isNextToken(Lexer::T_ORDER) + ? $this->OrderByClause() : null; + // Decrease query nesting level $this->_nestingLevel--; @@ -1190,10 +1181,10 @@ class Parser public function UpdateItem() { $token = $this->_lexer->lookahead; - $identificationVariable = $this->IdentificationVariable(); + $identVariable = $this->IdentificationVariable(); // Validate if IdentificationVariable is defined - $queryComponent = $this->_validateIdentificationVariable($identificationVariable, null, $token); + $queryComponent = $this->_validateIdentificationVariable($identVariable, null, $token); $this->match('.'); $this->match(Lexer::T_IDENTIFIER); @@ -1213,7 +1204,7 @@ class Parser $newValue = $this->NewValue(); $updateItem = new AST\UpdateItem($field, $newValue); - $updateItem->setIdentificationVariable($identificationVariable); + $updateItem->identificationVariable = $identVariable; return $updateItem; } @@ -1230,12 +1221,12 @@ class Parser if ($glimpse['value'] != '.') { $token = $this->_lexer->lookahead; - $identificationVariable = $this->IdentificationVariable(); + $identVariable = $this->IdentificationVariable(); // Validate if IdentificationVariable is defined - $this->_validateIdentificationVariable($identificationVariable, null, $token); + $this->_validateIdentificationVariable($identVariable, null, $token); - return $identificationVariable; + return $identVariable; } return $this->SingleValuedPathExpression(); @@ -1251,15 +1242,17 @@ class Parser */ public function OrderByItem() { + $type = 'ASC'; + // We need to check if we are in a ResultVariable or StateFieldPathExpression $glimpse = $this->_lexer->glimpse(); if ($glimpse['value'] != '.') { $token = $this->_lexer->lookahead; - $expr = $this->ResultVariable(); + $resultVariable = $this->ResultVariable(); // Check if ResultVariable is defined in query components - $queryComponent = $this->_validateIdentificationVariable($expr, null, $token); + $queryComponent = $this->_validateIdentificationVariable($resultVariable, null, $token); // Outer defininition used in inner subselect is not enough. // ResultVariable exists in queryComponents, check nesting level @@ -1276,17 +1269,12 @@ class Parser if ($this->_lexer->isNextToken(Lexer::T_ASC)) { $this->match(Lexer::T_ASC); - $item->setAsc(true); - return $item; - } - - if ($this->_lexer->isNextToken(Lexer::T_DESC)) { + } else if ($this->_lexer->isNextToken(Lexer::T_DESC)) { $this->match(Lexer::T_DESC); - $item->setDesc(true); - return $item; + $type = 'DESC'; } - $item->setAsc(true); + $item->type = $type; return $item; } @@ -1350,10 +1338,10 @@ class Parser $peek = $this->_lexer->glimpse(); if ($peek['value'] == '.') { - $subselectIdVarDecl = new AST\SubselectIdentificationVariableDeclaration; - $subselectIdVarDecl->setAssociationPathExpression($this->AssociationPathExpression()); + $subselectIdVarDecl = new AST\SubselectIdentificationVariableDeclaration(); + $subselectIdVarDecl->associationPathExpression = $this->AssociationPathExpression(); $this->match(Lexer::T_AS); - $subselectIdVarDecl->setAliasIdentificationVariable($this->AliasIdentificationVariable()); + $subselectIdVarDecl->aliasIdentificationVariable = $this->AliasIdentificationVariable(); return $subselectIdVarDecl; } @@ -1445,8 +1433,8 @@ class Parser $aliasIdentificationVariable = $this->AliasIdentificationVariable(); // Verify that the association exists. - $parentClass = $this->_queryComponents[$joinPathExpression->getIdentificationVariable()]['metadata']; - $assocField = $joinPathExpression->getAssociationField(); + $parentClass = $this->_queryComponents[$joinPathExpression->identificationVariable]['metadata']; + $assocField = $joinPathExpression->associationField; if ( ! $parentClass->hasAssociation($assocField)) { $this->semanticalError( @@ -1459,7 +1447,7 @@ class Parser // Building queryComponent $joinQueryComponent = array( 'metadata' => $this->_em->getClassMetadata($targetClassName), - 'parent' => $joinPathExpression->getIdentificationVariable(), + 'parent' => $joinPathExpression->identificationVariable, 'relation' => $parentClass->getAssociationMapping($assocField), 'map' => null, 'nestingLevel' => $this->_nestingLevel, @@ -1474,12 +1462,12 @@ class Parser if ($this->_lexer->isNextToken(Lexer::T_ON) || $this->_lexer->isNextToken(Lexer::T_WITH)) { if ($this->_lexer->isNextToken(Lexer::T_ON)) { $this->match(Lexer::T_ON); - $join->setWhereType(AST\Join::JOIN_WHERE_ON); + $join->whereType = AST\Join::JOIN_WHERE_ON; } else { $this->match(Lexer::T_WITH); } - $join->setConditionalExpression($this->ConditionalExpression()); + $join->conditionalExpression = $this->ConditionalExpression(); } return $join; @@ -1497,8 +1485,8 @@ class Parser $pathExp = $this->SimpleStateFieldPathExpression(); // Add the INDEX BY info to the query component - $parts = $pathExp->getParts(); - $this->_queryComponents[$pathExp->getIdentificationVariable()]['map'] = $parts[0]; + $parts = $pathExp->parts; + $this->_queryComponents[$pathExp->identificationVariable]['map'] = $parts[0]; return $pathExp; } @@ -1593,7 +1581,7 @@ class Parser if ($this->_lexer->isNextToken(Lexer::T_IDENTIFIER)) { $token = $this->_lexer->lookahead; $resultVariable = $this->ResultVariable(); - $expr->setFieldIdentificationVariable($resultVariable); + $expr->fieldIdentificationVariable = $resultVariable; // Include ResultVariable in query components. $this->_queryComponents[$resultVariable] = array( @@ -1657,7 +1645,10 @@ class Parser $not = true; } - return new AST\ConditionalFactor($this->ConditionalPrimary(), $not); + $condFactor = new AST\ConditionalFactor($this->ConditionalPrimary()); + $condFactor->not = $not; + + return $condFactor; } /** @@ -1691,14 +1682,14 @@ class Parser // Check if unmatched parenthesis is > 0, then we found a matching arithmetic operator if ($numUnmatched > 0) { - $condPrimary->setSimpleConditionalExpression($this->SimpleConditionalExpression()); + $condPrimary->simpleConditionalExpression = $this->SimpleConditionalExpression(); } else { $this->match('('); - $condPrimary->setConditionalExpression($this->ConditionalExpression()); + $condPrimary->conditionalExpression = $this->ConditionalExpression(); $this->match(')'); } } else { - $condPrimary->setSimpleConditionalExpression($this->SimpleConditionalExpression()); + $condPrimary->simpleConditionalExpression = $this->SimpleConditionalExpression(); } return $condPrimary; @@ -1799,7 +1790,7 @@ class Parser if ($this->_lexer->isNextToken(Lexer::T_NOT)) { $this->match(Lexer::T_NOT); - $emptyColletionCompExpr->setNot(true); + $emptyColletionCompExpr->not = true; } $this->match(Lexer::T_EMPTY); @@ -1817,12 +1808,12 @@ class Parser */ public function CollectionMemberExpression() { - $isNot = false; + $not = false; $entityExpr = $this->EntityExpression(); if ($this->_lexer->isNextToken(Lexer::T_NOT)) { - $isNot = true; + $not = true; $this->match(Lexer::T_NOT); } @@ -1832,9 +1823,12 @@ class Parser $this->match(Lexer::T_OF); } - return new AST\CollectionMemberExpression( - $entityExpr, $this->CollectionValuedPathExpression(), $isNot + $collMemberExpr = new AST\CollectionMemberExpression( + $entityExpr, $this->CollectionValuedPathExpression() ); + $collMemberExpr->not = $not; + + return $collMemberExpr; } @@ -1967,17 +1961,17 @@ class Parser */ public function ArithmeticFactor() { - $pSign = $nSign = false; + $sign = null; if ($this->_lexer->lookahead['value'] == '+') { $this->match('+'); - $pSign = true; + $sign = true; } else if ($this->_lexer->lookahead['value'] == '-') { $this->match('-'); - $nSign = true; + $sign = false; } - return new AST\ArithmeticFactor($this->ArithmeticPrimary(), $pSign, $nSign); + return new AST\ArithmeticFactor($this->ArithmeticPrimary(), $sign); } /** @@ -2171,29 +2165,26 @@ class Parser */ public function QuantifiedExpression() { - $all = $any = $some = false; + $type = ''; if ($this->_lexer->isNextToken(Lexer::T_ALL)) { $this->match(Lexer::T_ALL); - $all = true; + $type = 'ALL'; } else if ($this->_lexer->isNextToken(Lexer::T_ANY)) { $this->match(Lexer::T_ANY); - $any = true; + $type = 'ANY'; } else if ($this->_lexer->isNextToken(Lexer::T_SOME)) { $this->match(Lexer::T_SOME); - $some = true; + $type = 'SOME'; } else { $this->syntaxError('ALL, ANY or SOME'); } $this->match('('); $qExpr = new AST\QuantifiedExpression($this->Subselect()); + $qExpr->type = $type; $this->match(')'); - $qExpr->setAll($all); - $qExpr->setAny($any); - $qExpr->setSome($some); - return $qExpr; } @@ -2218,7 +2209,7 @@ class Parser $arithExpr3 = $this->ArithmeticExpression(); $betweenExpr = new AST\BetweenExpression($arithExpr1, $arithExpr2, $arithExpr3); - $betweenExpr->setNot($not); + $betweenExpr->not = $not; return $betweenExpr; } @@ -2255,14 +2246,14 @@ class Parser if ($this->_lexer->isNextToken(Lexer::T_NOT)) { $this->match(Lexer::T_NOT); - $inExpression->setNot(true); + $inExpression->not = true; } $this->match(Lexer::T_IN); $this->match('('); if ($this->_lexer->isNextToken(Lexer::T_SELECT)) { - $inExpression->setSubselect($this->Subselect()); + $inExpression->subselect = $this->Subselect(); } else { $literals = array(); $literals[] = $this->InParameter(); @@ -2272,7 +2263,7 @@ class Parser $literals[] = $this->InParameter(); } - $inExpression->setLiterals($literals); + $inExpression->literals = $literals; } $this->match(')'); @@ -2288,11 +2279,11 @@ class Parser public function LikeExpression() { $stringExpr = $this->StringExpression(); - $isNot = false; + $not = false; if ($this->_lexer->lookahead['type'] === Lexer::T_NOT) { $this->match(Lexer::T_NOT); - $isNot = true; + $not = true; } $this->match(Lexer::T_LIKE); @@ -2313,7 +2304,10 @@ class Parser $escapeChar = $this->_lexer->token['value']; } - return new AST\LikeExpression($stringExpr, $stringPattern, $isNot, $escapeChar); + $likeExpr = new AST\LikeExpression($stringExpr, $stringPattern, $escapeChar); + $likeExpr->not = $not; + + return $likeExpr; } /** @@ -2335,7 +2329,7 @@ class Parser if ($this->_lexer->isNextToken(Lexer::T_NOT)) { $this->match(Lexer::T_NOT); - $nullCompExpr->setNot(true); + $nullCompExpr->not = true; } $this->match(Lexer::T_NULL); @@ -2360,8 +2354,8 @@ class Parser $this->match(Lexer::T_EXISTS); $this->match('('); $existsExpression = new AST\ExistsExpression($this->Subselect()); + $existsExpression->not = $not; $this->match(')'); - $existsExpression->setNot($not); return $existsExpression; } diff --git a/lib/Doctrine/ORM/Query/SqlWalker.php b/lib/Doctrine/ORM/Query/SqlWalker.php index 77b8fc5a6..930bdc386 100644 --- a/lib/Doctrine/ORM/Query/SqlWalker.php +++ b/lib/Doctrine/ORM/Query/SqlWalker.php @@ -122,1275 +122,52 @@ class SqlWalker implements TreeWalker return $this->_em; } + /** + * Gets the Query Component related to the given DQL alias. + * + * @param string $dqlAlias DQL alias + * @return array + */ public function getQueryComponent($dqlAlias) { return $this->_queryComponents[$dqlAlias]; } - - /** - * Walks down a SelectStatement AST node, thereby generating the appropriate SQL. - * - * @return string The SQL. - */ - public function walkSelectStatement(AST\SelectStatement $AST) - { - $sql = $this->walkSelectClause($AST->getSelectClause()); - $sql .= $this->walkFromClause($AST->getFromClause()); - - if ($whereClause = $AST->getWhereClause()) { - $sql .= $this->walkWhereClause($whereClause); - } else if ($discSql = $this->_generateDiscriminatorColumnConditionSql($this->_currentRootAlias)) { - $sql .= ' WHERE ' . $discSql; - } - - $sql .= $AST->getGroupByClause() ? $this->walkGroupByClause($AST->getGroupByClause()) : ''; - $sql .= $AST->getHavingClause() ? $this->walkHavingClause($AST->getHavingClause()) : ''; - $sql .= $AST->getOrderByClause() ? $this->walkOrderByClause($AST->getOrderByClause()) : ''; - - $q = $this->getQuery(); - $sql = $this->getConnection()->getDatabasePlatform()->modifyLimitQuery( - $sql, $q->getMaxResults(), $q->getFirstResult() - ); - - return $sql; - } - - /** - * Walks down a SelectClause AST node, thereby generating the appropriate SQL. - * - * @return string The SQL. - */ - public function walkSelectClause($selectClause) - { - $sql = 'SELECT ' . (($selectClause->isDistinct()) ? 'DISTINCT ' : '') . implode( - ', ', array_map(array($this, 'walkSelectExpression'), $selectClause->getSelectExpressions()) - ); - - foreach ($this->_selectedClasses as $dqlAlias => $class) { - if ($this->_queryComponents[$dqlAlias]['relation'] === null) { - $this->_rsm->addEntityResult($class->name, $dqlAlias); - } else { - $this->_rsm->addJoinedEntityResult( - $class->name, $dqlAlias, - $this->_queryComponents[$dqlAlias]['parent'], - $this->_queryComponents[$dqlAlias]['relation'] - ); - } - - if ($class->isInheritanceTypeSingleTable() || $class->isInheritanceTypeJoined()) { - $rootClass = $this->_em->getClassMetadata($class->rootEntityName); - $tblAlias = $this->getSqlTableAlias($rootClass->getTableName(), $dqlAlias); - $discrColumn = $rootClass->discriminatorColumn; - $columnAlias = $this->getSqlColumnAlias($discrColumn['name']); - $sql .= ", $tblAlias." . $this->_conn->quoteIdentifier($discrColumn['name']) - . ' AS ' . $columnAlias; - - $this->_rsm->setDiscriminatorColumn($dqlAlias, $columnAlias); - $this->_rsm->addMetaResult($dqlAlias, $columnAlias, $discrColumn['fieldName']); - } - } - - return $sql; - } - - /** - * Walks down a FromClause AST node, thereby generating the appropriate SQL. - * - * @return string The SQL. - */ - public function walkFromClause($fromClause) - { - $sql = ' FROM '; - $identificationVarDecls = $fromClause->getIdentificationVariableDeclarations(); - $firstIdentificationVarDecl = $identificationVarDecls[0]; - $rangeDecl = $firstIdentificationVarDecl->getRangeVariableDeclaration(); - $dqlAlias = $rangeDecl->getAliasIdentificationVariable(); - - $this->_currentRootAlias = $dqlAlias; - $class = $rangeDecl->getClassMetadata(); - - $sql .= $this->_conn->quoteIdentifier($class->getTableName()) . ' ' - . $this->getSqlTableAlias($class->getTableName(), $dqlAlias); - - if ($class->isInheritanceTypeJoined()) { - $sql .= $this->_generateClassTableInheritanceJoins($class, $dqlAlias); - } - - foreach ($firstIdentificationVarDecl->getJoinVariableDeclarations() as $joinVarDecl) { - $sql .= $this->walkJoinVariableDeclaration($joinVarDecl); - } - - return $sql; - } - - /** - * Walks down a FunctionNode AST node, thereby generating the appropriate SQL. - * - * @return string The SQL. - */ - public function walkFunction($function) - { - return $function->getSql($this); - } - - /** - * Walks down an OrderByClause AST node, thereby generating the appropriate SQL. - * - * @param OrderByClause - * @return string The SQL. - */ - public function walkOrderByClause($orderByClause) - { - // OrderByClause ::= "ORDER" "BY" OrderByItem {"," OrderByItem}* - return ' ORDER BY ' . implode( - ', ', array_map(array($this, 'walkOrderByItem'), $orderByClause->getOrderByItems()) - ); - } - - /** - * Walks down an OrderByItem AST node, thereby generating the appropriate SQL. - * - * @param OrderByItem - * @return string The SQL. - */ - public function walkOrderByItem($orderByItem) - { - $expr = $orderByItem->getExpression(); - $parts = $expr->getParts(); - $dqlAlias = $expr->getIdentificationVariable(); - $qComp = $this->_queryComponents[$dqlAlias]; - $columnName = $qComp['metadata']->getColumnName($parts[0]); - - $sql = $this->getSqlTableAlias($qComp['metadata']->getTableName(), $dqlAlias) . '.' - . $this->_conn->quoteIdentifier($columnName) - . ($orderByItem->isDesc() ? ' DESC' : ' ASC'); - - return $sql; - } - - /** - * Walks down a HavingClause AST node, thereby generating the appropriate SQL. - * - * @param HavingClause - * @return string The SQL. - */ - public function walkHavingClause($havingClause) - { - $condExpr = $havingClause->getConditionalExpression(); - - return ' HAVING ' . implode( - ' OR ', array_map(array($this, 'walkConditionalTerm'), $condExpr->getConditionalTerms()) - ); - } - - /** - * Walks down a JoinVariableDeclaration AST node and creates the corresponding SQL. - * - * @param JoinVariableDeclaration $joinVarDecl - * @return string The SQL. - */ - public function walkJoinVariableDeclaration($joinVarDecl) - { - $join = $joinVarDecl->getJoin(); - $joinType = $join->getJoinType(); - - if ($joinType == AST\Join::JOIN_TYPE_LEFT || $joinType == AST\Join::JOIN_TYPE_LEFTOUTER) { - $sql = ' LEFT JOIN '; - } else { - $sql = ' INNER JOIN '; - } - - $joinAssocPathExpr = $join->getJoinAssociationPathExpression(); - $joinedDqlAlias = $join->getAliasIdentificationVariable(); - $sourceQComp = $this->_queryComponents[$joinAssocPathExpr->getIdentificationVariable()]; - $targetQComp = $this->_queryComponents[$joinedDqlAlias]; - - $targetTableName = $targetQComp['metadata']->getTableName(); - $targetTableAlias = $this->getSqlTableAlias($targetTableName, $joinedDqlAlias); - $sourceTableAlias = $this->getSqlTableAlias( - $sourceQComp['metadata']->getTableName(), $joinAssocPathExpr->getIdentificationVariable() - ); - - // Ensure we got the owning side, since it has all mapping info - if ( ! $targetQComp['relation']->isOwningSide()) { - $assoc = $targetQComp['metadata']->getAssociationMapping($targetQComp['relation']->getMappedByFieldName()); - } else { - $assoc = $targetQComp['relation']; - } - - if ($assoc->isOneToOne()) { - $sql .= $this->_conn->quoteIdentifier($targetTableName) . ' ' . $targetTableAlias . ' ON '; - $joinColumns = $assoc->getSourceToTargetKeyColumns(); - $first = true; - foreach ($joinColumns as $sourceColumn => $targetColumn) { - if ( ! $first) { - $sql .= ' AND '; - } else { - $first = false; - } - - if ($targetQComp['relation']->isOwningSide()) { - $sql .= $sourceTableAlias . '.' . $this->_conn->quoteIdentifier($sourceColumn) - . ' = ' - . $targetTableAlias . '.' . $this->_conn->quoteIdentifier($targetColumn); - } else { - $sql .= $sourceTableAlias . '.' . $this->_conn->quoteIdentifier($targetColumn) - . ' = ' - . $targetTableAlias . '.' . $this->_conn->quoteIdentifier($sourceColumn); - } - } - } else if ($assoc->isManyToMany()) { - // Join relation table - $joinTable = $assoc->getJoinTable(); - $joinTableAlias = $this->getSqlTableAlias($joinTable['name']); - $sql .= $this->_conn->quoteIdentifier($joinTable['name']) . ' ' . $joinTableAlias . ' ON '; - - if ($targetQComp['relation']->isOwningSide) { - $sourceToRelationJoinColumns = $assoc->getSourceToRelationKeyColumns(); - - foreach ($sourceToRelationJoinColumns as $sourceColumn => $relationColumn) { - $sql .= $sourceTableAlias . '.' . $this->_conn->quoteIdentifier($sourceColumn) - . ' = ' - . $joinTableAlias . '.' . $this->_conn->quoteIdentifier($relationColumn); - } - } else { - $targetToRelationJoinColumns = $assoc->getTargetToRelationKeyColumns(); - - foreach ($targetToRelationJoinColumns as $targetColumn => $relationColumn) { - $sql .= $sourceTableAlias . '.' . $this->_conn->quoteIdentifier($targetColumn) - . ' = ' - . $joinTableAlias . '.' . $this->_conn->quoteIdentifier($relationColumn); - } - } - - // Join target table - $sql .= ($joinType == AST\Join::JOIN_TYPE_LEFT || $joinType == AST\Join::JOIN_TYPE_LEFTOUTER) - ? ' LEFT JOIN ' : ' INNER JOIN '; - $sql .= $this->_conn->quoteIdentifier($targetTableName) . ' ' . $targetTableAlias . ' ON '; - - if ($targetQComp['relation']->isOwningSide) { - $targetToRelationJoinColumns = $assoc->getTargetToRelationKeyColumns(); - - foreach ($targetToRelationJoinColumns as $targetColumn => $relationColumn) { - $sql .= $targetTableAlias . '.' . $this->_conn->quoteIdentifier($targetColumn) - . ' = ' - . $joinTableAlias . '.' . $this->_conn->quoteIdentifier($relationColumn); - } - } else { - $sourceToRelationJoinColumns = $assoc->getSourceToRelationKeyColumns(); - - foreach ($sourceToRelationJoinColumns as $sourceColumn => $relationColumn) { - $sql .= $targetTableAlias . '.' . $this->_conn->quoteIdentifier($sourceColumn) - . ' = ' - . $joinTableAlias . '.' . $this->_conn->quoteIdentifier($relationColumn); - } - } - } - - $discrSql = $this->_generateDiscriminatorColumnConditionSql($joinedDqlAlias); - - if ($discrSql) { - $sql .= ' AND ' . $discrSql; - } - - if ($targetQComp['metadata']->isInheritanceTypeJoined()) { - $sql .= $this->_generateClassTableInheritanceJoins($targetQComp['metadata'], $joinedDqlAlias); - } - - return $sql; - } - - /** - * Walks down a SelectExpression AST node and generates the corresponding SQL. - * - * @param SelectExpression $selectExpression - * @return string The SQL. - */ - public function walkSelectExpression($selectExpression) - { - $sql = ''; - $expr = $selectExpression->getExpression(); - if ($expr instanceof AST\PathExpression) { - if ($expr->getType() == AST\PathExpression::TYPE_STATE_FIELD) { - $parts = $expr->getParts(); - $numParts = count($parts); - $dqlAlias = $expr->getIdentificationVariable(); - $fieldName = $parts[$numParts-1]; - $qComp = $this->_queryComponents[$dqlAlias]; - $class = $qComp['metadata']; - - if ( ! isset($this->_selectedClasses[$dqlAlias])) { - $this->_selectedClasses[$dqlAlias] = $class; - } - - $sqlTableAlias = $this->getSqlTableAlias($class->getTableName(), $dqlAlias); - $columnName = $class->getColumnName($fieldName); - $columnAlias = $this->getSqlColumnAlias($columnName); - $sql .= $sqlTableAlias . '.' . $this->_conn->quoteIdentifier($columnName) - . ' AS ' . $columnAlias; - - $this->_rsm->addFieldResult($dqlAlias, $columnAlias, $fieldName); - } else { - throw DoctrineException::updateMe("Encountered invalid PathExpression during SQL construction."); - } - } else if ($expr instanceof AST\AggregateExpression) { - if ( ! $selectExpression->getFieldIdentificationVariable()) { - $resultAlias = $this->_scalarResultCounter++; - } else { - $resultAlias = $selectExpression->getFieldIdentificationVariable(); - } - - $columnAlias = 'sclr' . $this->_aliasCounter++; - $sql .= $this->walkAggregateExpression($expr) . ' AS ' . $columnAlias; - - $this->_rsm->addScalarResult($columnAlias, $resultAlias); - } else if ($expr instanceof AST\Subselect) { - $sql .= $this->walkSubselect($expr); - } else if ($expr instanceof AST\Functions\FunctionNode) { - if ( ! $selectExpression->getFieldIdentificationVariable()) { - $resultAlias = $this->_scalarResultCounter++; - } else { - $resultAlias = $selectExpression->getFieldIdentificationVariable(); - } - - $columnAlias = 'sclr' . $this->_aliasCounter++; - $sql .= $this->walkFunction($expr) . ' AS ' . $columnAlias; - - $this->_rsm->addScalarResult($columnAlias, $resultAlias); - } else { - // IdentificationVariable - $dqlAlias = $expr; - $queryComp = $this->_queryComponents[$dqlAlias]; - $class = $queryComp['metadata']; - - if ( ! isset($this->_selectedClasses[$dqlAlias])) { - $this->_selectedClasses[$dqlAlias] = $class; - } - - $beginning = true; - if ($class->isInheritanceTypeJoined()) { - // Select all fields from the queried class - foreach ($class->fieldMappings as $fieldName => $mapping) { - if (isset($mapping['inherited'])) { - $tableName = $this->_em->getClassMetadata($mapping['inherited'])->primaryTable['name']; - } else { - $tableName = $class->primaryTable['name']; - } - - if ($beginning) $beginning = false; else $sql .= ', '; - - $sqlTableAlias = $this->getSqlTableAlias($tableName, $dqlAlias); - $columnAlias = $this->getSqlColumnAlias($mapping['columnName']); - $sql .= $sqlTableAlias . '.' . $this->_conn->quoteIdentifier($mapping['columnName']) - . ' AS ' . $columnAlias; - - $this->_rsm->addFieldResult($dqlAlias, $columnAlias, $fieldName); - } - - // Add any additional fields of subclasses (not inherited fields) - foreach ($class->subClasses as $subClassName) { - $subClass = $this->_em->getClassMetadata($subClassName); - - foreach ($subClass->fieldMappings as $fieldName => $mapping) { - if (isset($mapping['inherited'])) { - continue; - } - - if ($beginning) $beginning = false; else $sql .= ', '; - - $sqlTableAlias = $this->getSqlTableAlias($subClass->primaryTable['name'], $dqlAlias); - $columnAlias = $this->getSqlColumnAlias($mapping['columnName']); - $sql .= $sqlTableAlias . '.' . $this->_conn->quoteIdentifier($mapping['columnName']) - . ' AS ' . $columnAlias; - - $this->_rsm->addFieldResult($dqlAlias, $columnAlias, $fieldName); - } - } - } else { - $fieldMappings = $class->fieldMappings; - - foreach ($class->subClasses as $subclassName) { - $fieldMappings = array_merge( - $fieldMappings, - $this->_em->getClassMetadata($subclassName)->fieldMappings - ); - } - - $sqlTableAlias = $this->getSqlTableAlias($class->getTableName(), $dqlAlias); - - foreach ($fieldMappings as $fieldName => $mapping) { - if ($beginning) $beginning = false; else $sql .= ', '; - - $columnAlias = $this->getSqlColumnAlias($mapping['columnName']); - $sql .= $sqlTableAlias . '.' . $this->_conn->quoteIdentifier($mapping['columnName']) - . ' AS ' . $columnAlias; - - $this->_rsm->addFieldResult($dqlAlias, $columnAlias, $fieldName); - } - - // Append foreign keys if necessary. - //FIXME: Evaluate HINT_INCLUDE_META_COLUMNS - //FIXME: Needs to be done in the case of Class Table Inheritance, too - // (see upper block of the if/else) - if ( - ! $this->_em->getConfiguration()->getAllowPartialObjects() && - ! $this->_query->getHint(Query::HINT_FORCE_PARTIAL_LOAD) - ) { - foreach ($class->associationMappings as $assoc) { - if ($assoc->isOwningSide && $assoc->isOneToOne()) { - foreach ($assoc->targetToSourceKeyColumns as $srcColumn) { - $columnAlias = $this->getSqlColumnAlias($srcColumn); - $sql .= ', ' . $sqlTableAlias . '.' . $this->_conn->quoteIdentifier($srcColumn) - . ' AS ' . $columnAlias; - - $this->_rsm->addMetaResult($dqlAlias, $columnAlias, $srcColumn); - } - } - } - } - - } - } - - return $sql; - } - - /** - * Walks down a QuantifiedExpression AST node, thereby generating the appropriate SQL. - * - * @param QuantifiedExpression - * @return string The SQL. - */ - public function walkQuantifiedExpression($qExpr) - { - $sql = ''; - - if ($qExpr->isAll()) $sql .= ' ALL'; - else if ($qExpr->isAny()) $sql .= ' ANY'; - else if ($qExpr->isSome()) $sql .= ' SOME'; - - return $sql .= '(' . $this->walkSubselect($qExpr->getSubselect()) . ')'; - } - - /** - * Walks down a Subselect AST node, thereby generating the appropriate SQL. - * - * @param Subselect - * @return string The SQL. - */ - public function walkSubselect($subselect) - { - $useAliasesBefore = $this->_useSqlTableAliases; - $this->_useSqlTableAliases = true; - - $sql = $this->walkSimpleSelectClause($subselect->getSimpleSelectClause()); - $sql .= $this->walkSubselectFromClause($subselect->getSubselectFromClause()); - $sql .= $subselect->getWhereClause() ? $this->walkWhereClause($subselect->getWhereClause()) : ''; - $sql .= $subselect->getGroupByClause() ? $this->walkGroupByClause($subselect->getGroupByClause()) : ''; - $sql .= $subselect->getHavingClause() ? $this->walkHavingClause($subselect->getHavingClause()) : ''; - $sql .= $subselect->getOrderByClause() ? $this->walkOrderByClause($subselect->getOrderByClause()) : ''; - - $this->_useSqlTableAliases = $useAliasesBefore; - - return $sql; - } - - /** - * Walks down a SubselectFromClause AST node, thereby generating the appropriate SQL. - * - * @param SubselectFromClause - * @return string The SQL. - */ - public function walkSubselectFromClause($subselectFromClause) - { - $sql = ' FROM '; - $identificationVarDecls = $subselectFromClause->getSubselectIdentificationVariableDeclarations(); - $firstIdentificationVarDecl = $identificationVarDecls[0]; - $rangeDecl = $firstIdentificationVarDecl->getRangeVariableDeclaration(); - - $sql .= $this->_conn->quoteIdentifier($rangeDecl->getClassMetadata()->getTableName()) . ' ' - . $this->getSqlTableAlias($rangeDecl->getClassMetadata()->getTableName(), $rangeDecl->getAliasIdentificationVariable()); - - foreach ($firstIdentificationVarDecl->getJoinVariableDeclarations() as $joinVarDecl) { - $sql .= $this->walkJoinVariableDeclaration($joinVarDecl); - } - - return $sql; - } - - /** - * Walks down a SimpleSelectClause AST node, thereby generating the appropriate SQL. - * - * @param SimpleSelectClause - * @return string The SQL. - */ - public function walkSimpleSelectClause($simpleSelectClause) - { - $sql = 'SELECT'; - - if ($simpleSelectClause->isDistinct()) { - $sql .= ' DISTINCT'; - } - - $sql .= $this->walkSimpleSelectExpression($simpleSelectClause->getSimpleSelectExpression()); - - return $sql; - } - - /** - * Walks down a SimpleSelectExpression AST node, thereby generating the appropriate SQL. - * - * @param SimpleSelectExpression - * @return string The SQL. - */ - public function walkSimpleSelectExpression($simpleSelectExpression) - { - $sql = ''; - $expr = $simpleSelectExpression->getExpression(); - - if ($expr instanceof AST\PathExpression) { - $sql .= ' ' . $this->walkPathExpression($expr); - //... - } else if ($expr instanceof AST\AggregateExpression) { - if ( ! $simpleSelectExpression->getFieldIdentificationVariable()) { - $alias = $this->_scalarAliasCounter++; - } else { - $alias = $simpleSelectExpression->getFieldIdentificationVariable(); - } - - $sql .= $this->walkAggregateExpression($expr) . ' AS dctrn__' . $alias; - } else { - // IdentificationVariable - // FIXME: Composite key support, or select all columns? Does that make - // in a subquery? - $class = $this->_queryComponents[$expr]['metadata']; - $sql .= ' ' . $this->getSqlTableAlias($class->getTableName(), $expr) . '.'; - $sql .= $this->_conn->quoteIdentifier($class->getColumnName($class->identifier[0])); - } - - return $sql; - } - - /** - * Walks down an AggregateExpression AST node, thereby generating the appropriate SQL. - * - * @param AggregateExpression - * @return string The SQL. - */ - public function walkAggregateExpression($aggExpression) - { - $sql = ''; - $parts = $aggExpression->pathExpression->getParts(); - $dqlAlias = $aggExpression->pathExpression->getIdentificationVariable(); - $fieldName = $parts[0]; - - $qComp = $this->_queryComponents[$dqlAlias]; - $columnName = $qComp['metadata']->getColumnName($fieldName); - - $sql .= $aggExpression->functionName . '('; - - if ($aggExpression->isDistinct) $sql .= 'DISTINCT '; - - $sql .= $this->getSqlTableAlias($qComp['metadata']->getTableName(), $dqlAlias) . '.' - . $this->_conn->quoteIdentifier($columnName) . ')'; - - return $sql; - } - - /** - * Walks down a GroupByClause AST node, thereby generating the appropriate SQL. - * - * @param GroupByClause - * @return string The SQL. - */ - public function walkGroupByClause($groupByClause) - { - return ' GROUP BY ' . implode( - ', ', array_map(array($this, 'walkGroupByItem'), $groupByClause->getGroupByItems()) - ); - } - - /** - * Walks down a GroupByItem AST node, thereby generating the appropriate SQL. - * - * @param GroupByItem - * @return string The SQL. - */ - public function walkGroupByItem(AST\PathExpression $pathExpr) - { - $parts = $pathExpr->getParts(); - $dqlAlias = $pathExpr->getIdentificationVariable(); - $qComp = $this->_queryComponents[$dqlAlias]; - $columnName = $qComp['metadata']->getColumnName($parts[0]); - - return $this->getSqlTableAlias($qComp['metadata']->getTableName(), $dqlAlias) . '.' - . $this->_conn->quoteIdentifier($columnName); - } - - /** - * Walks down an UpdateStatement AST node, thereby generating the appropriate SQL. - * - * @param UpdateStatement - * @return string The SQL. - */ - public function walkUpdateStatement(AST\UpdateStatement $AST) - { - $this->_useSqlTableAliases = false; - $sql = $this->walkUpdateClause($AST->getUpdateClause()); - - if ($whereClause = $AST->getWhereClause()) { - $sql .= $this->walkWhereClause($whereClause); - } else if ($discSql = $this->_generateDiscriminatorColumnConditionSql($this->_currentRootAlias)) { - $sql .= ' WHERE ' . $discSql; - } - - return $sql; - } - - /** - * Walks down a DeleteStatement AST node, thereby generating the appropriate SQL. - * - * @param DeleteStatement - * @return string The SQL. - */ - public function walkDeleteStatement(AST\DeleteStatement $AST) - { - $this->_useSqlTableAliases = false; - $sql = $this->walkDeleteClause($AST->getDeleteClause()); - - if ($whereClause = $AST->getWhereClause()) { - $sql .= $this->walkWhereClause($whereClause); - } else if ($discSql = $this->_generateDiscriminatorColumnConditionSql($this->_currentRootAlias)) { - $sql .= ' WHERE ' . $discSql; - } - - return $sql; - } - - /** - * Walks down a DeleteClause AST node, thereby generating the appropriate SQL. - * - * @param DeleteClause - * @return string The SQL. - */ - public function walkDeleteClause(AST\DeleteClause $deleteClause) - { - $sql = 'DELETE FROM '; - $class = $this->_em->getClassMetadata($deleteClause->getAbstractSchemaName()); - $sql .= $this->_conn->quoteIdentifier($class->getTableName()); - - if ($this->_useSqlTableAliases) { - $sql .= ' ' . $this->getSqlTableAlias($class->getTableName()); - } - - $this->_currentRootAlias = $deleteClause->getAliasIdentificationVariable(); - - return $sql; - } - - /** - * Walks down an UpdateClause AST node, thereby generating the appropriate SQL. - * - * @param UpdateClause - * @return string The SQL. - */ - public function walkUpdateClause($updateClause) - { - $sql = 'UPDATE '; - $class = $this->_em->getClassMetadata($updateClause->getAbstractSchemaName()); - $sql .= $this->_conn->quoteIdentifier($class->getTableName()); - - if ($this->_useSqlTableAliases) { - $sql .= ' ' . $this->getSqlTableAlias($class->getTableName()); - } - - $this->_currentRootAlias = $updateClause->getAliasIdentificationVariable(); - - $sql .= ' SET ' . implode( - ', ', array_map(array($this, 'walkUpdateItem'), $updateClause->getUpdateItems()) - ); - - return $sql; - } - - /** - * Walks down an UpdateItem AST node, thereby generating the appropriate SQL. - * - * @param UpdateItem - * @return string The SQL. - */ - public function walkUpdateItem($updateItem) - { - $useTableAliasesBefore = $this->_useSqlTableAliases; - $this->_useSqlTableAliases = false; - - $sql = ''; - $dqlAlias = $updateItem->getIdentificationVariable(); - $qComp = $this->_queryComponents[$dqlAlias]; - - if ($this->_useSqlTableAliases) { - $sql .= $this->getSqlTableAlias($qComp['metadata']->getTableName()) . '.'; - } - - $sql .= $this->_conn->quoteIdentifier($qComp['metadata']->getColumnName($updateItem->getField())) . ' = '; - - $newValue = $updateItem->getNewValue(); - - if ($newValue instanceof AST\Node) { - $sql .= $newValue->dispatch($this); - } else if (is_string($newValue)) { - if (strcasecmp($newValue, 'NULL') === 0) { - $sql .= 'NULL'; - } else { - $sql .= $this->_conn->quote($newValue); - } - } - - $this->_useSqlTableAliases = $useTableAliasesBefore; - - return $sql; - } - - /** - * Walks down a WhereClause AST node, thereby generating the appropriate SQL. - * - * @param WhereClause - * @return string The SQL. - */ - public function walkWhereClause($whereClause) - { - $sql = ' WHERE '; - $condExpr = $whereClause->getConditionalExpression(); - - $sql .= implode( - ' OR ', array_map(array($this, 'walkConditionalTerm'), $condExpr->getConditionalTerms()) - ); - - $discrSql = $this->_generateDiscriminatorColumnConditionSql($this->_currentRootAlias); - - if ($discrSql) { - if ($termsSql) $sql .= ' AND'; - - $sql .= ' ' . $discrSql; - } - - return $sql; - } - - /** - * Generates a discriminator column SQL condition for the class with the given DQL alias. - * - * @param string $dqlAlias - * @return string - */ - private function _generateDiscriminatorColumnConditionSql($dqlAlias) - { - $sql = ''; - if ($dqlAlias) { - $class = $this->_queryComponents[$dqlAlias]['metadata']; - - if ($class->isInheritanceTypeSingleTable()) { - $conn = $this->_em->getConnection(); - $values = array($conn->quote($class->discriminatorValue)); - - foreach ($class->subClasses as $subclassName) { - $values[] = $conn->quote($this->_em->getClassMetadata($subclassName)->discriminatorValue); - } - - $discrColumn = $class->discriminatorColumn; - - if ($this->_useSqlTableAliases) { - $sql .= $this->getSqlTableAlias($class->getTableName(), $dqlAlias) . '.'; - } - - $sql .= $this->_conn->quoteIdentifier($discrColumn['name']) . ' IN (' . implode(', ', $values) . ')'; - } - } - - return $sql; - } - - /** - * Walks down a ConditionalTerm AST node, thereby generating the appropriate SQL. - * - * @param ConditionalTerm - * @return string The SQL. - */ - public function walkConditionalTerm($condTerm) - { - return implode( - ' AND ', array_map(array($this, 'walkConditionalFactor'), $condTerm->getConditionalFactors()) - ); - } - - /** - * Walks down a ConditionalFactor AST node, thereby generating the appropriate SQL. - * - * @param ConditionalFactor - * @return string The SQL. - */ - public function walkConditionalFactor($factor) - { - $sql = ''; - - if ($factor->isNot()) $sql .= 'NOT '; - - $primary = $factor->getConditionalPrimary(); - - if ($primary->isSimpleConditionalExpression()) { - $sql .= $primary->getSimpleConditionalExpression()->dispatch($this); - } else if ($primary->isConditionalExpression()) { - $condExpr = $primary->getConditionalExpression(); - $sql .= '(' . implode( - ' OR ', array_map(array($this, 'walkConditionalTerm'), $condExpr->getConditionalTerms()) - ) . ')'; - } - - return $sql; - } - - /** - * Walks down an ExistsExpression AST node, thereby generating the appropriate SQL. - * - * @param ExistsExpression - * @return string The SQL. - */ - public function walkExistsExpression($existsExpr) - { - $sql = ''; - - if ($existsExpr->isNot()) $sql .= ' NOT'; - - $sql .= 'EXISTS (' . $this->walkSubselect($existsExpr->getSubselect()) . ')'; - - return $sql; - } /** - * Walks down a CollectionMemberExpression AST node, thereby generating the appropriate SQL. - * - * @param CollectionMemberExpression - * @return string The SQL. + * Gets an executor that can be used to execute the result of this walker. + * + * @return AbstractExecutor */ - public function walkCollectionMemberExpression($collMemberExpr) + public function getExecutor($AST) { - $sql = $collMemberExpr->isNot ? 'NOT ' : ''; - $sql .= 'EXISTS (SELECT 1 FROM '; - $entityExpr = $collMemberExpr->entityExpression; - $collPathExpr = $collMemberExpr->collectionValuedPathExpression; - $parts = $collPathExpr->getParts(); - $dqlAlias = $collPathExpr->getIdentificationVariable(); - - $class = $this->_queryComponents[$dqlAlias]['metadata']; - - if ($entityExpr instanceof AST\InputParameter) { - $dqlParamKey = $entityExpr->isNamed() ? $entityExpr->getName() : $entityExpr->getPosition(); - $entity = $this->_query->getParameter($dqlParamKey); + $isDeleteStatement = $AST instanceof AST\DeleteStatement; + $isUpdateStatement = $AST instanceof AST\UpdateStatement; + + if ($isDeleteStatement) { + $primaryClass = $this->_em->getClassMetadata( + $AST->deleteClause->abstractSchemaName + ); + + if ($primaryClass->isInheritanceTypeJoined()) { + return new Exec\MultiTableDeleteExecutor($AST, $this); + } else { + return new Exec\SingleTableDeleteUpdateExecutor($AST, $this); + } + } else if ($isUpdateStatement) { + $primaryClass = $this->_em->getClassMetadata( + $AST->updateClause->abstractSchemaName + ); + + if ($primaryClass->isInheritanceTypeJoined()) { + return new Exec\MultiTableUpdateExecutor($AST, $this); + } else { + return new Exec\SingleTableDeleteUpdateExecutor($AST, $this); + } } else { - //TODO - throw DoctrineException::notImplemented(); + return new Exec\SingleSelectExecutor($AST, $this); } - - $assoc = $class->associationMappings[$parts[0]]; - - if ($assoc->isOneToMany()) { - $targetClass = $this->_em->getClassMetadata($assoc->targetEntityName); - $targetTableAlias = $this->getSqlTableAlias($targetClass->primaryTable['name']); - $sourceTableAlias = $this->getSqlTableAlias($class->primaryTable['name'], $dqlAlias); - - $sql .= $this->_conn->quoteIdentifier($targetClass->primaryTable['name']) - . ' ' . $targetTableAlias . ' WHERE '; - - $owningAssoc = $targetClass->associationMappings[$assoc->mappedByFieldName]; - - $first = true; - - foreach ($owningAssoc->targetToSourceKeyColumns as $targetColumn => $sourceColumn) { - if ($first) $first = false; else $sql .= ' AND '; - - $sql .= $sourceTableAlias . '.' . $this->_conn->quoteIdentifier($targetColumn) - . ' = ' - . $targetTableAlias . '.' . $this->_conn->quoteIdentifier($sourceColumn); - } - - $sql .= ' AND '; - $first = true; - - foreach ($targetClass->identifier as $idField) { - if ($first) $first = false; else $sql .= ' AND '; - - $this->_parserResult->addParameterMapping($dqlParamKey, $this->_sqlParamIndex++); - $sql .= $targetTableAlias . '.' - . $this->_conn->quoteIdentifier($targetClass->columnNames[$idField]) . ' = ?'; - } - } else { // many-to-many - $targetClass = $this->_em->getClassMetadata($assoc->targetEntityName); - $sourceTableAlias = $this->getSqlTableAlias($class->primaryTable['name'], $dqlAlias); - $joinTable = $assoc->isOwningSide ? $assoc->joinTable : $targetClass->associationMappings[$assoc->mappedByFieldName]->joinTable; - $joinTableAlias = $this->getSqlTableAlias($joinTable['name']); - $targetTableAlias = $this->getSqlTableAlias($targetClass->primaryTable['name']); - - // join to target table - $sql .= $this->_conn->quoteIdentifier($joinTable['name']) - . ' ' . $joinTableAlias . ' INNER JOIN ' - . $this->_conn->quoteIdentifier($targetClass->primaryTable['name']) - . ' ' . $targetTableAlias . ' ON '; - - // join conditions - $joinColumns = $assoc->isOwningSide ? $joinTable['joinColumns'] : $joinTable['inverseJoinColumns']; - $first = true; - - foreach ($joinColumns as $joinColumn) { - if ($first) $first = false; else $sql .= ' AND '; - - $sql .= $joinTableAlias . '.' . $this->_conn->quoteIdentifier($joinColumn['name']) - . ' = ' - . $sourceTableAlias . '.' . $this->_conn->quoteIdentifier($joinColumn['referencedColumnName']); - } - - $sql .= ' WHERE '; - - $joinColumns = $assoc->isOwningSide ? $joinTable['inverseJoinColumns'] : $joinTable['joinColumns']; - $first = true; - - foreach ($joinColumns as $joinColumn) { - if ($first) $first = false; else $sql .= ' AND '; - - $sql .= $joinTableAlias . '.' . $this->_conn->quoteIdentifier($joinColumn['name']) - . ' = ' - . $targetTableAlias . '.' . $this->_conn->quoteIdentifier($joinColumn['referencedColumnName']); - } - - $sql .= ' AND '; - $first = true; - - foreach ($targetClass->identifier as $idField) { - if ($first) $first = false; else $sql .= ' AND '; - - $this->_parserResult->addParameterMapping($dqlParamKey, $this->_sqlParamIndex++); - $sql .= $targetTableAlias . '.' - . $this->_conn->quoteIdentifier($targetClass->columnNames[$idField]) . ' = ?'; - } - } - - return $sql . ')'; } - /** - * Walks down an EmptyCollectionComparisonExpression AST node, thereby generating the appropriate SQL. - * - * @param EmptyCollectionComparisonExpression - * @return string The SQL. - */ - public function walkEmptyCollectionComparisonExpression($emptyCollCompExpr) - { - $sizeFunc = new AST\Functions\SizeFunction('size'); - $sizeFunc->setCollectionPathExpression($emptyCollCompExpr->getExpression()); - - $sql = $sizeFunc->getSql($this); - $sql .= ($emptyCollCompExpr->isNot() ? ' > 0' : ' = 0'); - - return $sql; - } - - /** - * Walks down a NullComparisonExpression AST node, thereby generating the appropriate SQL. - * - * @param NullComparisonExpression - * @return string The SQL. - */ - public function walkNullComparisonExpression($nullCompExpr) - { - $sql = ''; - $innerExpr = $nullCompExpr->getExpression(); - - if ($innerExpr instanceof AST\InputParameter) { - $dqlParamKey = $innerExpr->isNamed() ? $innerExpr->getName() : $innerExpr->getPosition(); - $this->_parserResult->addParameterMapping($dqlParamKey, $this->_sqlParamIndex++); - $sql .= ' ?';// . ($innerExpr->isNamed() ? ':' . $innerExpr->getName() : '?'); - } else { - $sql .= $this->walkPathExpression($innerExpr); - } - - $sql .= ' IS' . ($nullCompExpr->isNot() ? ' NOT' : '') . ' NULL'; - - return $sql; - } - - /** - * Walks down an InExpression AST node, thereby generating the appropriate SQL. - * - * @param InExpression - * @return string The SQL. - */ - public function walkInExpression($inExpr) - { - $sql = $this->walkPathExpression($inExpr->getPathExpression()); - - if ($inExpr->isNot()) $sql .= ' NOT'; - - $sql .= ' IN ('; - - if ($inExpr->getSubselect()) { - $sql .= $this->walkSubselect($inExpr->getSubselect()); - } else { - $sql .= implode(', ', array_map(array($this, 'walkLiteral'), $inExpr->getLiterals())); - } - - $sql .= ')'; - - return $sql; - } - - /** - * Walks down a literal that represents an AST node, thereby generating the appropriate SQL. - * - * @param mixed - * @return string The SQL. - */ - public function walkLiteral($literal) - { - if ($literal instanceof AST\InputParameter) { - $dqlParamKey = $literal->isNamed() ? $literal->getName() : $literal->getPosition(); - $this->_parserResult->addParameterMapping($dqlParamKey, $this->_sqlParamIndex++); - - return '?'; - } - - return $literal; //TODO: quote() ? - } - - /** - * Walks down a BetweenExpression AST node, thereby generating the appropriate SQL. - * - * @param BetweenExpression - * @return string The SQL. - */ - public function walkBetweenExpression($betweenExpr) - { - $sql = $this->walkArithmeticExpression($betweenExpr->getBaseExpression()); - - if ($betweenExpr->getNot()) $sql .= ' NOT'; - - $sql .= ' BETWEEN ' . $this->walkArithmeticExpression($betweenExpr->getLeftBetweenExpression()) - . ' AND ' . $this->walkArithmeticExpression($betweenExpr->getRightBetweenExpression()); - - return $sql; - } - - /** - * Walks down a LikeExpression AST node, thereby generating the appropriate SQL. - * - * @param LikeExpression - * @return string The SQL. - */ - public function walkLikeExpression($likeExpr) - { - $stringExpr = $likeExpr->getStringExpression(); - $sql = $stringExpr->dispatch($this); - - if ($likeExpr->isNot()) $sql .= ' NOT'; - - $sql .= ' LIKE '; - - if ($likeExpr->getStringPattern() instanceof AST\InputParameter) { - $inputParam = $likeExpr->getStringPattern(); - $dqlParamKey = $inputParam->isNamed() ? $inputParam->getName() : $inputParam->getPosition(); - $this->_parserResult->addParameterMapping($dqlParamKey, $this->_sqlParamIndex++); - $sql .= '?'; - } else { - $sql .= $this->_conn->quote($likeExpr->getStringPattern()); - } - - if ($likeExpr->getEscapeChar()) { - $sql .= ' ESCAPE ' . $this->_conn->quote($likeExpr->getEscapeChar()); - } - - return $sql; - } - - /** - * Walks down a StateFieldPathExpression AST node, thereby generating the appropriate SQL. - * - * @param StateFieldPathExpression - * @return string The SQL. - */ - public function walkStateFieldPathExpression($stateFieldPathExpression) - { - return $this->walkPathExpression($stateFieldPathExpression); - } - - /** - * Walks down a ComparisonExpression AST node, thereby generating the appropriate SQL. - * - * @param ComparisonExpression - * @return string The SQL. - */ - public function walkComparisonExpression($compExpr) - { - $sql = ''; - $leftExpr = $compExpr->getLeftExpression(); - $rightExpr = $compExpr->getRightExpression(); - - if ($leftExpr instanceof AST\Node) { - $sql .= $leftExpr->dispatch($this); - } else { - $sql .= $this->_conn->quote($leftExpr); - } - - $sql .= ' ' . $compExpr->getOperator() . ' '; - - if ($rightExpr instanceof AST\Node) { - $sql .= $rightExpr->dispatch($this); - } else { - $sql .= $this->_conn->quote($rightExpr); - } - - return $sql; - } - - /** - * Walks down an InputParameter AST node, thereby generating the appropriate SQL. - * - * @param InputParameter - * @return string The SQL. - */ - public function walkInputParameter($inputParam) - { - $dqlParamKey = $inputParam->isNamed() ? $inputParam->getName() : $inputParam->getPosition(); - $this->_parserResult->addParameterMapping($dqlParamKey, $this->_sqlParamIndex++); - - return '?'; - } - - /** - * Walks down an ArithmeticExpression AST node, thereby generating the appropriate SQL. - * - * @param ArithmeticExpression - * @return string The SQL. - */ - public function walkArithmeticExpression($arithmeticExpr) - { - return ($arithmeticExpr->isSimpleArithmeticExpression()) - ? $this->walkSimpleArithmeticExpression($arithmeticExpr->simpleArithmeticExpression) - : $this->walkSubselect($arithmeticExpr->subselect); - } - - /** - * Walks down an ArithmeticTerm AST node, thereby generating the appropriate SQL. - * - * @param mixed - * @return string The SQL. - */ - public function walkArithmeticTerm($term) - { - if (is_string($term)) return $term; - - return implode( - ' ', array_map(array($this, 'walkArithmeticFactor'), $term->getArithmeticFactors()) - ); - } - - /** - * Walks down a StringPrimary that represents an AST node, thereby generating the appropriate SQL. - * - * @param mixed - * @return string The SQL. - */ - public function walkStringPrimary($stringPrimary) - { - return (is_string($stringPrimary)) - ? $this->_conn->quote($stringPrimary) - : $stringPrimary->dispatch($this); - } - - /** - * Walks down an ArithmeticFactor that represents an AST node, thereby generating the appropriate SQL. - * - * @param mixed - * @return string The SQL. - */ - public function walkArithmeticFactor($factor) - { - if (is_string($factor)) return $factor; - - $sql = ''; - $primary = $factor->getArithmeticPrimary(); - - if (is_numeric($primary)) { - $sql .= $primary; //TODO: quote() ? - } else if (is_string($primary)) { - $sql .= $this->_conn->quote($primary); - } else if ($primary instanceof AST\SimpleArithmeticExpression) { - $sql .= '(' . $this->walkSimpleArithmeticExpression($primary) . ')'; - } else if ($primary instanceof AST\Node) { - $sql .= $primary->dispatch($this); - } - - return $sql; - } - - /** - * Walks down an SimpleArithmeticExpression AST node, thereby generating the appropriate SQL. - * - * @param SimpleArithmeticExpression - * @return string The SQL. - */ - public function walkSimpleArithmeticExpression($simpleArithmeticExpr) - { - return implode( - ' ', array_map(array($this, 'walkArithmeticTerm'), $simpleArithmeticExpr->getArithmeticTerms()) - ); - } - - /** - * Walks down a PathExpression AST node, thereby generating the appropriate SQL. - * - * @param mixed - * @return string The SQL. - */ - public function walkPathExpression($pathExpr) - { - $sql = ''; - $pathExprType = $pathExpr->getType(); - - if ($pathExprType == AST\PathExpression::TYPE_STATE_FIELD) { - $parts = $pathExpr->getParts(); - $numParts = count($parts); - $dqlAlias = $pathExpr->getIdentificationVariable(); - $fieldName = $parts[$numParts-1]; - $qComp = $this->_queryComponents[$dqlAlias]; - $class = $qComp['metadata']; - - if ($this->_useSqlTableAliases) { - if ($class->isInheritanceTypeJoined() && isset($class->fieldMappings[$fieldName]['inherited'])) { - $sql .= $this->getSqlTableAlias( - $this->_em->getClassMetadata($class->fieldMappings[$fieldName]['inherited'])->getTableName(), - $dqlAlias - ) . '.'; - } else { - $sql .= $this->getSqlTableAlias($class->getTableName(), $dqlAlias) . '.'; - } - } - - if (isset($class->associationMappings[$fieldName])) { - //FIXME: Inverse side support - //FIXME: Throw exception on composite key - $sql .= $this->_conn->quoteIdentifier( - $class->associationMappings[$fieldName]->joinColumns[0]['name'] - ); - } else { - $sql .= $this->_conn->quoteIdentifier($class->getColumnName($fieldName)); - } - } else if ($pathExprType == AST\PathExpression::TYPE_COLLECTION_VALUED_ASSOCIATION) { - throw DoctrineException::updateMe("Not yet implemented."); - } else { - throw DoctrineException::updateMe("Encountered invalid PathExpression during SQL construction."); - } - - return $sql; - } - /** * Generates a unique, short SQL table alias. * @@ -1481,39 +258,1263 @@ class SqlWalker implements TreeWalker return $sql; } + + + /** + * Walks down a SelectStatement AST node, thereby generating the appropriate SQL. + * + * @return string The SQL. + */ + public function walkSelectStatement(AST\SelectStatement $AST) + { + $sql = $this->walkSelectClause($AST->selectClause); + $sql .= $this->walkFromClause($AST->fromClause); + + if ($whereClause = $AST->whereClause) { + $sql .= $this->walkWhereClause($whereClause); + } else if ($discSql = $this->_generateDiscriminatorColumnConditionSql($this->_currentRootAlias)) { + $sql .= ' WHERE ' . $discSql; + } + + $sql .= $AST->groupByClause ? $this->walkGroupByClause($AST->groupByClause) : ''; + $sql .= $AST->havingClause ? $this->walkHavingClause($AST->havingClause) : ''; + $sql .= $AST->orderByClause ? $this->walkOrderByClause($AST->orderByClause) : ''; + + $q = $this->getQuery(); + $sql = $this->getConnection()->getDatabasePlatform()->modifyLimitQuery( + $sql, $q->getMaxResults(), $q->getFirstResult() + ); + + return $sql; + } /** - * Gets an executor that can be used to execute the result of this walker. - * - * @return AbstractExecutor + * Walks down an UpdateStatement AST node, thereby generating the appropriate SQL. + * + * @param UpdateStatement + * @return string The SQL. */ - public function getExecutor($AST) + public function walkUpdateStatement(AST\UpdateStatement $AST) { - $isDeleteStatement = $AST instanceof AST\DeleteStatement; - $isUpdateStatement = $AST instanceof AST\UpdateStatement; - - if ($isDeleteStatement) { - $primaryClass = $this->_em->getClassMetadata( - $AST->getDeleteClause()->getAbstractSchemaName() - ); - - if ($primaryClass->isInheritanceTypeJoined()) { - return new Exec\MultiTableDeleteExecutor($AST, $this); - } else { - return new Exec\SingleTableDeleteUpdateExecutor($AST, $this); - } - } else if ($isUpdateStatement) { - $primaryClass = $this->_em->getClassMetadata( - $AST->getUpdateClause()->getAbstractSchemaName() - ); - - if ($primaryClass->isInheritanceTypeJoined()) { - return new Exec\MultiTableUpdateExecutor($AST, $this); - } else { - return new Exec\SingleTableDeleteUpdateExecutor($AST, $this); - } - } else { - return new Exec\SingleSelectExecutor($AST, $this); + $this->_useSqlTableAliases = false; + $sql = $this->walkUpdateClause($AST->updateClause); + + if ($whereClause = $AST->whereClause) { + $sql .= $this->walkWhereClause($whereClause); + } else if ($discSql = $this->_generateDiscriminatorColumnConditionSql($this->_currentRootAlias)) { + $sql .= ' WHERE ' . $discSql; } + + return $sql; + } + + /** + * Walks down a DeleteStatement AST node, thereby generating the appropriate SQL. + * + * @param DeleteStatement + * @return string The SQL. + */ + public function walkDeleteStatement(AST\DeleteStatement $AST) + { + $this->_useSqlTableAliases = false; + $sql = $this->walkDeleteClause($AST->deleteClause); + + if ($whereClause = $AST->whereClause) { + $sql .= $this->walkWhereClause($whereClause); + } else if ($discSql = $this->_generateDiscriminatorColumnConditionSql($this->_currentRootAlias)) { + $sql .= ' WHERE ' . $discSql; + } + + return $sql; + } + + + /** + * Walks down an IdentificationVariable (no AST node associated), thereby generating the SQL. + * + * @param string + * @return string The SQL. + */ + public function walkIdentificationVariable($identVariable) + { + $qComp = $this->_queryComponents[$identVariable]; + $class = $qComp['metadata']; + + if ( ! isset($this->_selectedClasses[$identVariable])) { + $this->_selectedClasses[$identVariable] = $class; + } + + return $this->_dqlToSqlAliasMap[$class->getTableName()]; + } + + + /** + * Walks down a SelectClause AST node, thereby generating the appropriate SQL. + * + * @return string The SQL. + */ + public function walkSelectClause($selectClause) + { + $sql = 'SELECT ' . (($selectClause->isDistinct) ? 'DISTINCT ' : '') . implode( + ', ', array_map(array($this, 'walkSelectExpression'), $selectClause->selectExpressions) + ); + + foreach ($this->_selectedClasses as $dqlAlias => $class) { + if ($this->_queryComponents[$dqlAlias]['relation'] === null) { + $this->_rsm->addEntityResult($class->name, $dqlAlias); + } else { + $this->_rsm->addJoinedEntityResult( + $class->name, $dqlAlias, + $this->_queryComponents[$dqlAlias]['parent'], + $this->_queryComponents[$dqlAlias]['relation'] + ); + } + + if ($class->isInheritanceTypeSingleTable() || $class->isInheritanceTypeJoined()) { + $rootClass = $this->_em->getClassMetadata($class->rootEntityName); + $tblAlias = $this->getSqlTableAlias($rootClass->getTableName(), $dqlAlias); + $discrColumn = $rootClass->discriminatorColumn; + $columnAlias = $this->getSqlColumnAlias($discrColumn['name']); + $sql .= ", $tblAlias." . $this->_conn->quoteIdentifier($discrColumn['name']) + . ' AS ' . $columnAlias; + + $this->_rsm->setDiscriminatorColumn($dqlAlias, $columnAlias); + $this->_rsm->addMetaResult($dqlAlias, $columnAlias, $discrColumn['fieldName']); + } + } + + return $sql; + } + + /** + * Walks down a FromClause AST node, thereby generating the appropriate SQL. + * + * @return string The SQL. + */ + public function walkFromClause($fromClause) + { + $sql = ' FROM '; + $identificationVarDecls = $fromClause->identificationVariableDeclarations; + $firstIdentificationVarDecl = $identificationVarDecls[0]; + $rangeDecl = $firstIdentificationVarDecl->rangeVariableDeclaration; + $dqlAlias = $rangeDecl->aliasIdentificationVariable; + + $this->_currentRootAlias = $dqlAlias; + $class = $rangeDecl->classMetadata; + + $sql .= $this->_conn->quoteIdentifier($class->getTableName()) . ' ' + . $this->getSqlTableAlias($class->getTableName(), $dqlAlias); + + if ($class->isInheritanceTypeJoined()) { + $sql .= $this->_generateClassTableInheritanceJoins($class, $dqlAlias); + } + + foreach ($firstIdentificationVarDecl->joinVariableDeclarations as $joinVarDecl) { + $sql .= $this->walkJoinVariableDeclaration($joinVarDecl); + } + + return $sql; + } + + /** + * Walks down a FunctionNode AST node, thereby generating the appropriate SQL. + * + * @return string The SQL. + */ + public function walkFunction($function) + { + return $function->getSql($this); + } + + /** + * Walks down an OrderByClause AST node, thereby generating the appropriate SQL. + * + * @param OrderByClause + * @return string The SQL. + */ + public function walkOrderByClause($orderByClause) + { + // OrderByClause ::= "ORDER" "BY" OrderByItem {"," OrderByItem}* + return ' ORDER BY ' . implode( + ', ', array_map(array($this, 'walkOrderByItem'), $orderByClause->orderByItems) + ); + } + + /** + * Walks down an OrderByItem AST node, thereby generating the appropriate SQL. + * + * @param OrderByItem + * @return string The SQL. + */ + public function walkOrderByItem($orderByItem) + { + $expr = $orderByItem->expression; + $parts = $expr->parts; + $dqlAlias = $expr->identificationVariable; + $qComp = $this->_queryComponents[$dqlAlias]; + $columnName = $qComp['metadata']->getColumnName($parts[0]); + + return $this->getSqlTableAlias($qComp['metadata']->getTableName(), $dqlAlias) . '.' + . $this->_conn->quoteIdentifier($columnName) . ' ' . strtoupper($orderByItem->type); + } + + /** + * Walks down a HavingClause AST node, thereby generating the appropriate SQL. + * + * @param HavingClause + * @return string The SQL. + */ + public function walkHavingClause($havingClause) + { + $condExpr = $havingClause->getConditionalExpression(); + + return ' HAVING ' . implode( + ' OR ', array_map(array($this, 'walkConditionalTerm'), $condExpr->conditionalTerms) + ); + } + + /** + * Walks down a JoinVariableDeclaration AST node and creates the corresponding SQL. + * + * @param JoinVariableDeclaration $joinVarDecl + * @return string The SQL. + */ + public function walkJoinVariableDeclaration($joinVarDecl) + { + $join = $joinVarDecl->join; + $joinType = $join->joinType; + + if ($joinType == AST\Join::JOIN_TYPE_LEFT || $joinType == AST\Join::JOIN_TYPE_LEFTOUTER) { + $sql = ' LEFT JOIN '; + } else { + $sql = ' INNER JOIN '; + } + + $joinAssocPathExpr = $join->joinAssociationPathExpression; + $joinedDqlAlias = $join->aliasIdentificationVariable; + $sourceQComp = $this->_queryComponents[$joinAssocPathExpr->identificationVariable]; + $targetQComp = $this->_queryComponents[$joinedDqlAlias]; + + $targetTableName = $targetQComp['metadata']->getTableName(); + $targetTableAlias = $this->getSqlTableAlias($targetTableName, $joinedDqlAlias); + $sourceTableAlias = $this->getSqlTableAlias( + $sourceQComp['metadata']->getTableName(), $joinAssocPathExpr->identificationVariable + ); + + // Ensure we got the owning side, since it has all mapping info + if ( ! $targetQComp['relation']->isOwningSide()) { + $assoc = $targetQComp['metadata']->getAssociationMapping($targetQComp['relation']->getMappedByFieldName()); + } else { + $assoc = $targetQComp['relation']; + } + + if ($assoc->isOneToOne()) { + $sql .= $this->_conn->quoteIdentifier($targetTableName) . ' ' . $targetTableAlias . ' ON '; + $joinColumns = $assoc->getSourceToTargetKeyColumns(); + $first = true; + + foreach ($joinColumns as $sourceColumn => $targetColumn) { + if ( ! $first) { + $sql .= ' AND '; + } else { + $first = false; + } + + if ($targetQComp['relation']->isOwningSide()) { + $sql .= $sourceTableAlias . '.' . $this->_conn->quoteIdentifier($sourceColumn) + . ' = ' + . $targetTableAlias . '.' . $this->_conn->quoteIdentifier($targetColumn); + } else { + $sql .= $sourceTableAlias . '.' . $this->_conn->quoteIdentifier($targetColumn) + . ' = ' + . $targetTableAlias . '.' . $this->_conn->quoteIdentifier($sourceColumn); + } + } + } else if ($assoc->isManyToMany()) { + // Join relation table + $joinTable = $assoc->getJoinTable(); + $joinTableAlias = $this->getSqlTableAlias($joinTable['name']); + $sql .= $this->_conn->quoteIdentifier($joinTable['name']) . ' ' . $joinTableAlias . ' ON '; + + if ($targetQComp['relation']->isOwningSide) { + $sourceToRelationJoinColumns = $assoc->getSourceToRelationKeyColumns(); + + foreach ($sourceToRelationJoinColumns as $sourceColumn => $relationColumn) { + $sql .= $sourceTableAlias . '.' . $this->_conn->quoteIdentifier($sourceColumn) + . ' = ' + . $joinTableAlias . '.' . $this->_conn->quoteIdentifier($relationColumn); + } + } else { + $targetToRelationJoinColumns = $assoc->getTargetToRelationKeyColumns(); + + foreach ($targetToRelationJoinColumns as $targetColumn => $relationColumn) { + $sql .= $sourceTableAlias . '.' . $this->_conn->quoteIdentifier($targetColumn) + . ' = ' + . $joinTableAlias . '.' . $this->_conn->quoteIdentifier($relationColumn); + } + } + + // Join target table + $sql .= ($joinType == AST\Join::JOIN_TYPE_LEFT || $joinType == AST\Join::JOIN_TYPE_LEFTOUTER) + ? ' LEFT JOIN ' : ' INNER JOIN '; + $sql .= $this->_conn->quoteIdentifier($targetTableName) . ' ' . $targetTableAlias . ' ON '; + + if ($targetQComp['relation']->isOwningSide) { + $targetToRelationJoinColumns = $assoc->getTargetToRelationKeyColumns(); + + foreach ($targetToRelationJoinColumns as $targetColumn => $relationColumn) { + $sql .= $targetTableAlias . '.' . $this->_conn->quoteIdentifier($targetColumn) + . ' = ' + . $joinTableAlias . '.' . $this->_conn->quoteIdentifier($relationColumn); + } + } else { + $sourceToRelationJoinColumns = $assoc->getSourceToRelationKeyColumns(); + + foreach ($sourceToRelationJoinColumns as $sourceColumn => $relationColumn) { + $sql .= $targetTableAlias . '.' . $this->_conn->quoteIdentifier($sourceColumn) + . ' = ' + . $joinTableAlias . '.' . $this->_conn->quoteIdentifier($relationColumn); + } + } + } + + $discrSql = $this->_generateDiscriminatorColumnConditionSql($joinedDqlAlias); + + if ($discrSql) { + $sql .= ' AND ' . $discrSql; + } + + if ($targetQComp['metadata']->isInheritanceTypeJoined()) { + $sql .= $this->_generateClassTableInheritanceJoins($targetQComp['metadata'], $joinedDqlAlias); + } + + return $sql; + } + + /** + * Walks down a SelectExpression AST node and generates the corresponding SQL. + * + * @param SelectExpression $selectExpression + * @return string The SQL. + */ + public function walkSelectExpression($selectExpression) + { + $sql = ''; + $expr = $selectExpression->expression; + + if ($expr instanceof AST\PathExpression) { + if ($expr->type == AST\PathExpression::TYPE_STATE_FIELD) { + $parts = $expr->parts; + $numParts = count($parts); + $dqlAlias = $expr->identificationVariable; + $fieldName = $parts[$numParts - 1]; + $qComp = $this->_queryComponents[$dqlAlias]; + $class = $qComp['metadata']; + + if ( ! isset($this->_selectedClasses[$dqlAlias])) { + $this->_selectedClasses[$dqlAlias] = $class; + } + + $sqlTableAlias = $this->getSqlTableAlias($class->getTableName(), $dqlAlias); + $columnName = $class->getColumnName($fieldName); + $columnAlias = $this->getSqlColumnAlias($columnName); + $sql .= $sqlTableAlias . '.' . $this->_conn->quoteIdentifier($columnName) + . ' AS ' . $columnAlias; + + $this->_rsm->addFieldResult($dqlAlias, $columnAlias, $fieldName); + } else { + throw DoctrineException::updateMe( + "Encountered invalid PathExpression during SQL construction." + ); + } + } else if ($expr instanceof AST\AggregateExpression) { + if ( ! $selectExpression->fieldIdentificationVariable) { + $resultAlias = $this->_scalarResultCounter++; + } else { + $resultAlias = $selectExpression->fieldIdentificationVariable; + } + + $columnAlias = 'sclr' . $this->_aliasCounter++; + $sql .= $this->walkAggregateExpression($expr) . ' AS ' . $columnAlias; + + $this->_rsm->addScalarResult($columnAlias, $resultAlias); + } else if ($expr instanceof AST\Subselect) { + $sql .= $this->walkSubselect($expr); + } else if ($expr instanceof AST\Functions\FunctionNode) { + if ( ! $selectExpression->fieldIdentificationVariable) { + $resultAlias = $this->_scalarResultCounter++; + } else { + $resultAlias = $selectExpression->fieldIdentificationVariable; + } + + $columnAlias = 'sclr' . $this->_aliasCounter++; + $sql .= $this->walkFunction($expr) . ' AS ' . $columnAlias; + + $this->_rsm->addScalarResult($columnAlias, $resultAlias); + } else { + // IdentificationVariable + $dqlAlias = $expr; + $queryComp = $this->_queryComponents[$dqlAlias]; + $class = $queryComp['metadata']; + + if ( ! isset($this->_selectedClasses[$dqlAlias])) { + $this->_selectedClasses[$dqlAlias] = $class; + } + + $beginning = true; + if ($class->isInheritanceTypeJoined()) { + // Select all fields from the queried class + foreach ($class->fieldMappings as $fieldName => $mapping) { + if (isset($mapping['inherited'])) { + $tableName = $this->_em->getClassMetadata($mapping['inherited'])->primaryTable['name']; + } else { + $tableName = $class->primaryTable['name']; + } + + if ($beginning) $beginning = false; else $sql .= ', '; + + $sqlTableAlias = $this->getSqlTableAlias($tableName, $dqlAlias); + $columnAlias = $this->getSqlColumnAlias($mapping['columnName']); + $sql .= $sqlTableAlias . '.' . $this->_conn->quoteIdentifier($mapping['columnName']) + . ' AS ' . $columnAlias; + + $this->_rsm->addFieldResult($dqlAlias, $columnAlias, $fieldName); + } + + // Add any additional fields of subclasses (not inherited fields) + foreach ($class->subClasses as $subClassName) { + $subClass = $this->_em->getClassMetadata($subClassName); + + foreach ($subClass->fieldMappings as $fieldName => $mapping) { + if (isset($mapping['inherited'])) { + continue; + } + + if ($beginning) $beginning = false; else $sql .= ', '; + + $sqlTableAlias = $this->getSqlTableAlias($subClass->primaryTable['name'], $dqlAlias); + $columnAlias = $this->getSqlColumnAlias($mapping['columnName']); + $sql .= $sqlTableAlias . '.' . $this->_conn->quoteIdentifier($mapping['columnName']) + . ' AS ' . $columnAlias; + + $this->_rsm->addFieldResult($dqlAlias, $columnAlias, $fieldName); + } + } + } else { + $fieldMappings = $class->fieldMappings; + + foreach ($class->subClasses as $subclassName) { + $fieldMappings = array_merge( + $fieldMappings, + $this->_em->getClassMetadata($subclassName)->fieldMappings + ); + } + + $sqlTableAlias = $this->getSqlTableAlias($class->getTableName(), $dqlAlias); + + foreach ($fieldMappings as $fieldName => $mapping) { + if ($beginning) $beginning = false; else $sql .= ', '; + + $columnAlias = $this->getSqlColumnAlias($mapping['columnName']); + $sql .= $sqlTableAlias . '.' . $this->_conn->quoteIdentifier($mapping['columnName']) + . ' AS ' . $columnAlias; + + $this->_rsm->addFieldResult($dqlAlias, $columnAlias, $fieldName); + } + + // Append foreign keys if necessary. + //FIXME: Evaluate HINT_INCLUDE_META_COLUMNS + //FIXME: Needs to be done in the case of Class Table Inheritance, too + // (see upper block of the if/else) + if ( + ! $this->_em->getConfiguration()->getAllowPartialObjects() && + ! $this->_query->getHint(Query::HINT_FORCE_PARTIAL_LOAD) + ) { + foreach ($class->associationMappings as $assoc) { + if ($assoc->isOwningSide && $assoc->isOneToOne()) { + foreach ($assoc->targetToSourceKeyColumns as $srcColumn) { + $columnAlias = $this->getSqlColumnAlias($srcColumn); + $sql .= ', ' . $sqlTableAlias . '.' + . $this->_conn->quoteIdentifier($srcColumn) + . ' AS ' . $columnAlias; + + $this->_rsm->addMetaResult($dqlAlias, $columnAlias, $srcColumn); + } + } + } + } + + } + } + + return $sql; + } + + /** + * Walks down a QuantifiedExpression AST node, thereby generating the appropriate SQL. + * + * @param QuantifiedExpression + * @return string The SQL. + */ + public function walkQuantifiedExpression($qExpr) + { + return ' ' . strtoupper($qExpr->type) + . '(' . $this->walkSubselect($qExpr->getSubselect()) . ')'; + } + + /** + * Walks down a Subselect AST node, thereby generating the appropriate SQL. + * + * @param Subselect + * @return string The SQL. + */ + public function walkSubselect($subselect) + { + $useAliasesBefore = $this->_useSqlTableAliases; + $this->_useSqlTableAliases = true; + + $sql = $this->walkSimpleSelectClause($subselect->simpleSelectClause); + $sql .= $this->walkSubselectFromClause($subselect->subselectFromClause); + $sql .= $subselect->whereClause ? $this->walkWhereClause($subselect->whereClause) : ''; + $sql .= $subselect->groupByClause ? $this->walkGroupByClause($subselect->groupByClause) : ''; + $sql .= $subselect->havingClause ? $this->walkHavingClause($subselect->havingClause) : ''; + $sql .= $subselect->orderByClause ? $this->walkOrderByClause($subselect->orderByClause) : ''; + + $this->_useSqlTableAliases = $useAliasesBefore; + + return $sql; + } + + /** + * Walks down a SubselectFromClause AST node, thereby generating the appropriate SQL. + * + * @param SubselectFromClause + * @return string The SQL. + */ + public function walkSubselectFromClause($subselectFromClause) + { + $identificationVarDecls = $subselectFromClause->identificationVariableDeclarations; + $firstIdentificationVarDecl = $identificationVarDecls[0]; + $rangeDecl = $firstIdentificationVarDecl->rangeVariableDeclaration; + $tblName = $rangeDecl->classMetadata->getTableName(); + + $sql = ' FROM ' . $this->_conn->quoteIdentifier($tblName) . ' ' + . $this->getSqlTableAlias($tblName, $rangeDecl->aliasIdentificationVariable); + + foreach ($firstIdentificationVarDecl->joinVariableDeclarations as $joinVarDecl) { + $sql .= $this->walkJoinVariableDeclaration($joinVarDecl); + } + + return $sql; + } + + /** + * Walks down a SimpleSelectClause AST node, thereby generating the appropriate SQL. + * + * @param SimpleSelectClause + * @return string The SQL. + */ + public function walkSimpleSelectClause($simpleSelectClause) + { + return 'SELECT' . ($simpleSelectClause->isDistinct ? ' DISTINCT' : '') + . $this->walkSimpleSelectExpression($simpleSelectClause->simpleSelectExpression); + } + + /** + * Walks down a SimpleSelectExpression AST node, thereby generating the appropriate SQL. + * + * @param SimpleSelectExpression + * @return string The SQL. + */ + public function walkSimpleSelectExpression($simpleSelectExpression) + { + $sql = ''; + $expr = $simpleSelectExpression->expression; + + if ($expr instanceof AST\PathExpression) { + $sql .= ' ' . $this->walkPathExpression($expr); + //... + } else if ($expr instanceof AST\AggregateExpression) { + if ( ! $simpleSelectExpression->fieldIdentificationVariable) { + $alias = $this->_scalarAliasCounter++; + } else { + $alias = $simpleSelectExpression->fieldIdentificationVariable; + } + + $sql .= $this->walkAggregateExpression($expr) . ' AS dctrn__' . $alias; + } else { + // IdentificationVariable + // FIXME: Composite key support, or select all columns? Does that make + // in a subquery? + $class = $this->_queryComponents[$expr]['metadata']; + $sql .= ' ' . $this->getSqlTableAlias($class->getTableName(), $expr) . '.' + . $this->_conn->quoteIdentifier($class->getColumnName($class->identifier[0])); + } + + return $sql; + } + + /** + * Walks down an AggregateExpression AST node, thereby generating the appropriate SQL. + * + * @param AggregateExpression + * @return string The SQL. + */ + public function walkAggregateExpression($aggExpression) + { + $sql = ''; + $parts = $aggExpression->pathExpression->parts; + $dqlAlias = $aggExpression->pathExpression->identificationVariable; + $fieldName = $parts[0]; + + $qComp = $this->_queryComponents[$dqlAlias]; + $columnName = $qComp['metadata']->getColumnName($fieldName); + + return $aggExpression->functionName . '(' . ($aggExpression->isDistinct ? 'DISTINCT ' : '') + . $this->getSqlTableAlias($qComp['metadata']->getTableName(), $dqlAlias) . '.' + . $this->_conn->quoteIdentifier($columnName) . ')'; + } + + /** + * Walks down a GroupByClause AST node, thereby generating the appropriate SQL. + * + * @param GroupByClause + * @return string The SQL. + */ + public function walkGroupByClause($groupByClause) + { + return ' GROUP BY ' . implode( + ', ', array_map(array($this, 'walkGroupByItem'), $groupByClause->groupByItems) + ); + } + + /** + * Walks down a GroupByItem AST node, thereby generating the appropriate SQL. + * + * @param GroupByItem + * @return string The SQL. + */ + public function walkGroupByItem(AST\PathExpression $pathExpr) + { + $parts = $pathExpr->parts; + $dqlAlias = $pathExpr->identificationVariable; + $qComp = $this->_queryComponents[$dqlAlias]; + $columnName = $qComp['metadata']->getColumnName($parts[0]); + + return $this->getSqlTableAlias($qComp['metadata']->getTableName(), $dqlAlias) . '.' + . $this->_conn->quoteIdentifier($columnName); + } + + /** + * Walks down a DeleteClause AST node, thereby generating the appropriate SQL. + * + * @param DeleteClause + * @return string The SQL. + */ + public function walkDeleteClause(AST\DeleteClause $deleteClause) + { + $sql = 'DELETE FROM '; + $class = $this->_em->getClassMetadata($deleteClause->abstractSchemaName); + $sql .= $this->_conn->quoteIdentifier($class->getTableName()); + + if ($this->_useSqlTableAliases) { + $sql .= ' ' . $this->getSqlTableAlias($class->getTableName()); + } + + $this->_currentRootAlias = $deleteClause->aliasIdentificationVariable; + + return $sql; + } + + /** + * Walks down an UpdateClause AST node, thereby generating the appropriate SQL. + * + * @param UpdateClause + * @return string The SQL. + */ + public function walkUpdateClause($updateClause) + { + $sql = 'UPDATE '; + $class = $this->_em->getClassMetadata($updateClause->abstractSchemaName); + $sql .= $this->_conn->quoteIdentifier($class->getTableName()); + + if ($this->_useSqlTableAliases) { + $sql .= ' ' . $this->getSqlTableAlias($class->getTableName()); + } + + $this->_currentRootAlias = $updateClause->aliasIdentificationVariable; + + $sql .= ' SET ' . implode( + ', ', array_map(array($this, 'walkUpdateItem'), $updateClause->updateItems) + ); + + return $sql; + } + + /** + * Walks down an UpdateItem AST node, thereby generating the appropriate SQL. + * + * @param UpdateItem + * @return string The SQL. + */ + public function walkUpdateItem($updateItem) + { + $useTableAliasesBefore = $this->_useSqlTableAliases; + $this->_useSqlTableAliases = false; + + $sql = ''; + $dqlAlias = $updateItem->identificationVariable; + $qComp = $this->_queryComponents[$dqlAlias]; + + if ($this->_useSqlTableAliases) { + $sql .= $this->getSqlTableAlias($qComp['metadata']->getTableName()) . '.'; + } + + $sql .= $this->_conn->quoteIdentifier($qComp['metadata']->getColumnName($updateItem->field)) . ' = '; + + $newValue = $updateItem->newValue; + + if ($newValue instanceof AST\Node) { + $sql .= $newValue->dispatch($this); + } else if (is_string($newValue)) { + if (strcasecmp($newValue, 'NULL') === 0) { + $sql .= 'NULL'; + } else { + $sql .= $this->_conn->quote($newValue); + } + } + + $this->_useSqlTableAliases = $useTableAliasesBefore; + + return $sql; + } + + /** + * Walks down a WhereClause AST node, thereby generating the appropriate SQL. + * + * @param WhereClause + * @return string The SQL. + */ + public function walkWhereClause($whereClause) + { + $sql = ' WHERE '; + $condExpr = $whereClause->conditionalExpression; + + $sql .= implode( + ' OR ', array_map(array($this, 'walkConditionalTerm'), $condExpr->conditionalTerms) + ); + + $discrSql = $this->_generateDiscriminatorColumnConditionSql($this->_currentRootAlias); + + if ($discrSql) { + if ($termsSql) $sql .= ' AND'; + + $sql .= ' ' . $discrSql; + } + + return $sql; + } + + /** + * Generates a discriminator column SQL condition for the class with the given DQL alias. + * + * @param string $dqlAlias + * @return string + */ + private function _generateDiscriminatorColumnConditionSql($dqlAlias) + { + $sql = ''; + if ($dqlAlias) { + $class = $this->_queryComponents[$dqlAlias]['metadata']; + + if ($class->isInheritanceTypeSingleTable()) { + $conn = $this->_em->getConnection(); + $values = array($conn->quote($class->discriminatorValue)); + + foreach ($class->subClasses as $subclassName) { + $values[] = $conn->quote($this->_em->getClassMetadata($subclassName)->discriminatorValue); + } + + $discrColumn = $class->discriminatorColumn; + + if ($this->_useSqlTableAliases) { + $sql .= $this->getSqlTableAlias($class->getTableName(), $dqlAlias) . '.'; + } + + $sql .= $this->_conn->quoteIdentifier($discrColumn['name']) . ' IN (' . implode(', ', $values) . ')'; + } + } + + return $sql; + } + + /** + * Walks down a ConditionalTerm AST node, thereby generating the appropriate SQL. + * + * @param ConditionalTerm + * @return string The SQL. + */ + public function walkConditionalTerm($condTerm) + { + return implode( + ' AND ', array_map(array($this, 'walkConditionalFactor'), $condTerm->conditionalFactors) + ); + } + + /** + * Walks down a ConditionalFactor AST node, thereby generating the appropriate SQL. + * + * @param ConditionalFactor + * @return string The SQL. + */ + public function walkConditionalFactor($factor) + { + $sql = ($factor->not) ? 'NOT ' : ''; + + $primary = $factor->conditionalPrimary; + + if ($primary->isSimpleConditionalExpression()) { + $sql .= $primary->simpleConditionalExpression->dispatch($this); + } else if ($primary->isConditionalExpression()) { + $condExpr = $primary->conditionalExpression; + + $sql .= '(' . implode( + ' OR ', array_map(array($this, 'walkConditionalTerm'), $condExpr->conditionalTerms) + ) . ')'; + } + + return $sql; + } + + /** + * Walks down an ExistsExpression AST node, thereby generating the appropriate SQL. + * + * @param ExistsExpression + * @return string The SQL. + */ + public function walkExistsExpression($existsExpr) + { + $sql = ($existsExpr->not) ? 'NOT ' : ''; + + $sql .= 'EXISTS (' . $this->walkSubselect($existsExpr->subselect) . ')'; + + return $sql; + } + + /** + * Walks down a CollectionMemberExpression AST node, thereby generating the appropriate SQL. + * + * @param CollectionMemberExpression + * @return string The SQL. + */ + public function walkCollectionMemberExpression($collMemberExpr) + { + $sql = $collMemberExpr->not ? 'NOT ' : ''; + $sql .= 'EXISTS (SELECT 1 FROM '; + $entityExpr = $collMemberExpr->entityExpression; + $collPathExpr = $collMemberExpr->collectionValuedPathExpression; + $parts = $collPathExpr->parts; + $dqlAlias = $collPathExpr->identificationVariable; + + $class = $this->_queryComponents[$dqlAlias]['metadata']; + + if ($entityExpr instanceof AST\InputParameter) { + $dqlParamKey = $entityExpr->name; + $entity = $this->_query->getParameter($dqlParamKey); + } else { + //TODO + throw DoctrineException::notImplemented(); + } + + $assoc = $class->associationMappings[$parts[0]]; + + if ($assoc->isOneToMany()) { + $targetClass = $this->_em->getClassMetadata($assoc->targetEntityName); + $targetTableAlias = $this->getSqlTableAlias($targetClass->primaryTable['name']); + $sourceTableAlias = $this->getSqlTableAlias($class->primaryTable['name'], $dqlAlias); + + $sql .= $this->_conn->quoteIdentifier($targetClass->primaryTable['name']) + . ' ' . $targetTableAlias . ' WHERE '; + + $owningAssoc = $targetClass->associationMappings[$assoc->mappedByFieldName]; + + $first = true; + + foreach ($owningAssoc->targetToSourceKeyColumns as $targetColumn => $sourceColumn) { + if ($first) $first = false; else $sql .= ' AND '; + + $sql .= $sourceTableAlias . '.' . $this->_conn->quoteIdentifier($targetColumn) + . ' = ' + . $targetTableAlias . '.' . $this->_conn->quoteIdentifier($sourceColumn); + } + + $sql .= ' AND '; + $first = true; + + foreach ($targetClass->identifier as $idField) { + if ($first) $first = false; else $sql .= ' AND '; + + $this->_parserResult->addParameterMapping($dqlParamKey, $this->_sqlParamIndex++); + $sql .= $targetTableAlias . '.' + . $this->_conn->quoteIdentifier($targetClass->columnNames[$idField]) . ' = ?'; + } + } else { // many-to-many + $targetClass = $this->_em->getClassMetadata($assoc->targetEntityName); + $sourceTableAlias = $this->getSqlTableAlias($class->primaryTable['name'], $dqlAlias); + $joinTable = $assoc->isOwningSide + ? $assoc->joinTable + : $targetClass->associationMappings[$assoc->mappedByFieldName]->joinTable; + $joinTableAlias = $this->getSqlTableAlias($joinTable['name']); + $targetTableAlias = $this->getSqlTableAlias($targetClass->primaryTable['name']); + + // join to target table + $sql .= $this->_conn->quoteIdentifier($joinTable['name']) + . ' ' . $joinTableAlias . ' INNER JOIN ' + . $this->_conn->quoteIdentifier($targetClass->primaryTable['name']) + . ' ' . $targetTableAlias . ' ON '; + + // join conditions + $joinColumns = $assoc->isOwningSide + ? $joinTable['joinColumns'] + : $joinTable['inverseJoinColumns']; + $first = true; + + foreach ($joinColumns as $joinColumn) { + if ($first) $first = false; else $sql .= ' AND '; + + $sql .= $joinTableAlias . '.' . $this->_conn->quoteIdentifier($joinColumn['name']) + . ' = ' + . $sourceTableAlias . '.' . $this->_conn->quoteIdentifier($joinColumn['referencedColumnName']); + } + + $sql .= ' WHERE '; + + $joinColumns = $assoc->isOwningSide + ? $joinTable['inverseJoinColumns'] + : $joinTable['joinColumns']; + $first = true; + + foreach ($joinColumns as $joinColumn) { + if ($first) $first = false; else $sql .= ' AND '; + + $sql .= $joinTableAlias . '.' . $this->_conn->quoteIdentifier($joinColumn['name']) + . ' = ' + . $targetTableAlias . '.' . $this->_conn->quoteIdentifier($joinColumn['referencedColumnName']); + } + + $sql .= ' AND '; + $first = true; + + foreach ($targetClass->identifier as $idField) { + if ($first) $first = false; else $sql .= ' AND '; + + $this->_parserResult->addParameterMapping($dqlParamKey, $this->_sqlParamIndex++); + $sql .= $targetTableAlias . '.' + . $this->_conn->quoteIdentifier($targetClass->columnNames[$idField]) . ' = ?'; + } + } + + return $sql . ')'; + } + + /** + * Walks down an EmptyCollectionComparisonExpression AST node, thereby generating the appropriate SQL. + * + * @param EmptyCollectionComparisonExpression + * @return string The SQL. + */ + public function walkEmptyCollectionComparisonExpression($emptyCollCompExpr) + { + $sizeFunc = new AST\Functions\SizeFunction('size'); + $sizeFunc->collectionPathExpression = $emptyCollCompExpr->expression; + + return $sizeFunc->getSql($this) . ($emptyCollCompExpr->not ? ' > 0' : ' = 0'); + } + + /** + * Walks down a NullComparisonExpression AST node, thereby generating the appropriate SQL. + * + * @param NullComparisonExpression + * @return string The SQL. + */ + public function walkNullComparisonExpression($nullCompExpr) + { + $sql = ''; + $innerExpr = $nullCompExpr->expression; + + if ($innerExpr instanceof AST\InputParameter) { + $dqlParamKey = $innerExpr->name; + $this->_parserResult->addParameterMapping($dqlParamKey, $this->_sqlParamIndex++); + $sql .= ' ?'; + } else { + $sql .= $this->walkPathExpression($innerExpr); + } + + $sql .= ' IS' . ($nullCompExpr->not ? ' NOT' : '') . ' NULL'; + + return $sql; + } + + /** + * Walks down an InExpression AST node, thereby generating the appropriate SQL. + * + * @param InExpression + * @return string The SQL. + */ + public function walkInExpression($inExpr) + { + $sql = $this->walkPathExpression($inExpr->pathExpression) + . ($inExpr->not ? ' NOT' : '') . ' IN ('; + + if ($inExpr->subselect) { + $sql .= $this->walkSubselect($inExpr->subselect); + } else { + $sql .= implode(', ', array_map(array($this, 'walkLiteral'), $inExpr->literals)); + } + + $sql .= ')'; + + return $sql; + } + + /** + * Walks down a literal that represents an AST node, thereby generating the appropriate SQL. + * + * @param mixed + * @return string The SQL. + */ + public function walkLiteral($literal) + { + if ($literal instanceof AST\InputParameter) { + return $this->walkInputParameter($literal); + } + + return $literal; //TODO: quote() ? + } + + /** + * Walks down a BetweenExpression AST node, thereby generating the appropriate SQL. + * + * @param BetweenExpression + * @return string The SQL. + */ + public function walkBetweenExpression($betweenExpr) + { + $sql = $this->walkArithmeticExpression($betweenExpr->expression); + + if ($betweenExpr->not) $sql .= ' NOT'; + + $sql .= ' BETWEEN ' . $this->walkArithmeticExpression($betweenExpr->leftBetweenExpression) + . ' AND ' . $this->walkArithmeticExpression($betweenExpr->rightBetweenExpression); + + return $sql; + } + + /** + * Walks down a LikeExpression AST node, thereby generating the appropriate SQL. + * + * @param LikeExpression + * @return string The SQL. + */ + public function walkLikeExpression($likeExpr) + { + $stringExpr = $likeExpr->stringExpression; + $sql = $stringExpr->dispatch($this) . ($likeExpr->not ? ' NOT' : '') . ' LIKE '; + + if ($likeExpr->stringPattern instanceof AST\InputParameter) { + $inputParam = $likeExpr->stringPattern; + $dqlParamKey = $inputParam->name; + $this->_parserResult->addParameterMapping($dqlParamKey, $this->_sqlParamIndex++); + $sql .= '?'; + } else { + $sql .= $this->_conn->quote($likeExpr->stringPattern); + } + + if ($likeExpr->escapeChar) { + $sql .= ' ESCAPE ' . $this->_conn->quote($likeExpr->escapeChar); + } + + return $sql; + } + + /** + * Walks down a StateFieldPathExpression AST node, thereby generating the appropriate SQL. + * + * @param StateFieldPathExpression + * @return string The SQL. + */ + public function walkStateFieldPathExpression($stateFieldPathExpression) + { + return $this->walkPathExpression($stateFieldPathExpression); + } + + /** + * Walks down a ComparisonExpression AST node, thereby generating the appropriate SQL. + * + * @param ComparisonExpression + * @return string The SQL. + */ + public function walkComparisonExpression($compExpr) + { + $sql = ''; + $leftExpr = $compExpr->leftExpression; + $rightExpr = $compExpr->rightExpression; + + if ($leftExpr instanceof AST\Node) { + $sql .= $leftExpr->dispatch($this); + } else { + $sql .= $this->_conn->quote($leftExpr); + } + + $sql .= ' ' . $compExpr->operator . ' '; + + if ($rightExpr instanceof AST\Node) { + $sql .= $rightExpr->dispatch($this); + } else { + $sql .= $this->_conn->quote($rightExpr); + } + + return $sql; + } + + /** + * Walks down an InputParameter AST node, thereby generating the appropriate SQL. + * + * @param InputParameter + * @return string The SQL. + */ + public function walkInputParameter($inputParam) + { + $this->_parserResult->addParameterMapping($inputParam->name, $this->_sqlParamIndex++); + + return '?'; + } + + /** + * Walks down an ArithmeticExpression AST node, thereby generating the appropriate SQL. + * + * @param ArithmeticExpression + * @return string The SQL. + */ + public function walkArithmeticExpression($arithmeticExpr) + { + return ($arithmeticExpr->isSimpleArithmeticExpression()) + ? $this->walkSimpleArithmeticExpression($arithmeticExpr->simpleArithmeticExpression) + : $this->walkSubselect($arithmeticExpr->subselect); + } + + /** + * Walks down an ArithmeticTerm AST node, thereby generating the appropriate SQL. + * + * @param mixed + * @return string The SQL. + */ + public function walkArithmeticTerm($term) + { + if (is_string($term)) return $term; + + return implode( + ' ', array_map(array($this, 'walkArithmeticFactor'), $term->arithmeticFactors) + ); + } + + /** + * Walks down a StringPrimary that represents an AST node, thereby generating the appropriate SQL. + * + * @param mixed + * @return string The SQL. + */ + public function walkStringPrimary($stringPrimary) + { + return (is_string($stringPrimary)) + ? $this->_conn->quote($stringPrimary) + : $stringPrimary->dispatch($this); + } + + /** + * Walks down an ArithmeticFactor that represents an AST node, thereby generating the appropriate SQL. + * + * @param mixed + * @return string The SQL. + */ + public function walkArithmeticFactor($factor) + { + if (is_string($factor)) return $factor; + + $sql = ($factor->isNegativeSigned() ? '-' : ($factor->isPositiveSigned() ? '+' : '')); + $primary = $factor->arithmeticPrimary; + + if (is_numeric($primary)) { + $sql .= $primary; // We should not quote numeric values! + } else if (is_string($primary)) { + $sql .= $this->_conn->quote($primary); + } else if ($primary instanceof AST\SimpleArithmeticExpression) { + $sql .= '(' . $this->walkSimpleArithmeticExpression($primary) . ')'; + } else if ($primary instanceof AST\Node) { + $sql .= $primary->dispatch($this); + } + + return $sql; + } + + /** + * Walks down an SimpleArithmeticExpression AST node, thereby generating the appropriate SQL. + * + * @param SimpleArithmeticExpression + * @return string The SQL. + */ + public function walkSimpleArithmeticExpression($simpleArithmeticExpr) + { + return implode( + ' ', array_map(array($this, 'walkArithmeticTerm'), $simpleArithmeticExpr->arithmeticTerms) + ); + } + + /** + * Walks down a PathExpression AST node, thereby generating the appropriate SQL. + * + * @param mixed + * @return string The SQL. + */ + public function walkPathExpression($pathExpr) + { + $sql = ''; + $pathExprType = $pathExpr->type; + + if ($pathExprType == AST\PathExpression::TYPE_STATE_FIELD) { + $parts = $pathExpr->parts; + $numParts = count($parts); + $dqlAlias = $pathExpr->identificationVariable; + $fieldName = $parts[$numParts - 1]; + $qComp = $this->_queryComponents[$dqlAlias]; + $class = $qComp['metadata']; + + if ($this->_useSqlTableAliases) { + if ($class->isInheritanceTypeJoined() && isset($class->fieldMappings[$fieldName]['inherited'])) { + $sql .= $this->getSqlTableAlias( + $this->_em->getClassMetadata($class->fieldMappings[$fieldName]['inherited'])->getTableName(), + $dqlAlias + ) . '.'; + } else { + $sql .= $this->getSqlTableAlias($class->getTableName(), $dqlAlias) . '.'; + } + } + + if (isset($class->associationMappings[$fieldName])) { + //FIXME: Inverse side support + //FIXME: Throw exception on composite key + $sql .= $this->_conn->quoteIdentifier( + $class->associationMappings[$fieldName]->joinColumns[0]['name'] + ); + } else { + $sql .= $this->_conn->quoteIdentifier($class->getColumnName($fieldName)); + } + } else if ($pathExprType == AST\PathExpression::TYPE_COLLECTION_VALUED_ASSOCIATION) { + throw DoctrineException::updateMe("Not yet implemented."); + } else { + throw DoctrineException::updateMe("Encountered invalid PathExpression during SQL construction."); + } + + return $sql; } }