Commit 602c6d97 authored by romanb's avatar romanb

DQL Parser work. Getting some first tests back running. Reorganizing all...

DQL Parser work. Getting some first tests back running. Reorganizing all parser rules into the Parser itself.
parent f0a302ec
......@@ -118,4 +118,3 @@ class Doctrine_ORM_Mapping_OneToManyMapping extends Doctrine_ORM_Mapping_Associa
}
?>
\ No newline at end of file
......@@ -31,11 +31,4 @@
*/
abstract class Doctrine_ORM_Query_AST
{
protected $_parserResult = null;
public function __construct(Doctrine_ORM_Query_ParserResult $parserResult)
{
$this->_parserResult = $parserResult;
}
}
\ No newline at end of file
<?php
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
/**
* Description of AggregateExpression
*
* @author robo
*/
class Doctrine_ORM_Query_AST_AggregateExpression extends Doctrine_ORM_Query_AST
{
private $_functionName;
private $_pathExpression;
private $_isDistinct = false; // Some aggregate expressions support distinct, eg COUNT
public function __construct($functionName, $pathExpression, $isDistinct)
{
$this->_functionName = $functionName;
$this->_pathExpression = $pathExpression;
$this->_isDistinct = $isDistinct;
}
public function getPathExpression()
{
return $this->_pathExpression;
}
public function isDistinct()
{
return $this->_isDistinct;
}
public function getFunctionName()
{
return $this->_functionName;
}
}
<?php
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
/**
* Description of ComparisonExpression
*
* @author robo
*/
class Doctrine_ORM_Query_AST_ComparisonExpression extends Doctrine_ORM_Query_AST
{
}
<?php
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
/**
* ConditionalExpression ::= ConditionalTerm {"OR" ConditionalTerm}*
*
* @author robo
*/
class Doctrine_ORM_Query_AST_ConditionalExpression extends Doctrine_ORM_Query_AST
{
private $_conditionalTerms = array();
public function __construct(array $conditionalTerms)
{
$this->_conditionalTerms = $conditionalTerms;
}
public function getConditionalTerms()
{
return $this->_conditionalTerm;
}
}
<?php
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
/**
* ConditionalFactor ::= ["NOT"] ConditionalPrimary
*
* @author robo
*/
class Doctrine_ORM_Query_AST_ConditionalFactor extends Doctrine_ORM_Query_AST
{
private $_not = false;
private $_conditionalPrimary;
public function __construct($conditionalPrimary, $not = false)
{
$this->_conditionalPrimary = $conditionalPrimary;
$this->_not = $not;
}
public function isNot()
{
return $this->_not;
}
public function getConditionalPrimary()
{
return $this->_conditionalPrimary;
}
}
<?php
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
/**
* ConditionalPrimary ::= SimpleConditionalExpression | "(" ConditionalExpression ")"
*
* @author robo
*/
class Doctrine_ORM_Query_AST_ConditionalPrimary extends Doctrine_ORM_Query_AST
{
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;
}
}
<?php
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
/**
* ConditionalTerm ::= ConditionalFactor {"AND" ConditionalFactor}*
*
* @author robo
*/
class Doctrine_ORM_Query_AST_ConditionalTerm extends Doctrine_ORM_Query_AST
{
private $_conditionalFactors = array();
public function __construct(array $conditionalFactors)
{
$this->_conditionalFactors = $conditionalFactors;
}
public function getConditionalFactors()
{
return $this->_conditionalFactors;
}
}
......@@ -31,22 +31,11 @@
class Doctrine_ORM_Query_AST_FromClause extends Doctrine_ORM_Query_AST
{
protected $_identificationVariableDeclarations = array();
/* Setters */
public function addIdentificationVariableDeclaration($identificationVariableDeclaration)
public function __construct(array $identificationVariableDeclarations)
{
$this->_identificationVariableDeclarations[] = $identificationVariableDeclaration;
}
public function setIdentificationVariableDeclarations($identificationVariableDeclarations, $append = false)
{
$this->_selectExpressions = ($append === true)
? array_merge($this->_identificationVariableDeclarations, $identificationVariableDeclarations)
: $identificationVariableDeclarations;
}
$this->_identificationVariableDeclarations = $identificationVariableDeclarations;
}
/* Getters */
public function getIdentificationVariableDeclarations()
......
<?php
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
/**
* Description of GroupByClause
*
* @author robo
*/
class Doctrine_ORM_Query_AST_GroupByClause extends Doctrine_ORM_Query_AST
{
private $_groupByItems = array();
public function __construct(array $groupByItems)
{
$this->_groupByItems = $groupByItems;
}
public function getGroupByItems()
{
return $this->_groupByItems;
}
}
......@@ -35,34 +35,13 @@ class Doctrine_ORM_Query_AST_IdentificationVariableDeclaration extends Doctrine_
protected $_indexBy = null;
protected $_joinVariableDeclarations = array();
/* Setters */
public function setRangeVariableDeclaration($rangeVariableDeclaration)
{
$this->_rangeVariableDeclaration = $rangeVariableDeclaration;
}
public function setIndexBy($indexBy)
public function __construct($rangeVariableDecl, $indexBy, array $joinVariableDecls)
{
$this->_rangeVariableDeclaration = $rangeVariableDecl;
$this->_indexBy = $indexBy;
$this->_joinVariableDeclarations = $joinVariableDecls;
}
public function addJoinVariableDeclaration($joinVariableDeclaration)
{
$this->_joinVariableDeclarations[] = $joinVariableDeclaration;
}
public function setJoinVariableDeclarations($joinVariableDeclarations, $append = false)
{
$this->_joinVariableDeclarations = ($append === true)
? array_merge($this->_joinVariableDeclarations, $joinVariableDeclarations)
: $joinVariableDeclarations;
}
/* Getters */
public function getRangeVariableDeclaration()
......
......@@ -31,14 +31,11 @@
class Doctrine_ORM_Query_AST_IndexBy extends Doctrine_ORM_Query_AST
{
protected $_simpleStateFieldPathExpression = null;
/* Setters */
public function setSimpleStateFieldPathExpression($simpleStateFieldPathExpression)
public function __construct($simpleStateFieldPathExpression)
{
$this->_simpleStateFieldPathExpression = $simpleStateFieldPathExpression;
}
}
/* Getters */
public function getSimpleStateFieldPathExpression()
......
......@@ -52,23 +52,15 @@ class Doctrine_ORM_Query_AST_Join extends Doctrine_ORM_Query_AST
protected $_whereType = self::JOIN_WHERE_WITH;
protected $_conditionalExpression = null;
/* Setters */
public function setJoinType($joinType)
public function __construct($joinType, $joinAssocPathExpr, $aliasIdentVar)
{
$this->_joinType = $joinType;
$this->_joinAssociationPathExpression = $joinAssocPathExpr;
$this->_aliasIdentificationVariable = $aliasIdentVar;
}
public function setJoinAssociationPathExpression($joinAssociationPathExpression)
{
$this->_joinAssociationPathExpression = $joinAssociationPathExpression;
}
public function setAliasIdentificationVariable($aliasIdentificationVariable)
{
$this->_aliasIdentificationVariable = $aliasIdentificationVariable;
}
/* Setters */
public function setWhereType($whereType)
{
......
<?php
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
/**
* Description of JoinCollectionValuedPathExpression
*
* @author robo
*/
class Doctrine_ORM_Query_AST_JoinPathExpression extends Doctrine_ORM_Query_AST
{
private $_identificationVariable;
private $_assocField;
public function __construct($identificationVariable, $assocField)
{
$this->_identificationVariable = $identificationVariable;
$this->_assocField = $assocField;
}
public function getIdentificationVariable()
{
return $this->_identificationVariable;
}
public function getAssociationField()
{
return $this->_assocField;
}
}
......@@ -34,19 +34,11 @@ class Doctrine_ORM_Query_AST_JoinVariableDeclaration extends Doctrine_ORM_Query_
protected $_indexBy = null;
/* Setters */
public function setJoin($join)
public function __construct($join, $indexBy)
{
$this->_join = $join;
}
public function setIndexBy($indexBy)
{
$this->_indexBy = $indexBy;
}
/* Getters */
public function getJoin()
......
<?php
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
/**
* Description of PathExpression
*
* @author robo
*/
class Doctrine_ORM_Query_AST_PathExpression
{
private $_parts;
// Information that is attached during semantical analysis.
private $_isSimpleStateFieldPathExpression = false;
private $_isSimpleStateFieldAssociationPathExpression = false;
private $_embeddedClassFields = array();
private $_singleValuedAssociationFields = array();
public function __construct(array $parts)
{
$this->_parts = $parts;
}
public function getParts() {
return $this->_parts;
}
/**
* Gets whether the path expression represents a state field that is reached
* either directly (u.name) or by navigating over optionally many embedded class instances
* (u.address.zip).
*
* @return boolean
*/
public function isSimpleStateFieldPathExpression()
{
return $this->_isSimpleStateFieldPathExpression;
}
/**
* Gets whether the path expression represents a state field that is reached
* by navigating over at least one single-valued association and optionally
* many embedded class instances. (u.Group.address.zip, u.Group.address, ...)
*
* @return boolean
*/
public function isSimpleStateFieldAssociationPathExpression()
{
return $this->_isSimpleStateFieldAssociationPathExpression;
}
public function isPartEmbeddedClassField($part)
{
return isset($this->_embeddedClassFields[$part]);
}
public function isPartSingleValuedAssociationField($part)
{
return isset($this->_singleValuedAssociationFields[$part]);
}
/* Setters to attach semantical information during semantical analysis. */
public function setIsSimpleStateFieldPathExpression($bool)
{
$this->_isSimpleStateFieldPathExpression = $bool;
}
public function setIsSimpleStateFieldAssociationPathExpression($bool)
{
$this->_isSimpleStateFieldAssociationPathExpression = $bool;
}
public function setIsEmbeddedClassPart($part)
{
$this->_embeddedClassFields[$part] = true;
}
public function setIsSingleValuedAssociationPart($part)
{
$this->_singleValuedAssociationFields[$part] = true;
}
}
......@@ -30,23 +30,16 @@
*/
class Doctrine_ORM_Query_AST_RangeVariableDeclaration extends Doctrine_ORM_Query_AST
{
protected $_abstractSchemaName = null;
protected $_aliasIdentificationVariable = null;
/* Setters */
public function setAbstractSchemaName($abstractSchemaName)
{
$this->_abstractSchemaName = $abstractSchemaName;
}
private $_classMetadata;
private $_abstractSchemaName;
private $_aliasIdentificationVariable;
public function setAliasIdentificationVariable($aliasIdentificationVariable)
public function __construct($classMetadata, $aliasIdentificationVar)
{
$this->_aliasIdentificationVariable = $aliasIdentificationVariable;
}
$this->_classMetadata = $classMetadata;
$this->_abstractSchemaName = $classMetadata->getClassName();
$this->_aliasIdentificationVariable = $aliasIdentificationVar;
}
/* Getters */
public function getAbstractSchemaName()
......@@ -54,11 +47,15 @@ class Doctrine_ORM_Query_AST_RangeVariableDeclaration extends Doctrine_ORM_Query
return $this->_abstractSchemaName;
}
public function getAliasIdentificationVariable()
{
return $this->_aliasIdentificationVariable;
}
public function getClassMetadata()
{
return $this->_classMetadata;
}
/* REMOVE ME LATER. COPIED METHODS FROM SPLIT OF PRODUCTION INTO "AST" AND "PARSER" */
......
......@@ -33,28 +33,12 @@ class Doctrine_ORM_Query_AST_SelectClause extends Doctrine_ORM_Query_AST
protected $_isDistinct;
protected $_selectExpressions = array();
/* Setters */
public function setIsDistinct($value)
{
$this->_isDistinct = $value;
}
public function addSelectExpression($expression)
{
$this->_selectExpressions[] = $expression;
}
public function setSelectExpressions($expressions, $append = false)
public function __construct(array $selectExpressions, $isDistinct)
{
$this->_selectExpressions = ($append === true)
? array_merge($this->_selectExpressions, $expressions)
: $expressions;
$this->_isDistinct = $isDistinct;
$this->_selectExpressions = $selectExpressions;
}
/* Getters */
public function isDistinct()
......
......@@ -34,19 +34,12 @@ class Doctrine_ORM_Query_AST_SelectExpression extends Doctrine_ORM_Query_AST
protected $_expression;
protected $_fieldIdentificationVariable;
/* Setters */
public function setExpression($expression)
public function __construct($expression, $fieldIdentificationVariable)
{
$this->_expression = $expression;
}
public function setFieldIdentificationVariable($fieldIdentificationVariable)
{
$this->_fieldIdentificationVariable = $fieldIdentificationVariable;
}
}
/* Getters */
public function getExpression()
......
......@@ -31,54 +31,21 @@
class Doctrine_ORM_Query_AST_SelectStatement extends Doctrine_ORM_Query_AST
{
protected $_selectClause;
protected $_fromClause;
protected $_whereClause;
protected $_groupByClause;
protected $_havingClause;
protected $_orderByClause;
/* Setters */
public function setSelectClause($selectClause)
{
$this->_selectClause = $selectClause;
}
public function setFromClause($fromClause)
{
public function __construct($selectClause, $fromClause, $whereClause, $groupByClause,
$havingClause, $orderByClause) {
$this->_selectClause = $selectClause;
$this->_fromClause = $fromClause;
}
public function setWhereClause($whereClause)
{
$this->_whereClause = $whereClause;
}
public function setGroupByClause($groupByClause)
{
$this->_groupByClause = $groupByClause;
}
public function setHavingClause($havingClause)
{
$this->_havingClause = $havingClause;
}
public function setOrderByClause($orderByClause)
{
$this->_orderByClause = $orderByClause;
}
}
/* Getters */
public function getSelectClause()
......@@ -122,7 +89,7 @@ class Doctrine_ORM_Query_AST_SelectStatement extends Doctrine_ORM_Query_AST
public function buildSql()
{
return $this->_selectClause->buildSql() . ' ' . $this->_fromClause->buildSql()
. (($this->_whereClause !== null) ? ' ' . $this->_whereClause->buildSql() : ' WHERE 1 = 1')
. (($this->_whereClause !== null) ? ' ' . $this->_whereClause->buildSql() : '')
. (($this->_groupByClause !== null) ? ' ' . $this->_groupByClause->buildSql() : '')
. (($this->_havingClause !== null) ? ' ' . $this->_havingClause->buildSql() : '')
. (($this->_orderByClause !== null) ? ' ' . $this->_orderByClause->buildSql() : '');
......
<?php
/**
* SimpleConditionalExpression ::= ExistsExpression |
* (SimpleStateFieldPathExpression (ComparisonExpression | BetweenExpression | LikeExpression |
* InExpression | NullComparisonExpression)) |
* (CollectionValuedPathExpression EmptyCollectionComparisonExpression) |
* (EntityExpression CollectionMemberExpression)
*
* @author robo
*/
class Doctrine_ORM_Query_AST_SimpleConditionalExpression extends Doctrine_ORM_Query_AST
{
}
......@@ -33,20 +33,12 @@ class Doctrine_ORM_Query_AST_SimpleStateFieldPathExpression extends Doctrine_ORM
protected $_identificationVariable = null;
protected $_simpleStateField = null;
/* Setters */
public function setIdentificationVariable($identificationVariable)
{
$this->_identificationVariable = $identificationVariable;
}
public function setSimpleStateField($simpleStateField)
public function __construct($identificationVariable, $simpleStateField)
{
$this->_identificationVariable = $identificationVariable;
$this->_simpleStateField = $simpleStateField;
}
}
/* Getters */
public function getIdentificationVariable()
......
<?php
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
/**
* Description of WhereClause
*
* @author robo
*/
class Doctrine_ORM_Query_AST_WhereClause extends Doctrine_ORM_Query_AST
{
private $_conditionalExpression;
public function __construct($conditionalExpression)
{
$this->_conditionalExpression = $conditionalExpression;
}
public function getConditionalExpression()
{
return $this->_conditionalExpression;
}
}
......@@ -121,7 +121,7 @@ abstract class Doctrine_ORM_Query_AbstractResult
*/
public function getQueryComponent($componentAlias)
{
if ( ! array_key_exists($componentAlias, $this->_queryComponents)) {
if ( ! isset($this->_queryComponents[$componentAlias])) {
throw new Doctrine_ORM_Query_Exception('Unknown query component ' . $componentAlias);
}
......@@ -188,7 +188,7 @@ abstract class Doctrine_ORM_Query_AbstractResult
/**
* Get component alias associated with given table alias.
* Get DQL alias associated with given SQL table alias.
*
* @param string $tableAlias SQL table alias that identifies the component alias
* @return string Component alias
......@@ -272,5 +272,4 @@ abstract class Doctrine_ORM_Query_AbstractResult
$this->getEnumParams()
));
}
}
\ No newline at end of file
This diff is collapsed.
......@@ -91,14 +91,7 @@ class Doctrine_ORM_Query_Parser_SelectExpression extends Doctrine_ORM_Query_Pars
// We have an identifier here
if ($token['type'] === Doctrine_ORM_Query_Token::T_IDENTIFIER) {
$token = $this->_parser->getScanner()->peek();
// If we have a dot ".", then next char must be the "*"
if ($token['type'] === Doctrine_ORM_Query_Token::T_DOT) {
$token = $this->_parser->getScanner()->peek();
return $token['value'] === '*';
}
return true;
}
return false;
......
......@@ -44,9 +44,9 @@ class Doctrine_ORM_Query_Parser_SelectStatement extends Doctrine_ORM_Query_Parse
// Disable the semantical check for SelectClause now. This is needed
// since we dont know the query components yet (will be known only
// when the FROM and WHERE clause are processed).
$this->_dataHolder->set('semanticalCheck', false);
//$this->_dataHolder->set('semanticalCheck', false);
$this->_selectClause = $this->parse('SelectClause');
$this->_dataHolder->remove('semanticalCheck');
//$this->_dataHolder->remove('semanticalCheck');
$this->_AST->setFromClause($this->parse('FromClause'));
......
......@@ -38,14 +38,6 @@ class Doctrine_ORM_Query_ParserResult extends Doctrine_ORM_Query_AbstractResult
*/
protected $_em;
/**
* A simple array keys representing table aliases and values table alias
* seeds. The seeds are used for generating short table aliases.
*
* @var array $_tableAliasSeeds
*/
protected $_tableAliasSeeds = array();
/**
* Simple array of keys representing the fields used in query.
*
......@@ -154,33 +146,4 @@ class Doctrine_ORM_Query_ParserResult extends Doctrine_ORM_Query_AbstractResult
{
return isset($this->_queryFields[$fieldAlias]);
}
/**
* Generates a table alias from given table name and associates
* it with given component alias
*
* @param string $componentName Component name to be associated with generated table alias
* @return string Generated table alias
*/
public function generateTableAlias($componentName)
{
$baseAlias = strtolower(preg_replace('/[^A-Z]/', '\\1', $componentName));
// We may have a situation where we have all chars are lowercased
if ( $baseAlias == '' ) {
// We simply grab the first 2 chars of component name
$baseAlias = substr($componentNam, 0, 2);
}
$alias = $baseAlias;
if ( ! isset($this->_tableAliasSeeds[$baseAlias])) {
$this->_tableAliasSeeds[$baseAlias] = 1;
} else {
$alias .= $this->_tableAliasSeeds[$baseAlias]++;
}
return $alias;
}
}
......@@ -107,40 +107,35 @@ abstract class Doctrine_ORM_Query_ParserRule
*
* @param string $RuleName BNF Grammar Rule name
* @param array $paramHolder Production parameter holder
* @return Doctrine_ORM_Query_ParserRule
* @return Doctrine_ORM_Query_AST The constructed subtree during parsing.
*/
public function parse($RuleName)
public function parse($ruleName)
{
$BNFGrammarRule = $this->_getGrammarRule($RuleName);
//echo "Processing class: " . get_class($BNFGrammarRule) . "...\n";
//echo "Params: " . var_export($paramHolder, true) . "\n";
echo $ruleName . PHP_EOL;
return $this->_getGrammarRule($ruleName)->syntax();
// Syntax check
if ( ! $this->_dataHolder->has('syntaxCheck') || $this->_dataHolder->get('syntaxCheck') === true) {
/*if ( ! $this->_dataHolder->has('syntaxCheck') || $this->_dataHolder->get('syntaxCheck') === true) {
//echo "Processing syntax checks of " . $RuleName . "...\n";
$return = $BNFGrammarRule->syntax();
if ($return !== null) {
//echo "Returning Gramma Rule class: " . (is_object($return) ? get_class($return) : $return) . "...\n";
return $return;
$ASTNode = $BNFGrammarRule->syntax();
if ($ASTNode !== null) {
//echo "Returning Grammar Rule class: " . (is_object($ASTNode) ? get_class($ASTNode) : $ASTNode) . "...\n";
return $ASTNode;
}
}
}*/
// Semantical check
if ( ! $this->_dataHolder->has('semanticalCheck') || $this->_dataHolder->get('semanticalCheck') === true) {
//echo "Processing semantical checks of " . $RuleName . "...\n";
/*if ( ! $this->_dataHolder->has('semanticalCheck') || $this->_dataHolder->get('semanticalCheck') === true) {
echo "Processing semantical checks of " . $RuleName . "...\n";
$return = $BNFGrammarRule->semantical();
if ($return !== null) {
//echo "Returning Gramma Rule class: " . (is_object($return) ? get_class($return) : $return) . "...\n";
echo "Returning Grammar Rule class: " . (is_object($return) ? get_class($return) : $return) . "...\n";
return $return;
}
}
}*/
return $BNFGrammarRule;
}
......@@ -178,15 +173,6 @@ abstract class Doctrine_ORM_Query_ParserRule
public function AST($AstName)
{
$class = 'Doctrine_ORM_Query_AST_' . $AstName;
//echo $class . "\r\n";
if ( ! class_exists($class)) {
throw new Doctrine_ORM_Query_Parser_Exception(
"Unknown AST node '" . $AstName . "'. Could not find related compiler class."
);
}
return new $class($this->_parser->getParserResult());
}
......
<?php
/*
* $Id$
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information, see
* <http://www.phpdoctrine.org>.
*/
/**
* The SqlBuilder. Creates SQL out of an AST.
*
* INTERNAL: For platform-specific SQL, the platform of the connection should be used.
* ($this->_connection->getDatabasePlatform())
*
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
* @author Janne Vanhala <jpvanhal@cc.hut.fi>
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @link http://www.phpdoctrine.org
* @since 2.0
* @version $Revision$
*/
class Doctrine_ORM_Query_SqlBuilder
{
protected $_em;
protected $_conn;
public function __construct(Doctrine_ORM_EntityManager $em)
{
$this->_em = $em;
$this->_conn = $this->_em->getConnection();
}
/**
* Retrieves the assocated Doctrine_Connection to this object.
*
* @return Doctrine_Connection
*/
public function getConnection()
{
return $this->_connection;
}
/**
* @nodoc
*/
public function quoteIdentifier($identifier)
{
return $this->_conn->quoteIdentifier($identifier);
}
}
<?php
/*
* $Id$
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information, see
* <http://www.phpdoctrine.org>.
*/
/**
* MySql class of Sql Builder object
*
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
* @author Janne Vanhala <jpvanhal@cc.hut.fi>
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @link http://www.phpdoctrine.org
* @since 1.0
* @version $Revision$
*/
class Doctrine_ORM_Query_SqlBuilder_Mysql extends Doctrine_ORM_Query_SqlBuilder
{
}
<?php
/*
* $Id$
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information, see
* <http://www.phpdoctrine.org>.
*/
/**
* Sqlite class of Sql Builder object
*
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
* @author Janne Vanhala <jpvanhal@cc.hut.fi>
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @link http://www.phpdoctrine.org
* @since 1.0
* @version $Revision$
*/
class Doctrine_ORM_Query_SqlBuilder_Sqlite extends Doctrine_ORM_Query_SqlBuilder
{
}
\ No newline at end of file
......@@ -30,15 +30,10 @@
*/
abstract class Doctrine_ORM_Query_SqlExecutor_Abstract implements Serializable
{
// [TODO] Remove me later!
//public $AST;
protected $_sqlStatements;
public function __construct(Doctrine_ORM_Query_AST $AST)
public function __construct(Doctrine_ORM_Query_AST $AST, $sqlWalker)
{
// [TODO] Remove me later!
//$this->AST = $AST;
}
/**
......@@ -66,7 +61,7 @@ abstract class Doctrine_ORM_Query_SqlExecutor_Abstract implements Serializable
* @param Doctrine_ORM_Query_AST $AST The root node of the AST.
* @return Doctrine_ORM_Query_SqlExecutor_Abstract The executor that is suitable for the given AST.
*/
public static function create(Doctrine_ORM_Query_AST $AST)
public static function create(Doctrine_ORM_Query_AST $AST, $sqlWalker)
{
$isDeleteStatement = $AST instanceof Doctrine_ORM_Query_AST_DeleteStatement;
$isUpdateStatement = $AST instanceof Doctrine_ORM_Query_AST_UpdateStatement;
......@@ -84,7 +79,7 @@ abstract class Doctrine_ORM_Query_SqlExecutor_Abstract implements Serializable
*/
return new Doctrine_ORM_Query_SqlExecutor_SingleTableDeleteUpdate($AST);
} else {
return new Doctrine_ORM_Query_SqlExecutor_SingleSelect($AST);
return new Doctrine_ORM_Query_SqlExecutor_SingleSelect($AST, $sqlWalker);
}
}
......
......@@ -30,10 +30,10 @@
*/
class Doctrine_ORM_Query_SqlExecutor_SingleSelect extends Doctrine_ORM_Query_SqlExecutor_Abstract
{
public function __construct(Doctrine_ORM_Query_AST $AST)
public function __construct(Doctrine_ORM_Query_AST_SelectStatement $AST, $sqlWalker)
{
parent::__construct($AST);
$this->_sqlStatements = $AST->buildSql();
parent::__construct($AST, $sqlWalker);
$this->_sqlStatements = $sqlWalker->walkSelectStatement($AST);
}
public function execute(Doctrine_DBAL_Connection $conn, array $params)
......
<?php
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
/**
* Description of SqlWalker
*
* @author robo
*/
class Doctrine_ORM_Query_SqlWalker
{
/**
* A simple array keys representing table aliases and values table alias
* seeds. The seeds are used for generating short SQL table aliases.
*
* @var array $_tableAliasSeeds
*/
private $_tableAliasSeeds = array();
private $_parserResult;
private $_em;
private $_dqlToSqlAliasMap = array();
private $_scalarAliasCounter = 0;
public function __construct($em, $parserResult)
{
$this->_em = $em;
$this->_parserResult = $parserResult;
$sqlToDqlAliasMap = array();
foreach ($parserResult->getQueryComponents() as $dqlAlias => $qComp) {
if ($dqlAlias != 'dctrn') {
$sqlAlias = $this->generateTableAlias($qComp['metadata']->getClassName());
$sqlToDqlAliasMap[$sqlAlias] = $dqlAlias;
}
}
// SQL => DQL alias stored in ParserResult, needed for hydration.
$parserResult->setTableAliasMap($sqlToDqlAliasMap);
// DQL => SQL alias stored only locally, needed for SQL construction.
$this->_dqlToSqlAliasMap = array_flip($sqlToDqlAliasMap);
}
public function walkSelectStatement(Doctrine_ORM_Query_AST_SelectStatement $AST)
{
$sql = $this->walkSelectClause($AST->getSelectClause());
$sql .= $this->walkFromClause($AST->getFromClause());
$sql .= $AST->getGroupByClause() ? $this->walkGroupByClause($AST->getGroupByClause()) : '';
//... more clauses
return $sql;
}
public function walkSelectClause($selectClause)
{
return 'SELECT ' . (($selectClause->isDistinct()) ? 'DISTINCT ' : '')
. implode(', ', array_map(array(&$this, 'walkSelectExpression'),
$selectClause->getSelectExpressions()));
}
public function walkFromClause($fromClause)
{
$sql = ' FROM ';
$identificationVarDecls = $fromClause->getIdentificationVariableDeclarations();
$firstIdentificationVarDecl = $identificationVarDecls[0];
$rangeDecl = $firstIdentificationVarDecl->getRangeVariableDeclaration();
$sql .= $rangeDecl->getClassMetadata()->getTableName() . ' '
. $this->_dqlToSqlAliasMap[$rangeDecl->getAliasIdentificationVariable()];
foreach ($firstIdentificationVarDecl->getJoinVariableDeclarations() as $joinVarDecl) {
$sql .= $this->walkJoinVariableDeclaration($joinVarDecl);
}
return $sql;
}
/**
* Walks down a JoinVariableDeclaration AST node and creates the corresponding SQL.
*
* @param JoinVariableDeclaration $joinVarDecl
* @return string
*/
public function walkJoinVariableDeclaration($joinVarDecl)
{
$join = $joinVarDecl->getJoin();
$joinType = $join->getJoinType();
if ($joinType == Doctrine_ORM_Query_AST_Join::JOIN_TYPE_LEFT ||
$joinType == Doctrine_ORM_Query_AST_Join::JOIN_TYPE_LEFTOUTER) {
$sql = ' LEFT JOIN ';
} else {
$sql = ' INNER JOIN ';
}
$joinAssocPathExpr = $join->getJoinAssociationPathExpression();
$sourceQComp = $this->_parserResult->getQueryComponent($joinAssocPathExpr->getIdentificationVariable());
$targetQComp = $this->_parserResult->getQueryComponent($join->getAliasIdentificationVariable());
$targetTableName = $targetQComp['metadata']->getTableName();
$targetTableAlias = $this->_dqlToSqlAliasMap[$join->getAliasIdentificationVariable()];
$sourceTableAlias = $this->_dqlToSqlAliasMap[$joinAssocPathExpr->getIdentificationVariable()];
$sql .= $targetTableName . ' ' . $targetTableAlias . ' ON ';
if ( ! $targetQComp['relation']->isOwningSide()) {
$assoc = $targetQComp['metadata']->getAssociationMapping($targetQComp['relation']->getMappedByFieldName());
} else {
$assoc = $targetQComp['relation'];
}
if ($targetQComp['relation']->isOneToOne() || $targetQComp['relation']->isOneToMany()) {
$joinColumns = $assoc->getSourceToTargetKeyColumns();
$first = true;
foreach ($joinColumns as $sourceColumn => $targetColumn) {
if ( ! $first) $sql .= ' AND ';
if ($targetQComp['relation']->isOwningSide()) {
$sql .= "$sourceTableAlias.$sourceColumn = $targetTableAlias.$targetColumn";
} else {
$sql .= "$sourceTableAlias.$targetColumn = $targetTableAlias.$sourceColumn";
}
}
} else { // ManyToMany
//TODO
}
return $sql;
}
/**
* Walks down a SelectExpression AST node and generates the corresponding SQL.
*
* @param <type> $selectExpression
* @return string
*/
public function walkSelectExpression($selectExpression)
{
$sql = '';
if ($selectExpression->getExpression() instanceof Doctrine_ORM_Query_AST_PathExpression) {
$pathExpression = $selectExpression->getExpression();
if ($pathExpression->isSimpleStateFieldPathExpression()) {
$parts = $pathExpression->getParts();
$numParts = count($parts);
$dqlAlias = $parts[0];
$fieldName = $parts[$numParts-1];
$qComp = $this->_parserResult->getQueryComponent($dqlAlias);
$class = $qComp['metadata'];
if ($numParts > 2) {
for ($i = 1; $i < $numParts-1; ++$i) {
//TODO
}
}
$sqlTableAlias = $this->_dqlToSqlAliasMap[$dqlAlias];
$sql .= $sqlTableAlias . '.' . $class->getColumnName($fieldName) .
' AS ' . $sqlTableAlias . '__' . $class->getColumnName($fieldName);
} else if ($pathExpression->isSimpleStateFieldAssociationPathExpression()) {
echo "HERE!!";
} else {
throw new Doctrine_ORM_Query_Exception("Encountered invalid PathExpression during SQL construction.");
}
}
else if ($selectExpression->getExpression() instanceof Doctrine_ORM_Query_AST_AggregateExpression) {
$aggExpr = $selectExpression->getExpression();
if ( ! $selectExpression->getFieldIdentificationVariable()) {
$alias = $this->_scalarAliasCounter++;
} else {
$alias = $selectExpression->getFieldIdentificationVariable();
}
$parts = $aggExpr->getPathExpression()->getParts();
$dqlAlias = $parts[0];
$fieldName = $parts[1];
$qComp = $this->_parserResult->getQueryComponent($dqlAlias);
$columnName = $qComp['metadata']->getColumnName($fieldName);
$sql .= $aggExpr->getFunctionName() . '(';
$sql .= $this->_dqlToSqlAliasMap[$dqlAlias] . '.' . $columnName;
$sql .= ') AS dctrn__' . $alias;
}
//TODO: else if Subselect
else {
$dqlAlias = $selectExpression->getExpression();
$queryComp = $this->_parserResult->getQueryComponent($dqlAlias);
$class = $queryComp['metadata'];
$sqlTableAlias = $this->_dqlToSqlAliasMap[$dqlAlias];
$beginning = true;
foreach ($class->getFieldMappings() as $fieldName => $fieldMapping) {
if ($beginning) {
$beginning = false;
} else {
$sql .= ', ';
}
$sql .= $sqlTableAlias . '.' . $fieldMapping['columnName'] .
' AS ' . $sqlTableAlias . '__' . $fieldMapping['columnName'];
}
}
return $sql;
}
public function walkGroupByClause($groupByClause)
{
return ' GROUP BY '
. implode(', ', array_map(array(&$this, 'walkGroupByItem'),
$groupByClause->getGroupByItems()));
}
public function walkGroupByItem($pathExpr)
{
//TODO: support general SingleValuedPathExpression, not just state field
$parts = $pathExpr->getParts();
$qComp = $this->_parserResult->getQueryComponent($parts[0]);
$columnName = $qComp['metadata']->getColumnName($parts[1]);
return $this->_dqlToSqlAliasMap[$parts[0]] . '.' . $columnName;
}
public function walkUpdateStatement(Doctrine_ORM_Query_AST_UpdateStatement $AST)
{
}
public function walkDeleteStatement(Doctrine_ORM_Query_AST_DeleteStatement $AST)
{
}
/**
* Generates an SQL table alias from given table name and associates
* it with given component alias
*
* @param string $componentName Component name to be associated with generated table alias
* @return string Generated table alias
*/
public function generateTableAlias($componentName)
{
$baseAlias = strtolower(preg_replace('/[^A-Z]/', '\\1', $componentName));
// We may have a situation where we have all chars are lowercased
if ($baseAlias == '') {
// We simply grab the first 2 chars of component name
$baseAlias = substr($componentNam, 0, 2);
}
$alias = $baseAlias;
if ( ! isset($this->_tableAliasSeeds[$baseAlias])) {
$this->_tableAliasSeeds[$baseAlias] = 1;
} else {
$alias .= $this->_tableAliasSeeds[$baseAlias]++;
}
return $alias;
}
}
......@@ -54,7 +54,7 @@ AliasIdentificationVariable :: = identifier
/* identifier that must be a class name (the "User" of "FROM User u") */
AbstractSchemaName ::= identifier
/* identifier that must be a field (the "name" of "u.name") */
/* identifier that must be a field (the "name" of "u.name") */
/* This is responsable to know if the field exists in Object, no matter if it's a relation or a simple field */
FieldIdentificationVariable ::= identifier
......@@ -67,49 +67,49 @@ SingleValuedAssociationField ::= FieldIdentificationVariable
/* identifier that must be an embedded class state field (for the future) */
EmbeddedClassStateField ::= FieldIdentificationVariable
/* identifier that must be a simple state field (name, email, ...) (the "name" of "u.name") */
/* identifier that must be a simple state field (name, email, ...) (the "name" of "u.name") */
/* The difference between this and FieldIdentificationVariable is only semantical, because it points to a single field (not mapping to a relation) */
SimpleStateField ::= FieldIdentificationVariable
/* identifier that must be unique among other mapped field aliases (the "total" of "COUNT(*) AS total")*/
/* identifier that must be unique among other mapped field aliases (the "total" of "COUNT(*) AS total")*/
FieldAliasIdentificationVariable = identifier
/*
* PATH EXPRESSIONS
*/
*/
/* "u.Group" or "u.Phonenumbers" declarations */
JoinAssociationPathExpression ::= JoinCollectionValuedPathExpression | JoinSingleValuedAssociationPathExpression
/* "u.Phonenumbers" */
/* "u.Phonenumbers" */
JoinCollectionValuedPathExpression ::= IdentificationVariable "." CollectionValuedAssociationField
/* "u.Group" */
/* "u.Group" */
JoinSingleValuedAssociationPathExpression ::= IdentificationVariable "." SingleValuedAssociationField
/* "u.Group" or "u.Phonenumbers" usages */
/* "u.Group" or "u.Phonenumbers" usages */
AssociationPathExpression ::= CollectionValuedPathExpression | SingleValuedAssociationPathExpression
/* "u.name" or "u.Group" */
SingleValuedPathExpression ::= StateFieldPathExpression | SingleValuedAssociationPathExpression
/* "u.name" or "u.Group" */
SingleValuedPathExpression ::= StateFieldPathExpression | SingleValuedAssociationPathExpression
/* "u.name" or "u.Group.name" */
StateFieldPathExpression ::= SimpleStateFieldPathExpression | SimpleStateFieldAssociationPathExpression
StateFieldPathExpression ::= SimpleStateFieldPathExpression | SimpleStateFieldAssociationPathExpression
/* "u.Group" */
SingleValuedAssociationPathExpression ::= IdentificationVariable "." {SingleValuedAssociationField "."}* SingleValuedAssociationField
SingleValuedAssociationPathExpression ::= IdentificationVariable "." {SingleValuedAssociationField "."}* SingleValuedAssociationField
/* "u.Group.Permissions" */
CollectionValuedPathExpression ::= IdentificationVariable "." {SingleValuedAssociationField "."}* CollectionValuedAssociationField
CollectionValuedPathExpression ::= IdentificationVariable "." {SingleValuedAssociationField "."}* CollectionValuedAssociationField
/* "name" */
StateField ::= {EmbeddedClassStateField "."}* SimpleStateField
/* "u.name" */
SimpleStateFieldPathExpression ::= IdentificationVariable "." SimpleStateField
/* "u.Group.name" */
/* "u.name" or "u.address.zip" (address = EmbeddedClassStateField) */
SimpleStateFieldPathExpression ::= IdentificationVariable "." StateField
/* "u.Group.name" */
SimpleStateFieldAssociationPathExpression ::= SingleValuedAssociationPathExpression "." StateField
......@@ -156,7 +156,7 @@ IndexBy ::= "INDEX" "BY" SimpleStateFieldPath
/*
* SELECT EXPRESSION
*/
SelectExpression ::= IdentificationVariable ["." "*"] | StateFieldPathExpression |
SelectExpression ::= IdentificationVariable | StateFieldPathExpression |
(AggregateExpression | "(" Subselect ")") [["AS"] FieldAliasIdentificationVariable]
SimpleSelectExpression ::= SingleValuedPathExpression | IdentificationVariable | AggregateExpression
......@@ -164,21 +164,23 @@ SimpleSelectExpression ::= SingleValuedPathExpression | IdentificationVariable |
/*
* CONDITIONAL EXPRESSIONS
*/
ConditionalExpression ::= ConditionalTerm | ConditionalExpression "OR" ConditionalTerm
ConditionalTerm ::= ConditionalFactor | ConditionalTerm "AND" ConditionalFactor
ConditionalExpression ::= ConditionalTerm {"OR" ConditionalTerm}*
ConditionalTerm ::= ConditionalFactor {"AND" ConditionalFactor}*
ConditionalFactor ::= ["NOT"] ConditionalPrimary
ConditionalPrimary ::= SimpleConditionalExpression | "(" ConditionalExpression ")"
SimpleConditionalExpression ::= ComparisonExpression | BetweenExpression | LikeExpression |
InExpression | NullComparisonExpression | ExistsExpression |
EmptyCollectionComparisonExpression | CollectionMemberExpression
SimpleConditionalExpression ::= ExistsExpression |
(SimpleStateFieldPathExpression (ComparisonExpression | BetweenExpression | LikeExpression |
InExpression | NullComparisonExpression)) |
(CollectionValuedPathExpression EmptyCollectionComparisonExpression) |
(EntityExpression CollectionMemberExpression)
/* EmptyCollectionComparisonExpression and CollectionMemberExpression are for the future */
/*
* COLLECTION EXPRESSIONS (FOR THE FUTURE)
*/
EmptyCollectionComparisonExpression ::= CollectionValuedPathExpression "IS" ["NOT"] "EMPTY"
CollectionMemberExpression ::= EntityExpression ["NOT"] "MEMBER" ["OF"] CollectionValuedPathExpression
EmptyCollectionComparisonExpression ::= "IS" ["NOT"] "EMPTY"
CollectionMemberExpression ::= ["NOT"] "MEMBER" ["OF"] CollectionValuedPathExpression
/*
......@@ -199,8 +201,8 @@ NamedParameter ::= ":" string
* ARITHMETIC EXPRESSIONS
*/
ArithmeticExpression ::= SimpleArithmeticExpression | "(" Subselect ")"
SimpleArithmeticExpression ::= ArithmeticTerm | SimpleArithmeticExpression ("+"|"-") ArithmeticTerm
ArithmeticTerm ::= ArithmeticFactor | ArithmeticTerm ("*" |"/") ArithmeticFactor
SimpleArithmeticExpression ::= ArithmeticTerm {("+" | "-") ArithmeticTerm}*
ArithmeticTerm ::= ArithmeticFactor {("*" |"/") ArithmeticFactor}*
ArithmeticFactor ::= [("+" | "-")] ArithmeticPrimary
ArithmeticPrimary ::= StateFieldPathExpression | Literal | "(" SimpleArithmeticExpression ")" | Function | AggregateExpression
......
......@@ -25,12 +25,13 @@ class Orm_Query_AllTests
$suite = new Doctrine_TestSuite('Doctrine Orm Query');
$suite->addTestSuite('Orm_Query_IdentifierRecognitionTest');
/*$suite->addTestSuite('Orm_Query_LanguageRecognitionTest');
$suite->addTestSuite('Orm_Query_SelectSqlGenerationTest');
/*
$suite->addTestSuite('Orm_Query_LanguageRecognitionTest');
$suite->addTestSuite('Orm_Query_ScannerTest');
$suite->addTestSuite('Orm_Query_DqlGenerationTest');
$suite->addTestSuite('Orm_Query_DeleteSqlGenerationTest');
$suite->addTestSuite('Orm_Query_UpdateSqlGenerationTest');
$suite->addTestSuite('Orm_Query_SelectSqlGenerationTest');*/
$suite->addTestSuite('Orm_Query_UpdateSqlGenerationTest');*/
return $suite;
}
......
......@@ -24,8 +24,6 @@ require_once 'lib/DoctrineTestInit.php';
/**
* Test case for testing the saving and referencing of query identifiers.
*
* @package Doctrine
* @subpackage Query
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
* @author Janne Vanhala <jpvanhal@cc.hut.fi>
* @author Konsta Vesterinen <kvesteri@cc.hut.fi>
......@@ -46,7 +44,7 @@ class Orm_Query_IdentifierRecognitionTest extends Doctrine_OrmTestCase
public function testSingleAliasDeclarationIsSupported()
{
$entityManager = $this->_em;
$query = $entityManager->createQuery('SELECT u.* FROM CmsUser u');
$query = $entityManager->createQuery('SELECT u FROM CmsUser u');
$parserResult = $query->parse();
$decl = $parserResult->getQueryComponent('u');
......@@ -61,7 +59,7 @@ class Orm_Query_IdentifierRecognitionTest extends Doctrine_OrmTestCase
public function testSingleAliasDeclarationWithIndexByIsSupported()
{
$entityManager = $this->_em;
$query = $entityManager->createQuery('SELECT u.* FROM CmsUser u INDEX BY u.id');
$query = $entityManager->createQuery('SELECT u FROM CmsUser u INDEX BY u.id');
$parserResult = $query->parse();
$decl = $parserResult->getQueryComponent('u');
......@@ -76,12 +74,12 @@ class Orm_Query_IdentifierRecognitionTest extends Doctrine_OrmTestCase
public function testQueryParserSupportsMultipleAliasDeclarations()
{
$entityManager = $this->_em;
$query = $entityManager->createQuery('SELECT u.* FROM CmsUser u INDEX BY u.id LEFT JOIN u.phonenumbers p');
$query = $entityManager->createQuery('SELECT u FROM CmsUser u INDEX BY u.id LEFT JOIN u.phonenumbers p');
$parserResult = $query->parse();
$decl = $parserResult->getQueryComponent('u');
$this->assertTrue($decl['metadata'] instanceof Doctrine_ClassMetadata);
$this->assertTrue($decl['metadata'] instanceof Doctrine_ORM_Mapping_ClassMetadata);
$this->assertEquals(null, $decl['relation']);
$this->assertEquals(null, $decl['parent']);
$this->assertEquals(null, $decl['scalar']);
......@@ -89,8 +87,8 @@ class Orm_Query_IdentifierRecognitionTest extends Doctrine_OrmTestCase
$decl = $parserResult->getQueryComponent('p');
$this->assertTrue($decl['metadata'] instanceof Doctrine_ClassMetadata);
$this->assertTrue($decl['relation'] instanceof Doctrine_Association);
$this->assertTrue($decl['metadata'] instanceof Doctrine_ORM_Mapping_ClassMetadata);
$this->assertTrue($decl['relation'] instanceof Doctrine_ORM_Mapping_AssociationMapping);
$this->assertEquals('u', $decl['parent']);
$this->assertEquals(null, $decl['scalar']);
$this->assertEquals(null, $decl['map']);
......@@ -100,12 +98,12 @@ class Orm_Query_IdentifierRecognitionTest extends Doctrine_OrmTestCase
public function testQueryParserSupportsMultipleAliasDeclarationsWithIndexBy()
{
$entityManager = $this->_em;
$query = $entityManager->createQuery('SELECT u.* FROM CmsUser u INDEX BY u.id LEFT JOIN u.articles a INNER JOIN u.phonenumbers pn INDEX BY pn.phonenumber');
$query = $entityManager->createQuery('SELECT u FROM CmsUser u INDEX BY u.id LEFT JOIN u.articles a INNER JOIN u.phonenumbers pn INDEX BY pn.phonenumber');
$parserResult = $query->parse();
$decl = $parserResult->getQueryComponent('u');
$this->assertTrue($decl['metadata'] instanceof Doctrine_ClassMetadata);
$this->assertTrue($decl['metadata'] instanceof Doctrine_ORM_Mapping_ClassMetadata);
$this->assertEquals(null, $decl['relation']);
$this->assertEquals(null, $decl['parent']);
$this->assertEquals(null, $decl['scalar']);
......@@ -113,16 +111,16 @@ class Orm_Query_IdentifierRecognitionTest extends Doctrine_OrmTestCase
$decl = $parserResult->getQueryComponent('a');
$this->assertTrue($decl['metadata'] instanceof Doctrine_ClassMetadata);
$this->assertTrue($decl['relation'] instanceof Doctrine_Association);
$this->assertTrue($decl['metadata'] instanceof Doctrine_ORM_Mapping_ClassMetadata);
$this->assertTrue($decl['relation'] instanceof Doctrine_ORM_Mapping_AssociationMapping);
$this->assertEquals('u', $decl['parent']);
$this->assertEquals(null, $decl['scalar']);
$this->assertEquals(null, $decl['map']);
$decl = $parserResult->getQueryComponent('pn');
$this->assertTrue($decl['metadata'] instanceof Doctrine_ClassMetadata);
$this->assertTrue($decl['relation'] instanceof Doctrine_Association);
$this->assertTrue($decl['metadata'] instanceof Doctrine_ORM_Mapping_ClassMetadata);
$this->assertTrue($decl['relation'] instanceof Doctrine_ORM_Mapping_AssociationMapping);
$this->assertEquals('u', $decl['parent']);
$this->assertEquals(null, $decl['scalar']);
$this->assertEquals('phonenumber', $decl['map']);
......
......@@ -37,18 +37,20 @@ require_once 'lib/DoctrineTestInit.php';
*/
class Orm_Query_SelectSqlGenerationTest extends Doctrine_OrmTestCase
{
private $_em;
protected function setUp() {
$this->_em = $this->_getTestEntityManager();
}
public function assertSqlGeneration($dqlToBeTested, $sqlToBeConfirmed)
{
try {
$entityManager = $this->_em;
$query = $entityManager->createQuery($dqlToBeTested);
//echo print_r($query->parse()->getQueryFields(), true) . "\n";
$query = $this->_em->createQuery($dqlToBeTested);
parent::assertEquals($sqlToBeConfirmed, $query->getSql());
//echo $query->getSql() . "\n";
$query->free();
} catch (Doctrine_Exception $e) {
echo $e->getTraceAsString(); die();
$this->fail($e->getMessage());
}
}
......@@ -57,71 +59,65 @@ class Orm_Query_SelectSqlGenerationTest extends Doctrine_OrmTestCase
public function testPlainFromClauseWithoutAlias()
{
$this->assertSqlGeneration(
'SELECT * FROM CmsUser',
'SELECT cu.id AS cu__id, cu.status AS cu__status, cu.username AS cu__username, cu.name AS cu__name FROM cms_user cu WHERE 1 = 1'
'SELECT u FROM CmsUser u',
'SELECT cu.id AS cu__id, cu.status AS cu__status, cu.username AS cu__username, cu.name AS cu__name FROM CmsUser cu'
);
$this->assertSqlGeneration(
'SELECT id FROM CmsUser',
'SELECT cu.id AS cu__id FROM cms_user cu WHERE 1 = 1'
'SELECT u.id FROM CmsUser u',
'SELECT cu.id AS cu__id FROM CmsUser cu'
);
}
public function testPlainFromClauseWithAlias()
{
$this->assertSqlGeneration(
'SELECT u.id FROM CmsUser u',
'SELECT cu.id AS cu__id FROM cms_user cu WHERE 1 = 1'
);
}
public function testSelectSingleComponentWithAsterisk()
public function testSelectSingleComponentWithMultipleColumns()
{
$this->assertSqlGeneration(
'SELECT u.* FROM CmsUser u',
'SELECT cu.id AS cu__id, cu.status AS cu__status, cu.username AS cu__username, cu.name AS cu__name FROM cms_user cu WHERE 1 = 1'
'SELECT u.username, u.name FROM CmsUser u',
'SELECT cu.username AS cu__username, cu.name AS cu__name FROM CmsUser cu'
);
}
public function testSelectSingleComponentWithMultipleColumns()
public function testSelectWithCollectionAssociationJoin()
{
$this->assertSqlGeneration(
'SELECT u.username, u.name FROM CmsUser u',
'SELECT cu.username AS cu__username, cu.name AS cu__name FROM cms_user cu WHERE 1 = 1'
'SELECT u, p FROM CmsUser u JOIN u.phonenumbers p',
'SELECT cu.id AS cu__id, cu.status AS cu__status, cu.username AS cu__username, cu.name AS cu__name, cp.phonenumber AS cp__phonenumber FROM CmsUser cu INNER JOIN CmsPhonenumber cp ON cu.id = cp.user_id'
);
}
public function testSelectMultipleComponentsWithAsterisk()
public function testSelectWithSingleValuedAssociationJoin()
{
$this->assertSqlGeneration(
'SELECT u.*, p.* FROM CmsUser u, u.phonenumbers p',
'SELECT cu.id AS cu__id, cu.status AS cu__status, cu.username AS cu__username, cu.name AS cu__name, cp.user_id AS cp__user_id, cp.phonenumber AS cp__phonenumber FROM cms_user cu, cms_phonenumber cp WHERE 1 = 1'
'SELECT u, a FROM ForumUser u JOIN u.avatar a',
'SELECT fu.id AS fu__id, fu.username AS fu__username, fa.id AS fa__id FROM ForumUser fu INNER JOIN ForumAvatar fa ON fu.avatar_id = fa.id'
);
}
public function testSelectDistinctIsSupported()
{
$this->assertSqlGeneration(
'SELECT DISTINCT u.name FROM CmsUser u',
'SELECT DISTINCT cu.name AS cu__name FROM cms_user cu WHERE 1 = 1'
'SELECT DISTINCT cu.name AS cu__name FROM CmsUser cu'
);
}
public function testAggregateFunctionInSelect()
{
$this->assertSqlGeneration(
'SELECT COUNT(u.id) FROM CmsUser u GROUP BY u.id',
'SELECT COUNT(cu.id) AS dctrn__0 FROM cms_user cu WHERE 1 = 1 GROUP BY cu.id'
'SELECT COUNT(cu.id) AS dctrn__0 FROM CmsUser cu GROUP BY cu.id'
);
}
public function testAggregateFunctionWithDistinctInSelect()
/* public function testWhereClauseInSelect()
{
$this->assertSqlGeneration(
'select u from ForumUser u where u.id = ?',
'SELECT fu.id AS fu__id, fu.username AS fu__username FROM ForumUser fu WHERE fu.id = ?'
);
}
*/
/* public function testAggregateFunctionWithDistinctInSelect()
{
$this->assertSqlGeneration(
'SELECT COUNT(DISTINCT u.name) FROM CmsUser u',
......@@ -209,5 +205,5 @@ class Orm_Query_SelectSqlGenerationTest extends Doctrine_OrmTestCase
'SELECT cu.id AS cu__id, ca.id AS ca__id FROM cms_user cu INNER JOIN cms_article ca ON cu.id = ca.user_id WHERE 1 = 1'
);
}
*/
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment