Commit b718cd1a authored by romanb's avatar romanb

[2.0] Parser work.

parent bffd76d7
<?php
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
namespace Doctrine\ORM\Query\AST;
/**
* Description of BetweenExpression
*
* @author robo
*/
class BetweenExpression extends Node
{
private $_baseExpression;
private $_leftBetweenExpression;
private $_rightBetweenExpression;
private $_not;
public function __construct($baseExpr, $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;
}
}
<?php
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
namespace Doctrine\ORM\Query\AST;
/**
* DeleteClause ::= "DELETE" ["FROM"] AbstractSchemaName [["AS"] AliasIdentificationVariable]
*/
class DeleteClause extends Node
{
private $_abstractSchemaName;
private $_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;
}
}
......@@ -32,11 +32,10 @@ namespace Doctrine\ORM\Query\AST;
*/
class DeleteStatement extends Node
{
protected $_deleteClause;
protected $_whereClause;
/* Setters */
public function setDeleteClause($deleteClause)
private $_deleteClause;
private $_whereClause;
public function __construct($deleteClause)
{
$this->_deleteClause = $deleteClause;
}
......@@ -46,7 +45,6 @@ class DeleteStatement extends Node
$this->_whereClause = $whereClause;
}
/* Getters */
public function getDeleteClause()
{
return $this->_deleteClause;
......@@ -56,14 +54,4 @@ class DeleteStatement extends Node
{
return $this->_whereClause;
}
/* REMOVE ME LATER. COPIED METHODS FROM SPLIT OF PRODUCTION INTO "AST" AND "PARSER" */
public function buildSql()
{
// The 1=1 is needed to workaround the affected_rows in MySQL.
// Simple "DELETE FROM table_name" gives 0 affected rows.
return $this->_deleteClause->buildSql() . (($this->_whereClause !== null)
? ' ' . $this->_whereClause->buildSql() : ' WHERE 1 = 1');
}
}
\ No newline at end of file
<?php
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
namespace Doctrine\ORM\Query\AST;
/**
* Description of HavingClause
*
* @author robo
*/
class HavingClause extends Node
{
private $_conditionalExpression;
public function __construct($conditionalExpression)
{
$this->_conditionalExpression = $conditionalExpression;
}
public function getConditionalExpression()
{
return $this->_conditionalExpression;
}
}
\ No newline at end of file
<?php
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
namespace Doctrine\ORM\Query\AST;
/**
* OrderByClause ::= "ORDER" "BY" OrderByItem {"," OrderByItem}*
*
* @author robo
*/
class OrderByClause extends Node
{
private $_orderByItems = array();
public function __construct(array $orderByItems)
{
$this->_orderByItems = $orderByItems;
}
public function getOrderByItems()
{
return $this->_orderByItems;
}
}
\ No newline at end of file
<?php
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
namespace Doctrine\ORM\Query\AST;
/**
* OrderByItem ::= StateFieldPathExpression ["ASC" | "DESC"]
*
* @author robo
*/
class OrderByItem extends Node
{
private $_pathExpr;
private $_asc;
private $_desc;
public function __construct($pathExpr)
{
$this->_pathExpr = $pathExpr;
}
public function getStateFieldPathExpression()
{
return $this->_pathExpr;
}
public function setAsc($bool)
{
$this->_asc = $bool;
}
public function isAsc()
{
return $this->_asc;
}
public function setDesc($bool)
{
$this->_desc = $bool;
}
public function isDesc()
{
return $this->_desc;
}
}
\ No newline at end of file
......@@ -16,7 +16,7 @@
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information, see
* <http://www.phpdoctrine.org>.
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\ORM\Query\AST;
......@@ -26,7 +26,7 @@ namespace Doctrine\ORM\Query\AST;
*
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @link http://www.phpdoctrine.org
* @link http://www.doctrine-project.org
* @since 2.0
* @version $Revision$
*/
......
......@@ -22,7 +22,7 @@
namespace Doctrine\ORM\Query\AST;
/**
* SimpleSelectClause ::= "SELECT" [DISTINCT"] SimpleSelectExpression
* SimpleSelectClause ::= "SELECT" ["DISTINCT"] SimpleSelectExpression
*
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
......
<?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.doctrine-project.org>.
*/
namespace Doctrine\ORM\Query\AST;
/**
* SimpleSelectExpression ::= StateFieldPathExpression | IdentificationVariable
* | (AggregateExpression [["AS"] FieldAliasIdentificationVariable])
*
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @link http://www.doctrine-project.org
* @since 2.0
* @version $Revision$
*/
class SimpleSelectExpression extends Node
{
private $_expression;
private $_fieldIdentificationVariable;
public function __construct($expression)
{
$this->_expression = $expression;
}
public function getExpression()
{
return $this->_expression;
}
public function getFieldIdentificationVariable()
{
return $this->_fieldIdentificationVariable;
}
public function setFieldIdentificationVariable($fieldAlias)
{
$this->_fieldIdentificationVariable = $fieldAlias;
}
}
\ No newline at end of file
......@@ -40,7 +40,7 @@ class SubselectFromClause extends Node
}
/* Getters */
public function geSubselectIdentificationVariableDeclarations()
public function getSubselectIdentificationVariableDeclarations()
{
return $this->_identificationVariableDeclarations;
}
......
<?php
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
namespace Doctrine\ORM\Query\AST;
/**
* UpdateClause ::= "UPDATE" AbstractSchemaName [["AS"] AliasIdentificationVariable] "SET" UpdateItem {"," UpdateItem}*
*/
class UpdateClause extends Node
{
private $_abstractSchemaName;
private $_aliasIdentificationVariable;
private $_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;
}
}
<?php
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
namespace Doctrine\ORM\Query\AST;
/**
* UpdateItem ::= [IdentificationVariable "."] {StateField | SingleValuedAssociationField} "=" NewValue
*
* @author robo
*/
class UpdateItem extends Node
{
private $_identificationVariable;
private $_field;
private $_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;
}
}
......@@ -16,7 +16,7 @@
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information, see
* <http://www.phpdoctrine.org>.
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\ORM\Query\AST;
......@@ -26,17 +26,16 @@ namespace Doctrine\ORM\Query\AST;
*
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @link http://www.phpdoctrine.org
* @link http://www.doctrine-project.org
* @since 2.0
* @version $Revision$
*/
class UpdateStatement extends Node
{
protected $_updateClause;
protected $_whereClause;
/* Setters */
public function setUpdateClause($updateClause)
private $_updateClause;
private $_whereClause;
public function __construct($updateClause)
{
$this->_updateClause = $updateClause;
}
......@@ -46,7 +45,6 @@ class UpdateStatement extends Node
$this->_whereClause = $whereClause;
}
/* Getters */
public function getUpdateClause()
{
return $this->_updateClause;
......@@ -56,13 +54,4 @@ class UpdateStatement extends Node
{
return $this->_whereClause;
}
/* REMOVE ME LATER. COPIED METHODS FROM SPLIT OF PRODUCTION INTO "AST" AND "PARSER" */
public function buildSql()
{
// The 1=1 is needed to workaround the affected_rows in MySQL.
// Simple "UPDATE table_name SET column_name = value" gives 0 affected rows.
return $this->_updateClause->buildSql() . (($this->_whereClause !== null)
? ' ' . $this->_whereClause->buildSql() : ' WHERE 1 = 1');
}
}
\ No newline at end of file
......@@ -17,7 +17,7 @@
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information, see
* <http://www.phpdoctrine.org>.
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\ORM\Query;
......@@ -26,7 +26,7 @@ namespace Doctrine\ORM\Query;
* Doctrine_ORM_Query_AbstractResult
*
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @link www.phpdoctrine.com
* @link www.doctrine-project.com
* @since 2.0
* @version $Revision: 1393 $
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
......
......@@ -79,7 +79,7 @@ abstract class AbstractExecutor implements \Serializable
}
} else ...
*/
return new SingleTableDeleteUpdateExecutor($AST);
return new SingleTableDeleteUpdateExecutor($AST, $sqlWalker);
} else {
return new SingleSelectExecutor($AST, $sqlWalker);
}
......
......@@ -16,11 +16,13 @@
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information, see
* <http://www.phpdoctrine.org>.
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\ORM\Query\Exec;
use Doctrine\ORM\Query\AST;
/**
* Executor that executes the SQL statements for DQL DELETE/UPDATE statements on classes
* that are mapped to a single table.
......@@ -28,16 +30,20 @@ namespace Doctrine\ORM\Query\Exec;
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @author Roman Borschel <roman@code-factory.org>
* @version $Revision$
* @link www.phpdoctrine.org
* @link www.doctrine-project.org
* @since 2.0
* @todo This is exactly the same as SingleSelectExecutor. Unify in SingleStatementExecutor.
*/
class SingleTableDeleteUpdateExecutor extends AbstractExecutor
{
public function __construct(\Doctrine\ORM\Query\AST\Node $AST)
public function __construct(AST\Node $AST, $sqlWalker)
{
parent::__construct($AST);
$this->_sqlStatements = $AST->buildSql();
parent::__construct($AST, $sqlWalker);
if ($AST instanceof AST\UpdateStatement) {
$this->_sqlStatements = $sqlWalker->walkUpdateStatement($AST);
} else if ($AST instanceof AST\DeleteStatement) {
$this->_sqlStatements = $sqlWalker->walkDeleteStatement($AST);
}
}
public function execute(\Doctrine\DBAL\Connection $conn, array $params)
......
This diff is collapsed.
......@@ -181,27 +181,16 @@ class SqlWalker
}
else if ($selectExpression->getExpression() instanceof 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() . '(';
if ($aggExpr->isDistinct()) $sql .= 'DISTINCT ';
$sql .= $this->_dqlToSqlAliasMap[$dqlAlias] . '.' . $columnName;
$sql .= ') AS dctrn__' . $alias;
$sql .= $this->walkAggregateExpression($aggExpr) . ' AS dctrn__' . $alias;
}
//TODO: else if Subselect
else {
else if ($selectExpression->getExpression() instanceof AST\Subselect) {
$sql .= $this->walkSubselect($selectExpression->getExpression());
} else {
$dqlAlias = $selectExpression->getExpression();
$queryComp = $this->_parserResult->getQueryComponent($dqlAlias);
$class = $queryComp['metadata'];
......@@ -221,6 +210,80 @@ class SqlWalker
return $sql;
}
public function walkSubselect($subselect)
{
$sql = $this->walkSimpleSelectClause($subselect->getSimpleSelectClause());
$sql .= $this->walkSubselectFromClause($subselect->getSubselectFromClause());
$sql .= $subselect->getWhereClause() ? $this->walkWhereClause($subselect->getWhereClause()) : '';
$sql .= $subselect->getGroupByClause() ? $this->walkGroupByClause($subselect->getGroupByClause()) : '';
//... more clauses
return $sql;
}
public function walkSubselectFromClause($subselectFromClause)
{
$sql = ' FROM ';
$identificationVarDecls = $subselectFromClause->getSubselectIdentificationVariableDeclarations();
$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;
}
public function walkSimpleSelectClause($simpleSelectClause)
{
$sql = 'SELECT';
if ($simpleSelectClause->isDistinct()) {
$sql .= ' DISTINCT';
}
$sql .= $this->walkSimpleSelectExpression($simpleSelectClause->getSimpleSelectExpression());
return $sql;
}
public function walkSimpleSelectExpression($simpleSelectExpression)
{
$sql = '';
$expr = $simpleSelectExpression->getExpression();
if ($expr instanceof AST\PathExpression) {
//...
} else if ($expr instanceof AST\AggregateExpression) {
if ( ! $simpleSelectExpression->getFieldIdentificationVariable()) {
$alias = $this->_scalarAliasCounter++;
} else {
$alias = $simpleSelectExpression->getFieldIdentificationVariable();
}
$sql .= $this->walkAggregateExpression($expr) . ' AS dctrn__' . $alias;
} else {
// $expr is IdentificationVariable
//...
}
return $sql;
}
public function walkAggregateExpression($aggExpression)
{
$sql = '';
$parts = $aggExpression->getPathExpression()->getParts();
$dqlAlias = $parts[0];
$fieldName = $parts[1];
$qComp = $this->_parserResult->getQueryComponent($dqlAlias);
$columnName = $qComp['metadata']->getColumnName($fieldName);
$sql .= $aggExpression->getFunctionName() . '(';
if ($aggExpression->isDistinct()) $sql .= 'DISTINCT ';
$sql .= $this->_dqlToSqlAliasMap[$dqlAlias] . '.' . $columnName;
$sql .= ')';
return $sql;
}
public function walkGroupByClause($groupByClause)
{
return ' GROUP BY '
......
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