Fixes in unit tests.
Started refactoring in DQL parser to separate Production into Parser and AST classes. Finished first tests. Currently only 4 are active in IdentifierRecognitionTest, and only 2 are passing.
This commit is contained in:
parent
4b191a3141
commit
ad4db34a87
@ -104,7 +104,7 @@ class Doctrine_ConnectionFactory
|
|||||||
|
|
||||||
// driver
|
// driver
|
||||||
if ( isset($params['driver']) && ! isset($this->_drivers[$params['driver']])) {
|
if ( isset($params['driver']) && ! isset($this->_drivers[$params['driver']])) {
|
||||||
throw Doctrine_ConnectionFactory_Exception::unknownDriver($driverName);
|
throw Doctrine_ConnectionFactory_Exception::unknownDriver($params['driver']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
49
lib/Doctrine/ConnectionFactory/Exception.php
Normal file
49
lib/Doctrine/ConnectionFactory/Exception.php
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* $Id: Exception.php 1080 2007-02-10 18:17:08Z romanb $
|
||||||
|
*
|
||||||
|
* 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>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Doctrine_ConnectionFactory_Exception
|
||||||
|
*
|
||||||
|
* @package Doctrine
|
||||||
|
* @subpackage Hydrate
|
||||||
|
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||||
|
* @link www.phpdoctrine.org
|
||||||
|
* @since 1.0
|
||||||
|
* @version $Revision: 1080 $
|
||||||
|
* @author Konsta Vesterinen <kvesteri@cc.hut.fi>
|
||||||
|
*/
|
||||||
|
class Doctrine_ConnectionFactory_Exception extends Doctrine_Exception
|
||||||
|
{
|
||||||
|
public static function invalidPDOInstance()
|
||||||
|
{
|
||||||
|
return new self("Invalid PDO instance provided on connection creation.");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function driverRequired()
|
||||||
|
{
|
||||||
|
return new self("Please provide a driver or a driverClass to be able to start a Connection.");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function unknownDriver($driver)
|
||||||
|
{
|
||||||
|
return new self("Unknown Connection driver '$driver'.");
|
||||||
|
}
|
||||||
|
}
|
@ -944,7 +944,7 @@ abstract class Doctrine_DatabasePlatform
|
|||||||
*
|
*
|
||||||
* @todo Throw exception by default?
|
* @todo Throw exception by default?
|
||||||
*/
|
*/
|
||||||
public function getDropIndexSql($index)
|
public function getDropIndexSql($index, $name)
|
||||||
{
|
{
|
||||||
return 'DROP INDEX ' . $index;
|
return 'DROP INDEX ' . $index;
|
||||||
}
|
}
|
||||||
@ -982,7 +982,7 @@ abstract class Doctrine_DatabasePlatform
|
|||||||
*
|
*
|
||||||
* @todo Throw exception by default?
|
* @todo Throw exception by default?
|
||||||
*/
|
*/
|
||||||
public function getCreateTableSql($table, array $columns, array $options)
|
public function getCreateTableSql($table, array $columns, array $options = array())
|
||||||
{
|
{
|
||||||
if ( ! $table) {
|
if ( ! $table) {
|
||||||
throw new Doctrine_Export_Exception('no valid table name specified');
|
throw new Doctrine_Export_Exception('no valid table name specified');
|
||||||
|
@ -347,10 +347,10 @@ class Doctrine_HydratorNew extends Doctrine_Hydrator_Abstract
|
|||||||
if ($this->_isIgnoredName($key)) continue;
|
if ($this->_isIgnoredName($key)) continue;
|
||||||
|
|
||||||
// Cache general information like the column name <-> field name mapping
|
// Cache general information like the column name <-> field name mapping
|
||||||
$e = explode(Doctrine_Query_Production::SQLALIAS_SEPARATOR, $key);
|
$e = explode(Doctrine_Query_ParserRule::SQLALIAS_SEPARATOR, $key);
|
||||||
$columnName = array_pop($e);
|
$columnName = array_pop($e);
|
||||||
$cache[$key]['dqlAlias'] = $this->_tableAliases[
|
$cache[$key]['dqlAlias'] = $this->_tableAliases[
|
||||||
implode(Doctrine_Query_Production::SQLALIAS_SEPARATOR, $e)
|
implode(Doctrine_Query_ParserRule::SQLALIAS_SEPARATOR, $e)
|
||||||
];
|
];
|
||||||
$classMetadata = $this->_queryComponents[$cache[$key]['dqlAlias']]['metadata'];
|
$classMetadata = $this->_queryComponents[$cache[$key]['dqlAlias']]['metadata'];
|
||||||
// check whether it's an aggregate value or a regular field
|
// check whether it's an aggregate value or a regular field
|
||||||
@ -432,10 +432,10 @@ class Doctrine_HydratorNew extends Doctrine_Hydrator_Abstract
|
|||||||
if ($this->_isIgnoredName($key)) continue;
|
if ($this->_isIgnoredName($key)) continue;
|
||||||
|
|
||||||
// cache general information like the column name <-> field name mapping
|
// cache general information like the column name <-> field name mapping
|
||||||
$e = explode(Doctrine_Query_Production::SQLALIAS_SEPARATOR, $key);
|
$e = explode(Doctrine_Query_ParserRule::SQLALIAS_SEPARATOR, $key);
|
||||||
$columnName = array_pop($e);
|
$columnName = array_pop($e);
|
||||||
$cache[$key]['dqlAlias'] = $this->_tableAliases[
|
$cache[$key]['dqlAlias'] = $this->_tableAliases[
|
||||||
implode(Doctrine_Query_Production::SQLALIAS_SEPARATOR, $e)
|
implode(Doctrine_Query_ParserRule::SQLALIAS_SEPARATOR, $e)
|
||||||
];
|
];
|
||||||
$classMetadata = $this->_queryComponents[$cache[$key]['dqlAlias']]['metadata'];
|
$classMetadata = $this->_queryComponents[$cache[$key]['dqlAlias']]['metadata'];
|
||||||
// check whether it's an aggregate value or a regular field
|
// check whether it's an aggregate value or a regular field
|
||||||
|
43
lib/Doctrine/Query/AST.php
Normal file
43
lib/Doctrine/Query/AST.php
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
<?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>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Abstract class of an AST node
|
||||||
|
*
|
||||||
|
* @package Doctrine
|
||||||
|
* @subpackage Query
|
||||||
|
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
|
||||||
|
* @author Janne Vanhala <jpvanhal@cc.hut.fi>
|
||||||
|
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||||
|
* @link http://www.phpdoctrine.org
|
||||||
|
* @since 2.0
|
||||||
|
* @version $Revision$
|
||||||
|
*/
|
||||||
|
abstract class Doctrine_Query_AST
|
||||||
|
{
|
||||||
|
protected $_parserResult = null;
|
||||||
|
|
||||||
|
|
||||||
|
public function __construct(Doctrine_Query_ParserResult $parserResult)
|
||||||
|
{
|
||||||
|
$this->_parserResult = $parserResult;
|
||||||
|
}
|
||||||
|
}
|
50
lib/Doctrine/Query/AST/AbstractSchemaName.php
Normal file
50
lib/Doctrine/Query/AST/AbstractSchemaName.php
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
<?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>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* AbstractSchemaName ::= identifier
|
||||||
|
*
|
||||||
|
* @package Doctrine
|
||||||
|
* @subpackage Query
|
||||||
|
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
|
||||||
|
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||||
|
* @link http://www.phpdoctrine.org
|
||||||
|
* @since 2.0
|
||||||
|
* @version $Revision$
|
||||||
|
*/
|
||||||
|
class Doctrine_Query_AST_AbstractSchemaName extends Doctrine_Query_AST
|
||||||
|
{
|
||||||
|
protected $_componentName;
|
||||||
|
|
||||||
|
|
||||||
|
/* Setters */
|
||||||
|
public function setComponentName($componentName)
|
||||||
|
{
|
||||||
|
$this->_componentName = $componentName;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Getters */
|
||||||
|
public function getComponentName()
|
||||||
|
{
|
||||||
|
return $this->_componentName;
|
||||||
|
}
|
||||||
|
}
|
50
lib/Doctrine/Query/AST/AliasIdentificationVariable.php
Normal file
50
lib/Doctrine/Query/AST/AliasIdentificationVariable.php
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
<?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>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* AliasIdentificationVariable ::= identifier
|
||||||
|
*
|
||||||
|
* @package Doctrine
|
||||||
|
* @subpackage Query
|
||||||
|
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
|
||||||
|
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||||
|
* @link http://www.phpdoctrine.org
|
||||||
|
* @since 2.0
|
||||||
|
* @version $Revision$
|
||||||
|
*/
|
||||||
|
class Doctrine_Query_AST_AliasIdentificationVariable extends Doctrine_Query_AST
|
||||||
|
{
|
||||||
|
protected $_componentAlias;
|
||||||
|
|
||||||
|
|
||||||
|
/* Setters */
|
||||||
|
public function setComponentAlias($componentAlias)
|
||||||
|
{
|
||||||
|
$this->_componentAlias = $componentAlias;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Getters */
|
||||||
|
public function getComponentAlias()
|
||||||
|
{
|
||||||
|
return $this->_componentAlias;
|
||||||
|
}
|
||||||
|
}
|
75
lib/Doctrine/Query/AST/DeleteStatement.php
Normal file
75
lib/Doctrine/Query/AST/DeleteStatement.php
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
<?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>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DeleteStatement = DeleteClause [WhereClause]
|
||||||
|
*
|
||||||
|
* @package Doctrine
|
||||||
|
* @subpackage Query
|
||||||
|
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
|
||||||
|
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||||
|
* @link http://www.phpdoctrine.org
|
||||||
|
* @since 2.0
|
||||||
|
* @version $Revision$
|
||||||
|
*/
|
||||||
|
class Doctrine_Query_AST_DeleteStatement extends Doctrine_Query_AST
|
||||||
|
{
|
||||||
|
protected $_deleteClause;
|
||||||
|
|
||||||
|
protected $_whereClause;
|
||||||
|
|
||||||
|
|
||||||
|
/* Setters */
|
||||||
|
public function setDeleteClause($deleteClause)
|
||||||
|
{
|
||||||
|
$this->_deleteClause = $deleteClause;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function setWhereClause($whereClause)
|
||||||
|
{
|
||||||
|
$this->_whereClause = $whereClause;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Getters */
|
||||||
|
public function getDeleteClause()
|
||||||
|
{
|
||||||
|
return $this->_deleteClause;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function getWhereClause()
|
||||||
|
{
|
||||||
|
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');
|
||||||
|
}
|
||||||
|
}
|
50
lib/Doctrine/Query/AST/FieldIdentificationVariable.php
Normal file
50
lib/Doctrine/Query/AST/FieldIdentificationVariable.php
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
<?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>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* FieldIdentificationVariable ::= identifier
|
||||||
|
*
|
||||||
|
* @package Doctrine
|
||||||
|
* @subpackage Query
|
||||||
|
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
|
||||||
|
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||||
|
* @link http://www.phpdoctrine.org
|
||||||
|
* @since 2.0
|
||||||
|
* @version $Revision$
|
||||||
|
*/
|
||||||
|
class Doctrine_Query_AST_FieldIdentificationVariable extends Doctrine_Query_AST
|
||||||
|
{
|
||||||
|
protected $_fieldName;
|
||||||
|
|
||||||
|
|
||||||
|
/* Setters */
|
||||||
|
public function setFieldName($fieldName)
|
||||||
|
{
|
||||||
|
$this->_fieldName = $fieldName;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Getters */
|
||||||
|
public function getFieldName()
|
||||||
|
{
|
||||||
|
return $this->_fieldName;
|
||||||
|
}
|
||||||
|
}
|
87
lib/Doctrine/Query/AST/FromClause.php
Normal file
87
lib/Doctrine/Query/AST/FromClause.php
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
<?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>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* FromClause ::= "FROM" IdentificationVariableDeclaration {"," IdentificationVariableDeclaration}
|
||||||
|
*
|
||||||
|
* @package Doctrine
|
||||||
|
* @subpackage Query
|
||||||
|
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
|
||||||
|
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||||
|
* @link http://www.phpdoctrine.org
|
||||||
|
* @since 2.0
|
||||||
|
* @version $Revision$
|
||||||
|
*/
|
||||||
|
class Doctrine_Query_AST_FromClause extends Doctrine_Query_AST
|
||||||
|
{
|
||||||
|
protected $_identificationVariableDeclarations = array();
|
||||||
|
|
||||||
|
|
||||||
|
/* Setters */
|
||||||
|
public function addIdentificationVariableDeclaration($identificationVariableDeclaration)
|
||||||
|
{
|
||||||
|
$this->_identificationVariableDeclarations[] = $identificationVariableDeclaration;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function setIdentificationVariableDeclarations($identificationVariableDeclarations, $append = false)
|
||||||
|
{
|
||||||
|
$this->_selectExpressions = ($append === true)
|
||||||
|
? array_merge($this->_identificationVariableDeclarations, $identificationVariableDeclarations)
|
||||||
|
: $identificationVariableDeclarations;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Getters */
|
||||||
|
public function getIdentificationVariableDeclarations()
|
||||||
|
{
|
||||||
|
return $this->_identificationVariableDeclarations;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* REMOVE ME LATER. COPIED METHODS FROM SPLIT OF PRODUCTION INTO "AST" AND "PARSER" */
|
||||||
|
|
||||||
|
public function buildSql()
|
||||||
|
{
|
||||||
|
//echo "FromClause:\n";
|
||||||
|
//for ($i = 0; $i < count($this->_identificationVariableDeclaration);$i++) {
|
||||||
|
// echo (($this->_identificationVariableDeclaration[$i] instanceof IdentificationVariableDeclaration)
|
||||||
|
// ? get_class($this->_identificationVariableDeclaration[$i])
|
||||||
|
// : get_class($this->_identificationVariableDeclaration[$i])) . "\n";
|
||||||
|
//}
|
||||||
|
|
||||||
|
return 'FROM ' . implode(', ', $this->_mapIdentificationVariableDeclarations());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected function _mapIdentificationVariableDeclarations()
|
||||||
|
{
|
||||||
|
return array_map(
|
||||||
|
array(&$this, '_mapIdentificationVariableDeclaration'), $this->_identificationVariableDeclarations
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected function _mapIdentificationVariableDeclaration($value)
|
||||||
|
{
|
||||||
|
return $value->buildSql();
|
||||||
|
}
|
||||||
|
}
|
62
lib/Doctrine/Query/AST/IdentificationVariable.php
Normal file
62
lib/Doctrine/Query/AST/IdentificationVariable.php
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
<?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>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* IdentificationVariable ::= identifier
|
||||||
|
*
|
||||||
|
* @package Doctrine
|
||||||
|
* @subpackage Query
|
||||||
|
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
|
||||||
|
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||||
|
* @link http://www.phpdoctrine.org
|
||||||
|
* @since 2.0
|
||||||
|
* @version $Revision$
|
||||||
|
*/
|
||||||
|
class Doctrine_Query_AST_IdentificationVariable extends Doctrine_Query_AST
|
||||||
|
{
|
||||||
|
protected $_componentAlias;
|
||||||
|
|
||||||
|
|
||||||
|
/* Setters */
|
||||||
|
public function setComponentAlias($componentAlias)
|
||||||
|
{
|
||||||
|
$this->_componentAlias = $componentAlias;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Getters */
|
||||||
|
public function getComponentAlias()
|
||||||
|
{
|
||||||
|
return $this->_componentAlias;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* REMOVE ME LATER. COPIED METHODS FROM SPLIT OF PRODUCTION INTO "AST" AND "PARSER" */
|
||||||
|
|
||||||
|
public function buildSql()
|
||||||
|
{
|
||||||
|
$conn = $this->_parserResult->getEntityManager()->getConnection();
|
||||||
|
|
||||||
|
return $conn->quoteIdentifier(
|
||||||
|
$this->_parserResult->getTableAliasFromComponentAlias($this->_componentAlias)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
100
lib/Doctrine/Query/AST/IdentificationVariableDeclaration.php
Normal file
100
lib/Doctrine/Query/AST/IdentificationVariableDeclaration.php
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
<?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>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* IdentificationVariableDeclaration ::= RangeVariableDeclaration [IndexBy] {JoinVariableDeclaration}*
|
||||||
|
*
|
||||||
|
* @package Doctrine
|
||||||
|
* @subpackage Query
|
||||||
|
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
|
||||||
|
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||||
|
* @link http://www.phpdoctrine.org
|
||||||
|
* @since 2.0
|
||||||
|
* @version $Revision$
|
||||||
|
*/
|
||||||
|
class Doctrine_Query_AST_IdentificationVariableDeclaration extends Doctrine_Query_AST
|
||||||
|
{
|
||||||
|
protected $_rangeVariableDeclaration = null;
|
||||||
|
|
||||||
|
protected $_indexBy = null;
|
||||||
|
|
||||||
|
protected $_joinVariableDeclarations = array();
|
||||||
|
|
||||||
|
|
||||||
|
/* Setters */
|
||||||
|
public function setRangeVariableDeclaration($rangeVariableDeclaration)
|
||||||
|
{
|
||||||
|
$this->_rangeVariableDeclaration = $rangeVariableDeclaration;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function setIndexBy($indexBy)
|
||||||
|
{
|
||||||
|
$this->_indexBy = $indexBy;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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()
|
||||||
|
{
|
||||||
|
return $this->_rangeVariableDeclaration;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function getIndexBy()
|
||||||
|
{
|
||||||
|
return $this->_indexBy;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function getJoinVariableDeclarations()
|
||||||
|
{
|
||||||
|
return $this->_joinVariableDeclarations;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* REMOVE ME LATER. COPIED METHODS FROM SPLIT OF PRODUCTION INTO "AST" AND "PARSER" */
|
||||||
|
|
||||||
|
public function buildSql()
|
||||||
|
{
|
||||||
|
$str = $this->_rangeVariableDeclaration->buildSql();
|
||||||
|
|
||||||
|
for ($i = 0, $l = count($this->_joinVariableDeclarations); $i < $l; $i++) {
|
||||||
|
$str .= ' ' . $this->_joinVariableDeclarations[$i]->buildSql();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $str;
|
||||||
|
}
|
||||||
|
}
|
50
lib/Doctrine/Query/AST/IndexBy.php
Normal file
50
lib/Doctrine/Query/AST/IndexBy.php
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
<?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>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* IndexBy ::= "INDEX" "BY" SimpleStateFieldPathExpression
|
||||||
|
*
|
||||||
|
* @package Doctrine
|
||||||
|
* @subpackage Query
|
||||||
|
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
|
||||||
|
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||||
|
* @link http://www.phpdoctrine.org
|
||||||
|
* @since 2.0
|
||||||
|
* @version $Revision$
|
||||||
|
*/
|
||||||
|
class Doctrine_Query_AST_IndexBy extends Doctrine_Query_AST
|
||||||
|
{
|
||||||
|
protected $_simpleStateFieldPathExpression = null;
|
||||||
|
|
||||||
|
|
||||||
|
/* Setters */
|
||||||
|
public function setSimpleStateFieldPathExpression($simpleStateFieldPathExpression)
|
||||||
|
{
|
||||||
|
$this->_simpleStateFieldPathExpression = $simpleStateFieldPathExpression;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Getters */
|
||||||
|
public function getSimpleStateFieldPathExpression()
|
||||||
|
{
|
||||||
|
return $this->_simpleStateFieldPathExpression;
|
||||||
|
}
|
||||||
|
}
|
89
lib/Doctrine/Query/AST/RangeVariableDeclaration.php
Normal file
89
lib/Doctrine/Query/AST/RangeVariableDeclaration.php
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
<?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>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* RangeVariableDeclaration ::= AbstractSchemaName ["AS"] AliasIdentificationVariable
|
||||||
|
*
|
||||||
|
* @package Doctrine
|
||||||
|
* @subpackage Query
|
||||||
|
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
|
||||||
|
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||||
|
* @link http://www.phpdoctrine.org
|
||||||
|
* @since 2.0
|
||||||
|
* @version $Revision$
|
||||||
|
*/
|
||||||
|
class Doctrine_Query_AST_RangeVariableDeclaration extends Doctrine_Query_AST
|
||||||
|
{
|
||||||
|
protected $_abstractSchemaName = null;
|
||||||
|
|
||||||
|
protected $_aliasIdentificationVariable = null;
|
||||||
|
|
||||||
|
|
||||||
|
/* Setters */
|
||||||
|
public function setAbstractSchemaName($abstractSchemaName)
|
||||||
|
{
|
||||||
|
$this->_abstractSchemaName = $abstractSchemaName;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function setAliasIdentificationVariable($aliasIdentificationVariable)
|
||||||
|
{
|
||||||
|
$this->_aliasIdentificationVariable = $aliasIdentificationVariable;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Getters */
|
||||||
|
public function getAbstractSchemaName()
|
||||||
|
{
|
||||||
|
return $this->_abstractSchemaName;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function getAliasIdentificationVariable()
|
||||||
|
{
|
||||||
|
return $this->_aliasIdentificationVariable;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* REMOVE ME LATER. COPIED METHODS FROM SPLIT OF PRODUCTION INTO "AST" AND "PARSER" */
|
||||||
|
|
||||||
|
public function buildSql()
|
||||||
|
{
|
||||||
|
// Retrieving connection
|
||||||
|
$conn = $this->_parserResult->getEntityManager()->getConnection();
|
||||||
|
|
||||||
|
// Component alias
|
||||||
|
$componentAlias = $this->_aliasIdentificationVariable->getComponentAlias();
|
||||||
|
|
||||||
|
// Retrieving required information
|
||||||
|
try {
|
||||||
|
$queryComponent = $this->_parserResult->getQueryComponent($componentAlias);
|
||||||
|
$classMetadata = $queryComponent['metadata'];
|
||||||
|
} catch (Doctrine_Exception $e) {
|
||||||
|
$this->_parser->semanticalError($e->getMessage());
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $conn->quoteIdentifier($classMetadata->getTableName()) . ' '
|
||||||
|
. $conn->quoteIdentifier($this->_parserResult->getTableAliasFromComponentAlias($componentAlias));
|
||||||
|
}
|
||||||
|
}
|
93
lib/Doctrine/Query/AST/SelectClause.php
Normal file
93
lib/Doctrine/Query/AST/SelectClause.php
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
<?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>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SelectClause = "SELECT" ["DISTINCT"] SelectExpression {"," SelectExpression}
|
||||||
|
*
|
||||||
|
* @package Doctrine
|
||||||
|
* @subpackage Query
|
||||||
|
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
|
||||||
|
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||||
|
* @link http://www.phpdoctrine.org
|
||||||
|
* @since 2.0
|
||||||
|
* @version $Revision$
|
||||||
|
*/
|
||||||
|
class Doctrine_Query_AST_SelectClause extends Doctrine_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)
|
||||||
|
{
|
||||||
|
$this->_selectExpressions = ($append === true)
|
||||||
|
? array_merge($this->_selectExpressions, $expressions)
|
||||||
|
: $expressions;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* 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 $value->buildSql();
|
||||||
|
}
|
||||||
|
}
|
132
lib/Doctrine/Query/AST/SelectStatement.php
Normal file
132
lib/Doctrine/Query/AST/SelectStatement.php
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
<?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>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SelectStatement = SelectClause FromClause [WhereClause] [GroupByClause] [HavingClause] [OrderByClause]
|
||||||
|
*
|
||||||
|
* @package Doctrine
|
||||||
|
* @subpackage Query
|
||||||
|
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
|
||||||
|
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||||
|
* @link http://www.phpdoctrine.org
|
||||||
|
* @since 2.0
|
||||||
|
* @version $Revision$
|
||||||
|
*/
|
||||||
|
class Doctrine_Query_AST_SelectStatement extends Doctrine_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)
|
||||||
|
{
|
||||||
|
$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()
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* REMOVE ME LATER. COPIED METHODS FROM SPLIT OF PRODUCTION INTO "AST" AND "PARSER" */
|
||||||
|
|
||||||
|
public function buildSql()
|
||||||
|
{
|
||||||
|
return $this->_selectClause->buildSql() . ' ' . $this->_fromClause->buildSql()
|
||||||
|
. (($this->_whereClause !== null) ? ' ' . $this->_whereClause->buildSql() : ' WHERE 1 = 1')
|
||||||
|
. (($this->_groupByClause !== null) ? ' ' . $this->_groupByClause->buildSql() : '')
|
||||||
|
. (($this->_havingClause !== null) ? ' ' . $this->_havingClause->buildSql() : '')
|
||||||
|
. (($this->_orderByClause !== null) ? ' ' . $this->_orderByClause->buildSql() : '');
|
||||||
|
}
|
||||||
|
}
|
64
lib/Doctrine/Query/AST/SimpleStateFieldPathExpression.php
Normal file
64
lib/Doctrine/Query/AST/SimpleStateFieldPathExpression.php
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
<?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>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SimpleStateFieldPathExpression ::= IdentificationVariable "." SimpleStateField
|
||||||
|
*
|
||||||
|
* @package Doctrine
|
||||||
|
* @subpackage Query
|
||||||
|
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
|
||||||
|
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||||
|
* @link http://www.phpdoctrine.org
|
||||||
|
* @since 2.0
|
||||||
|
* @version $Revision$
|
||||||
|
*/
|
||||||
|
class Doctrine_Query_AST_SimpleStateFieldPathExpression extends Doctrine_Query_AST
|
||||||
|
{
|
||||||
|
protected $_identificationVariable = null;
|
||||||
|
|
||||||
|
protected $_simpleStateField = null;
|
||||||
|
|
||||||
|
|
||||||
|
/* Setters */
|
||||||
|
public function setIdentificationVariable($identificationVariable)
|
||||||
|
{
|
||||||
|
$this->_identificationVariable = $identificationVariable;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function setSimpleStateField($simpleStateField)
|
||||||
|
{
|
||||||
|
$this->_simpleStateField = $simpleStateField;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Getters */
|
||||||
|
public function getIdentificationVariable()
|
||||||
|
{
|
||||||
|
return $this->_identificationVariable;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function getSimpleStateField()
|
||||||
|
{
|
||||||
|
return $this->_simpleStateField;
|
||||||
|
}
|
||||||
|
}
|
75
lib/Doctrine/Query/AST/UpdateStatetement.php
Normal file
75
lib/Doctrine/Query/AST/UpdateStatetement.php
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
<?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>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* UpdateStatement = UpdateClause [WhereClause]
|
||||||
|
*
|
||||||
|
* @package Doctrine
|
||||||
|
* @subpackage Query
|
||||||
|
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
|
||||||
|
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||||
|
* @link http://www.phpdoctrine.org
|
||||||
|
* @since 2.0
|
||||||
|
* @version $Revision$
|
||||||
|
*/
|
||||||
|
class Doctrine_Query_AST_UpdateStatement extends Doctrine_Query_AST
|
||||||
|
{
|
||||||
|
protected $_updateClause;
|
||||||
|
|
||||||
|
protected $_whereClause;
|
||||||
|
|
||||||
|
|
||||||
|
/* Setters */
|
||||||
|
public function setUpdateClause($updateClause)
|
||||||
|
{
|
||||||
|
$this->_updateClause = $updateClause;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function setWhereClause($whereClause)
|
||||||
|
{
|
||||||
|
$this->_whereClause = $whereClause;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Getters */
|
||||||
|
public function getUpdateClause()
|
||||||
|
{
|
||||||
|
return $this->_updateClause;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function getWhereClause()
|
||||||
|
{
|
||||||
|
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');
|
||||||
|
}
|
||||||
|
}
|
@ -1,355 +1,380 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Id$
|
* $Id$
|
||||||
*
|
*
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* This software consists of voluntary contributions made by many individuals
|
* This software consists of voluntary contributions made by many individuals
|
||||||
* and is licensed under the LGPL. For more information, see
|
* and is licensed under the LGPL. For more information, see
|
||||||
* <http://www.phpdoctrine.org>.
|
* <http://www.phpdoctrine.org>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An LL(k) parser for the context-free grammar of Doctrine Query Language.
|
* An LL(k) parser for the context-free grammar of Doctrine Query Language.
|
||||||
* Parses a DQL query, reports any errors in it, and generates the corresponding
|
* Parses a DQL query, reports any errors in it, and generates the corresponding
|
||||||
* SQL.
|
* SQL.
|
||||||
*
|
*
|
||||||
* @package Doctrine
|
* @package Doctrine
|
||||||
* @subpackage Query
|
* @subpackage Query
|
||||||
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
|
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
|
||||||
* @author Janne Vanhala <jpvanhal@cc.hut.fi>
|
* @author Janne Vanhala <jpvanhal@cc.hut.fi>
|
||||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||||
* @link http://www.phpdoctrine.org
|
* @link http://www.phpdoctrine.org
|
||||||
* @since 2.0
|
* @since 2.0
|
||||||
* @version $Revision$
|
* @version $Revision$
|
||||||
*/
|
*/
|
||||||
class Doctrine_Query_Parser
|
class Doctrine_Query_Parser
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* The minimum number of tokens read after last detected error before
|
* The minimum number of tokens read after last detected error before
|
||||||
* another error can be reported.
|
* another error can be reported.
|
||||||
*
|
*
|
||||||
* @var int
|
* @var int
|
||||||
*/
|
*/
|
||||||
const MIN_ERROR_DISTANCE = 2;
|
const MIN_ERROR_DISTANCE = 2;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Sql Builder object.
|
* The Sql Builder object.
|
||||||
*
|
*
|
||||||
* @var Doctrine_Query_SqlBuilder
|
* @var Doctrine_Query_SqlBuilder
|
||||||
*/
|
*/
|
||||||
protected $_sqlbuilder;
|
protected $_sqlbuilder;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A scanner object.
|
* DQL string.
|
||||||
*
|
*
|
||||||
* @var Doctrine_Query_Scanner
|
* @var string
|
||||||
*/
|
*/
|
||||||
protected $_scanner;
|
protected $_input;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Parser Result object.
|
* A scanner object.
|
||||||
*
|
*
|
||||||
* @var Doctrine_Query_ParserResult
|
* @var Doctrine_Query_Scanner
|
||||||
*/
|
*/
|
||||||
protected $_parserResult;
|
protected $_scanner;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Keyword symbol table
|
* The Parser Result object.
|
||||||
*
|
*
|
||||||
* @var Doctrine_Query_Token
|
* @var Doctrine_Query_ParserResult
|
||||||
*/
|
*/
|
||||||
protected $_keywordTable;
|
protected $_parserResult;
|
||||||
|
|
||||||
// Scanner Stuff
|
/**
|
||||||
|
* Keyword symbol table
|
||||||
/**
|
*
|
||||||
* @var array The next token in the query string.
|
* @var Doctrine_Query_Token
|
||||||
*/
|
*/
|
||||||
public $lookahead;
|
protected $_keywordTable;
|
||||||
|
|
||||||
/**
|
// Scanner Stuff
|
||||||
* @var array The last matched token.
|
|
||||||
*/
|
/**
|
||||||
public $token;
|
* @var array The next token in the query string.
|
||||||
|
*/
|
||||||
// End of Scanner Stuff
|
public $lookahead;
|
||||||
|
|
||||||
|
/**
|
||||||
// Error management stuff
|
* @var array The last matched token.
|
||||||
|
*/
|
||||||
/**
|
public $token;
|
||||||
* Array containing errors detected in the query string during parsing process.
|
|
||||||
*
|
// End of Scanner Stuff
|
||||||
* @var array
|
|
||||||
*/
|
|
||||||
protected $_errors;
|
// Error management stuff
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var int The number of tokens read since last error in the input string.
|
* Array containing errors detected in the query string during parsing process.
|
||||||
*/
|
*
|
||||||
protected $_errorDistance;
|
* @var array
|
||||||
|
*/
|
||||||
/**
|
protected $_errors;
|
||||||
* The EntityManager.
|
|
||||||
*
|
/**
|
||||||
* @var EnityManager
|
* @var int The number of tokens read since last error in the input string.
|
||||||
*/
|
*/
|
||||||
protected $_em;
|
protected $_errorDistance;
|
||||||
|
|
||||||
// End of Error management stuff
|
/**
|
||||||
|
* The EntityManager.
|
||||||
|
*
|
||||||
/**
|
* @var EnityManager
|
||||||
* Creates a new query parser object.
|
*/
|
||||||
*
|
protected $_em;
|
||||||
* @param string $dql DQL to be parsed.
|
|
||||||
* @param Doctrine_Connection $connection The connection to use
|
// End of Error management stuff
|
||||||
*/
|
|
||||||
public function __construct(Doctrine_Query $query)
|
|
||||||
{
|
/**
|
||||||
$this->_em = $query->getEntityManager();
|
* Creates a new query parser object.
|
||||||
$this->_scanner = new Doctrine_Query_Scanner($query->getDql());
|
*
|
||||||
$this->_sqlBuilder = Doctrine_Query_SqlBuilder::fromConnection($this->_em);
|
* @param string $dql DQL to be parsed.
|
||||||
$this->_keywordTable = new Doctrine_Query_Token();
|
* @param Doctrine_Connection $connection The connection to use
|
||||||
|
*/
|
||||||
$this->_parserResult = new Doctrine_Query_ParserResult(
|
public function __construct(Doctrine_Query $query)
|
||||||
'',
|
{
|
||||||
array( // queryComponent
|
$this->_em = $query->getEntityManager();
|
||||||
'dctrn' => array(
|
$this->_input = $query->getDql();
|
||||||
'metadata' => null,
|
$this->_scanner = new Doctrine_Query_Scanner($this->_input);
|
||||||
'parent' => null,
|
$this->_sqlBuilder = Doctrine_Query_SqlBuilder::fromConnection($this->_em);
|
||||||
'relation' => null,
|
$this->_keywordTable = new Doctrine_Query_Token();
|
||||||
'map' => null,
|
|
||||||
'scalar' => null,
|
$this->_parserResult = new Doctrine_Query_ParserResult(
|
||||||
),
|
'',
|
||||||
),
|
array( // queryComponent
|
||||||
array( // tableAliasMap
|
'dctrn' => array(
|
||||||
'dctrn' => 'dctrn',
|
'metadata' => null,
|
||||||
)
|
'parent' => null,
|
||||||
);
|
'relation' => null,
|
||||||
|
'map' => null,
|
||||||
$this->free(true);
|
'scalar' => null,
|
||||||
}
|
),
|
||||||
|
),
|
||||||
|
array( // tableAliasMap
|
||||||
/**
|
'dctrn' => 'dctrn',
|
||||||
* Attempts to match the given token with the current lookahead token.
|
)
|
||||||
*
|
);
|
||||||
* If they match, updates the lookahead token; otherwise raises a syntax
|
|
||||||
* error.
|
$this->_parserResult->setEntityManager($this->_em);
|
||||||
*
|
|
||||||
* @param int|string token type or value
|
$this->free(true);
|
||||||
* @return bool True, if tokens match; false otherwise.
|
}
|
||||||
*/
|
|
||||||
public function match($token)
|
|
||||||
{
|
/**
|
||||||
if (is_string($token)) {
|
* Attempts to match the given token with the current lookahead token.
|
||||||
$isMatch = ($this->lookahead['value'] === $token);
|
*
|
||||||
} else {
|
* If they match, updates the lookahead token; otherwise raises a syntax
|
||||||
$isMatch = ($this->lookahead['type'] === $token);
|
* error.
|
||||||
}
|
*
|
||||||
|
* @param int|string token type or value
|
||||||
if ( ! $isMatch) {
|
* @return bool True, if tokens match; false otherwise.
|
||||||
// No definition for value checking.
|
*/
|
||||||
$this->syntaxError($this->_keywordTable->getLiteral($token));
|
public function match($token)
|
||||||
}
|
{
|
||||||
|
if (is_string($token)) {
|
||||||
$this->next();
|
$isMatch = ($this->lookahead['value'] === $token);
|
||||||
return true;
|
} else {
|
||||||
}
|
$isMatch = ($this->lookahead['type'] === $token);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
if ( ! $isMatch) {
|
||||||
* Moves the parser scanner to next token
|
// No definition for value checking.
|
||||||
*
|
$this->syntaxError($this->_keywordTable->getLiteral($token));
|
||||||
* @return void
|
}
|
||||||
*/
|
|
||||||
public function next()
|
$this->next();
|
||||||
{
|
return true;
|
||||||
$this->token = $this->lookahead;
|
}
|
||||||
$this->lookahead = $this->_scanner->next();
|
|
||||||
$this->_errorDistance++;
|
|
||||||
}
|
/**
|
||||||
|
* Moves the parser scanner to next token
|
||||||
|
*
|
||||||
public function isA($value, $token)
|
* @return void
|
||||||
{
|
*/
|
||||||
return $this->_scanner->isA($value, $token);
|
public function next()
|
||||||
}
|
{
|
||||||
|
$this->token = $this->lookahead;
|
||||||
|
$this->lookahead = $this->_scanner->next();
|
||||||
/**
|
$this->_errorDistance++;
|
||||||
* Free this parser enabling it to be reused
|
}
|
||||||
*
|
|
||||||
* @param boolean $deep Whether to clean peek and reset errors
|
|
||||||
* @param integer $position Position to reset
|
public function isA($value, $token)
|
||||||
* @return void
|
{
|
||||||
*/
|
return $this->_scanner->isA($value, $token);
|
||||||
public function free($deep = false, $position = 0)
|
}
|
||||||
{
|
|
||||||
// WARNING! Use this method with care. It resets the scanner!
|
|
||||||
$this->_scanner->resetPosition($position);
|
/**
|
||||||
|
* Free this parser enabling it to be reused
|
||||||
// Deep = true cleans peek and also any previously defined errors
|
*
|
||||||
if ($deep) {
|
* @param boolean $deep Whether to clean peek and reset errors
|
||||||
$this->_scanner->resetPeek();
|
* @param integer $position Position to reset
|
||||||
$this->_errors = array();
|
* @return void
|
||||||
}
|
*/
|
||||||
|
public function free($deep = false, $position = 0)
|
||||||
$this->token = null;
|
{
|
||||||
$this->lookahead = null;
|
// WARNING! Use this method with care. It resets the scanner!
|
||||||
|
$this->_scanner->resetPosition($position);
|
||||||
$this->_errorDistance = self::MIN_ERROR_DISTANCE;
|
|
||||||
}
|
// Deep = true cleans peek and also any previously defined errors
|
||||||
|
if ($deep) {
|
||||||
|
$this->_scanner->resetPeek();
|
||||||
/**
|
$this->_errors = array();
|
||||||
* Parses a query string.
|
}
|
||||||
*/
|
|
||||||
public function parse()
|
$this->token = null;
|
||||||
{
|
$this->lookahead = null;
|
||||||
$this->lookahead = $this->_scanner->next();
|
|
||||||
|
$this->_errorDistance = self::MIN_ERROR_DISTANCE;
|
||||||
// Building the Abstract Syntax Tree
|
}
|
||||||
// We have to double the call of QueryLanguage to allow it to work correctly... =\
|
|
||||||
$AST = new Doctrine_Query_Production_QueryLanguage($this);
|
|
||||||
$AST = $AST->AST('QueryLanguage', Doctrine_Query_ProductionParamHolder::create());
|
/**
|
||||||
|
* Parses a query string.
|
||||||
// Check for end of string
|
*/
|
||||||
if ($this->lookahead !== null) {
|
public function parse()
|
||||||
$this->syntaxError('end of string');
|
{
|
||||||
}
|
$this->lookahead = $this->_scanner->next();
|
||||||
|
|
||||||
// Check for semantical errors
|
// Building the Abstract Syntax Tree
|
||||||
if (count($this->_errors) > 0) {
|
// We have to double the call of QueryLanguage to allow it to work correctly... =\
|
||||||
throw new Doctrine_Query_Parser_Exception(implode("\r\n", $this->_errors));
|
$DQL = new Doctrine_Query_Parser_QueryLanguage($this);
|
||||||
}
|
$AST = $DQL->parse('QueryLanguage', Doctrine_Query_ParserParamHolder::create());
|
||||||
|
|
||||||
// Assign the executor in parser result
|
// Check for end of string
|
||||||
$this->_parserResult->setSqlExecutor(Doctrine_Query_SqlExecutor_Abstract::create($AST));
|
if ($this->lookahead !== null) {
|
||||||
|
$this->syntaxError('end of string');
|
||||||
return $this->_parserResult;
|
}
|
||||||
}
|
|
||||||
|
// Check for semantical errors
|
||||||
|
if (count($this->_errors) > 0) {
|
||||||
/**
|
throw new Doctrine_Query_Parser_Exception(implode("\r\n", $this->_errors));
|
||||||
* Retrieves the assocated Doctrine_Query_SqlBuilder to this object.
|
}
|
||||||
*
|
|
||||||
* @return Doctrine_Query_SqlBuilder
|
// Assign the executor in parser result
|
||||||
*/
|
$this->_parserResult->setSqlExecutor(Doctrine_Query_SqlExecutor_Abstract::create($AST));
|
||||||
public function getSqlBuilder()
|
|
||||||
{
|
return $this->_parserResult;
|
||||||
return $this->_sqlBuilder;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
/**
|
||||||
/**
|
* Retrieves the assocated Doctrine_Query_SqlBuilder to this object.
|
||||||
* Returns the scanner object associated with this object.
|
*
|
||||||
*
|
* @return Doctrine_Query_SqlBuilder
|
||||||
* @return Doctrine_Query_Scanner
|
*/
|
||||||
*/
|
public function getSqlBuilder()
|
||||||
public function getScanner()
|
{
|
||||||
{
|
return $this->_sqlBuilder;
|
||||||
return $this->_scanner;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
/**
|
||||||
/**
|
* Returns the scanner object associated with this object.
|
||||||
* Returns the parser result associated with this object.
|
*
|
||||||
*
|
* @return Doctrine_Query_Scanner
|
||||||
* @return Doctrine_Query_ParserResult
|
*/
|
||||||
*/
|
public function getScanner()
|
||||||
public function getParserResult()
|
{
|
||||||
{
|
return $this->_scanner;
|
||||||
return $this->_parserResult;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
/**
|
||||||
/**
|
* Returns the parser result associated with this object.
|
||||||
* Generates a new syntax error.
|
*
|
||||||
*
|
* @return Doctrine_Query_ParserResult
|
||||||
* @param string $expected Optional expected string.
|
*/
|
||||||
* @param array $token Optional token.
|
public function getParserResult()
|
||||||
*/
|
{
|
||||||
public function syntaxError($expected = '', $token = null)
|
return $this->_parserResult;
|
||||||
{
|
}
|
||||||
if ($token === null) {
|
|
||||||
$token = $this->lookahead;
|
|
||||||
}
|
/**
|
||||||
|
* Generates a new syntax error.
|
||||||
// Formatting message
|
*
|
||||||
$message = 'line 0, col ' . (isset($token['position']) ? $token['position'] : '-1') . ': Error: ';
|
* @param string $expected Optional expected string.
|
||||||
|
* @param array $token Optional token.
|
||||||
if ($expected !== '') {
|
*/
|
||||||
$message .= "Expected '$expected', got ";
|
public function syntaxError($expected = '', $token = null)
|
||||||
} else {
|
{
|
||||||
$message .= 'Unexpected ';
|
if ($token === null) {
|
||||||
}
|
$token = $this->lookahead;
|
||||||
|
}
|
||||||
if ($this->lookahead === null) {
|
|
||||||
$message .= 'end of string.';
|
// Formatting message
|
||||||
} else {
|
$message = 'line 0, col ' . (isset($token['position']) ? $token['position'] : '-1') . ': Error: ';
|
||||||
$message .= "'{$this->lookahead['value']}'";
|
|
||||||
}
|
if ($expected !== '') {
|
||||||
|
$message .= "Expected '$expected', got ";
|
||||||
throw new Doctrine_Query_Parser_Exception($message);
|
} else {
|
||||||
}
|
$message .= 'Unexpected ';
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
if ($this->lookahead === null) {
|
||||||
* Generates a new semantical error.
|
$message .= 'end of string.';
|
||||||
*
|
} else {
|
||||||
* @param string $message Optional message.
|
$message .= "'{$this->lookahead['value']}'";
|
||||||
* @param array $token Optional token.
|
}
|
||||||
*/
|
|
||||||
public function semanticalError($message = '', $token = null)
|
throw new Doctrine_Query_Parser_Exception($message);
|
||||||
{
|
}
|
||||||
$this->_semanticalErrorCount++;
|
|
||||||
|
|
||||||
if ($token === null) {
|
/**
|
||||||
$token = $this->token;
|
* Generates a new semantical error.
|
||||||
}
|
*
|
||||||
|
* @param string $message Optional message.
|
||||||
$this->_logError('Warning: ' . $message, $token);
|
* @param array $token Optional token.
|
||||||
}
|
*/
|
||||||
|
public function semanticalError($message = '', $token = null)
|
||||||
|
{
|
||||||
/**
|
$this->_semanticalErrorCount++;
|
||||||
* Logs new error entry.
|
|
||||||
*
|
if ($token === null) {
|
||||||
* @param string $message Message to log.
|
$token = $this->token;
|
||||||
* @param array $token Token that it was processing.
|
}
|
||||||
*/
|
|
||||||
protected function _logError($message = '', $token)
|
$this->_logError('Warning: ' . $message, $token);
|
||||||
{
|
}
|
||||||
if ($this->_errorDistance >= self::MIN_ERROR_DISTANCE) {
|
|
||||||
$message = 'line 0, col ' . $token['position'] . ': ' . $message;
|
|
||||||
$this->_errors[] = $message;
|
/**
|
||||||
}
|
* Logs new error entry.
|
||||||
|
*
|
||||||
$this->_errorDistance = 0;
|
* @param string $message Message to log.
|
||||||
}
|
* @param array $token Token that it was processing.
|
||||||
|
*/
|
||||||
/**
|
protected function _logError($message = '', $token)
|
||||||
* Gets the EntityManager used by the parser.
|
{
|
||||||
*
|
if ($this->_errorDistance >= self::MIN_ERROR_DISTANCE) {
|
||||||
* @return EntityManager
|
$message = 'line 0, col ' . $token['position'] . ': ' . $message;
|
||||||
*/
|
$this->_errors[] = $message;
|
||||||
public function getEntityManager()
|
}
|
||||||
{
|
|
||||||
return $this->_em;
|
$this->_errorDistance = 0;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
/**
|
||||||
|
* Gets the EntityManager used by the parser.
|
||||||
|
*
|
||||||
|
* @return EntityManager
|
||||||
|
*/
|
||||||
|
public function getEntityManager()
|
||||||
|
{
|
||||||
|
return $this->_em;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the piece of DQL string given the token position
|
||||||
|
*
|
||||||
|
* @param array $token Token that it was processing.
|
||||||
|
* @return string Piece of DQL string.
|
||||||
|
*/
|
||||||
|
public function getQueryPiece($token, $previousChars = 10, $nextChars = 10)
|
||||||
|
{
|
||||||
|
$start = max(0, $token['position'] - $previousChars);
|
||||||
|
$end = max($token['position'] + $nextChars, strlen($this->_input));
|
||||||
|
|
||||||
|
return substr($this->_input, $start, $end);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
76
lib/Doctrine/Query/Parser/AbstractSchemaName.php
Normal file
76
lib/Doctrine/Query/Parser/AbstractSchemaName.php
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
<?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>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* AbstractSchemaName ::= identifier
|
||||||
|
*
|
||||||
|
* @package Doctrine
|
||||||
|
* @subpackage Query
|
||||||
|
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
|
||||||
|
* @author Janne Vanhala <jpvanhal@cc.hut.fi>
|
||||||
|
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||||
|
* @link http://www.phpdoctrine.org
|
||||||
|
* @since 2.0
|
||||||
|
* @version $Revision$
|
||||||
|
*/
|
||||||
|
class Doctrine_Query_Parser_AbstractSchemaName extends Doctrine_Query_ParserRule
|
||||||
|
{
|
||||||
|
protected $_AST = null;
|
||||||
|
|
||||||
|
|
||||||
|
public function syntax($paramHolder)
|
||||||
|
{
|
||||||
|
// AbstractSchemaName ::= identifier
|
||||||
|
$this->_AST = $this->AST('AbstractSchemaName');
|
||||||
|
|
||||||
|
$this->_parser->match(Doctrine_Query_Token::T_IDENTIFIER);
|
||||||
|
$this->_AST->setComponentName($this->_parser->token['value']);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function semantical($paramHolder)
|
||||||
|
{
|
||||||
|
$componentName = $this->_AST->getComponentName();
|
||||||
|
|
||||||
|
// Check if we are dealing with a real Doctrine_Entity or not
|
||||||
|
if ( ! $this->_isDoctrineEntity($componentName)) {
|
||||||
|
$this->_parser->semanticalError(
|
||||||
|
"Defined entity '" . $companyName . "' is not a valid Doctrine_Entity."
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return AST node
|
||||||
|
return $this->_AST;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected function _isDoctrineEntity($componentName)
|
||||||
|
{
|
||||||
|
if (class_exists($componentName)) {
|
||||||
|
$reflectionClass = new ReflectionClass($componentName);
|
||||||
|
$dctrnEntityReflectionClass = new ReflectionClass('Doctrine_Entity');
|
||||||
|
|
||||||
|
return $reflectionClass->isSubclassOf($dctrnEntityReflectionClass);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
66
lib/Doctrine/Query/Parser/AliasIdentificationVariable.php
Normal file
66
lib/Doctrine/Query/Parser/AliasIdentificationVariable.php
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
<?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>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* AliasIdentificationVariable = identifier
|
||||||
|
*
|
||||||
|
* @package Doctrine
|
||||||
|
* @subpackage Query
|
||||||
|
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
|
||||||
|
* @author Janne Vanhala <jpvanhal@cc.hut.fi>
|
||||||
|
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||||
|
* @link http://www.phpdoctrine.org
|
||||||
|
* @since 2.0
|
||||||
|
* @version $Revision$
|
||||||
|
*/
|
||||||
|
class Doctrine_Query_Parser_AliasIdentificationVariable extends Doctrine_Query_ParserRule
|
||||||
|
{
|
||||||
|
protected $_AST = null;
|
||||||
|
|
||||||
|
|
||||||
|
public function syntax($paramHolder)
|
||||||
|
{
|
||||||
|
// AliasIdentificationVariable = identifier
|
||||||
|
$this->_AST = $this->AST('AliasIdentificationVariable');
|
||||||
|
|
||||||
|
$this->_parser->match(Doctrine_Query_Token::T_IDENTIFIER);
|
||||||
|
$this->_AST->setComponentAlias($this->_parser->token['value']);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function semantical($paramHolder)
|
||||||
|
{
|
||||||
|
$parserResult = $this->_parser->getParserResult();
|
||||||
|
|
||||||
|
if ($parserResult->hasQueryComponent($this->_AST->getComponentAlias())) {
|
||||||
|
// We should throw semantical error if there's already a component for this alias
|
||||||
|
$queryComponent = $parserResult->getQueryComponent($this->_AST->getComponentAlias());
|
||||||
|
$componentName = $queryComponent['metadata']->getClassName();
|
||||||
|
|
||||||
|
$message = "Cannot re-declare component alias '" . $this->_AST->getComponentAlias() . "'. "
|
||||||
|
. "It was already declared for component '" . $componentName . "'.";
|
||||||
|
|
||||||
|
$this->_parser->semanticalError($message);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->_AST;
|
||||||
|
}
|
||||||
|
}
|
53
lib/Doctrine/Query/Parser/DeleteStatement.php
Normal file
53
lib/Doctrine/Query/Parser/DeleteStatement.php
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
<?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>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DeleteStatement ::= DeleteClause [WhereClause]
|
||||||
|
*
|
||||||
|
* @package Doctrine
|
||||||
|
* @subpackage Query
|
||||||
|
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
|
||||||
|
* @author Janne Vanhala <jpvanhal@cc.hut.fi>
|
||||||
|
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||||
|
* @link http://www.phpdoctrine.org
|
||||||
|
* @since 2.0
|
||||||
|
* @version $Revision$
|
||||||
|
*/
|
||||||
|
class Doctrine_Query_Parser_DeleteStatement extends Doctrine_Query_Parser
|
||||||
|
{
|
||||||
|
protected $_AST = null;
|
||||||
|
|
||||||
|
|
||||||
|
public function syntax($paramHolder)
|
||||||
|
{
|
||||||
|
// DeleteStatement ::= DeleteClause [WhereClause]
|
||||||
|
$this->_AST = $this->AST('DeleteStatement');
|
||||||
|
|
||||||
|
$this->_AST->setDeleteClause($this->parse('DeleteClause', $paramHolder));
|
||||||
|
|
||||||
|
if ($this->_isNextToken(Doctrine_Query_Token::T_WHERE)) {
|
||||||
|
$this->_AST->setWhereClause($this->parse('WhereClause', $paramHolder));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return AST node
|
||||||
|
return $this->_AST;
|
||||||
|
}
|
||||||
|
}
|
61
lib/Doctrine/Query/Parser/FieldIdentificationVariable.php
Normal file
61
lib/Doctrine/Query/Parser/FieldIdentificationVariable.php
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
<?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>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* FieldIdentificationVariable ::= identifier
|
||||||
|
*
|
||||||
|
* @package Doctrine
|
||||||
|
* @subpackage Query
|
||||||
|
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
|
||||||
|
* @author Janne Vanhala <jpvanhal@cc.hut.fi>
|
||||||
|
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||||
|
* @link http://www.phpdoctrine.org
|
||||||
|
* @since 2.0
|
||||||
|
* @version $Revision$
|
||||||
|
*/
|
||||||
|
class Doctrine_Query_Parser_FieldIdentificationVariable extends Doctrine_Query_ParserRule
|
||||||
|
{
|
||||||
|
protected $_AST = null;
|
||||||
|
|
||||||
|
|
||||||
|
public function syntax($paramHolder)
|
||||||
|
{
|
||||||
|
// FieldIdentificationVariable ::= identifier
|
||||||
|
$this->_AST = $this->AST('FieldIdentificationVariable');
|
||||||
|
|
||||||
|
$this->_parser->match(Doctrine_Query_Token::T_IDENTIFIER);
|
||||||
|
$this->_AST->setFieldName($this->_parser->token['value']);
|
||||||
|
|
||||||
|
// Return AST node
|
||||||
|
return $this->_AST;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function semantical($paramHolder)
|
||||||
|
{
|
||||||
|
$parserResult = $this->_parser->getParserResult();
|
||||||
|
|
||||||
|
// [TODO] Check for field existance somewhere
|
||||||
|
|
||||||
|
// Return AST node
|
||||||
|
return $this->_AST;
|
||||||
|
}
|
||||||
|
}
|
61
lib/Doctrine/Query/Parser/FromClause.php
Normal file
61
lib/Doctrine/Query/Parser/FromClause.php
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
<?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>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* FromClause ::= "FROM" IdentificationVariableDeclaration {"," IdentificationVariableDeclaration}
|
||||||
|
*
|
||||||
|
* @package Doctrine
|
||||||
|
* @subpackage Query
|
||||||
|
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
|
||||||
|
* @author Janne Vanhala <jpvanhal@cc.hut.fi>
|
||||||
|
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||||
|
* @link http://www.phpdoctrine.org
|
||||||
|
* @since 1.0
|
||||||
|
* @version $Revision$
|
||||||
|
*/
|
||||||
|
class Doctrine_Query_Parser_FromClause extends Doctrine_Query_ParserRule
|
||||||
|
{
|
||||||
|
protected $_AST = null;
|
||||||
|
|
||||||
|
|
||||||
|
public function syntax($paramHolder)
|
||||||
|
{
|
||||||
|
// FromClause ::= "FROM" IdentificationVariableDeclaration {"," IdentificationVariableDeclaration}
|
||||||
|
$this->_AST = $this->AST('FromClause');
|
||||||
|
|
||||||
|
$this->_parser->match(Doctrine_Query_Token::T_FROM);
|
||||||
|
|
||||||
|
$this->_AST->addIdentificationVariableDeclaration(
|
||||||
|
$this->parse('IdentificationVariableDeclaration', $paramHolder)
|
||||||
|
);
|
||||||
|
|
||||||
|
while ($this->_isNextToken(',')) {
|
||||||
|
$this->_parser->match(',');
|
||||||
|
|
||||||
|
$this->_AST->addIdentificationVariableDeclaration(
|
||||||
|
$this->parse('IdentificationVariableDeclaration', $paramHolder)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return AST node
|
||||||
|
return $this->_AST;
|
||||||
|
}
|
||||||
|
}
|
64
lib/Doctrine/Query/Parser/IdentificationVariable.php
Normal file
64
lib/Doctrine/Query/Parser/IdentificationVariable.php
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
<?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>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* IdentificationVariable ::= identifier
|
||||||
|
*
|
||||||
|
* @package Doctrine
|
||||||
|
* @subpackage Query
|
||||||
|
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
|
||||||
|
* @author Janne Vanhala <jpvanhal@cc.hut.fi>
|
||||||
|
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||||
|
* @link http://www.phpdoctrine.org
|
||||||
|
* @since 2.0
|
||||||
|
* @version $Revision$
|
||||||
|
*/
|
||||||
|
class Doctrine_Query_Parser_IdentificationVariable extends Doctrine_Query_ParserRule
|
||||||
|
{
|
||||||
|
protected $_AST = null;
|
||||||
|
|
||||||
|
|
||||||
|
public function syntax($paramHolder)
|
||||||
|
{
|
||||||
|
// IdentificationVariable ::= identifier
|
||||||
|
$this->_AST = $this->AST('IdentificationVariable');
|
||||||
|
|
||||||
|
$this->_parser->match(Doctrine_Query_Token::T_IDENTIFIER);
|
||||||
|
$this->_AST->setComponentAlias($this->_parser->token['value']);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function semantical($paramHolder)
|
||||||
|
{
|
||||||
|
$parserResult = $this->_parser->getParserResult();
|
||||||
|
|
||||||
|
if ( ! $parserResult->hasQueryComponent($this->_AST->getComponentAlias())) {
|
||||||
|
// We should throw semantical error if we cannot find the component alias
|
||||||
|
$message = "No entity related to declared alias '" . $this->_AST->getComponentAlias()
|
||||||
|
. "' near '" . $this->_parser->getQueryPiece($this->_parser->token) . "'.";
|
||||||
|
|
||||||
|
$this->_parser->semanticalError($message);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return AST node
|
||||||
|
return $this->_AST;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,68 @@
|
|||||||
|
<?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>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* IdentificationVariableDeclaration ::= RangeVariableDeclaration [IndexBy] {JoinVariableDeclaration}*
|
||||||
|
*
|
||||||
|
* @package Doctrine
|
||||||
|
* @subpackage Query
|
||||||
|
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
|
||||||
|
* @author Janne Vanhala <jpvanhal@cc.hut.fi>
|
||||||
|
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||||
|
* @link http://www.phpdoctrine.org
|
||||||
|
* @since 1.0
|
||||||
|
* @version $Revision$
|
||||||
|
*/
|
||||||
|
class Doctrine_Query_Parser_IdentificationVariableDeclaration extends Doctrine_Query_ParserRule
|
||||||
|
{
|
||||||
|
protected $_AST = null;
|
||||||
|
|
||||||
|
|
||||||
|
public function syntax($paramHolder)
|
||||||
|
{
|
||||||
|
// IdentificationVariableDeclaration ::= RangeVariableDeclaration [IndexBy] {JoinVariableDeclaration}*
|
||||||
|
$this->_AST = $this->AST('IdentificationVariableDeclaration');
|
||||||
|
|
||||||
|
$this->_AST->setRangeVariableDeclaration($this->parse('RangeVariableDeclaration', $paramHolder));
|
||||||
|
|
||||||
|
if ($this->_isNextToken(Doctrine_Query_Token::T_INDEX)) {
|
||||||
|
$paramHolder->set(
|
||||||
|
'componentAlias',
|
||||||
|
$this->_AST->getRangeVariableDeclaration()->getAliasIdentificationVariable()->getComponentAlias()
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->_AST->setIndexBy($this->parse('IndexBy', $paramHolder));
|
||||||
|
|
||||||
|
$paramHolder->remove('componentAlias');
|
||||||
|
}
|
||||||
|
|
||||||
|
while (
|
||||||
|
$this->_isNextToken(Doctrine_Query_Token::T_LEFT) ||
|
||||||
|
$this->_isNextToken(Doctrine_Query_Token::T_INNER) ||
|
||||||
|
$this->_isNextToken(Doctrine_Query_Token::T_JOIN)
|
||||||
|
) {
|
||||||
|
$this->_AST->addJoinVariableDeclaration($this->parse('JoinVariableDeclaration', $paramHolder));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return AST node
|
||||||
|
return $this->_AST;
|
||||||
|
}
|
||||||
|
}
|
106
lib/Doctrine/Query/Parser/IndexBy.php
Normal file
106
lib/Doctrine/Query/Parser/IndexBy.php
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
<?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>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* IndexBy ::= "INDEX" "BY" SimpleStateFieldPathExpression
|
||||||
|
*
|
||||||
|
* @package Doctrine
|
||||||
|
* @subpackage Query
|
||||||
|
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
|
||||||
|
* @author Janne Vanhala <jpvanhal@cc.hut.fi>
|
||||||
|
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||||
|
* @link http://www.phpdoctrine.org
|
||||||
|
* @since 2.0
|
||||||
|
* @version $Revision$
|
||||||
|
*/
|
||||||
|
class Doctrine_Query_Parser_IndexBy extends Doctrine_Query_ParserRule
|
||||||
|
{
|
||||||
|
protected $_AST = null;
|
||||||
|
|
||||||
|
|
||||||
|
public function syntax($paramHolder)
|
||||||
|
{
|
||||||
|
// IndexBy ::= "INDEX" "BY" SimpleStateFieldPathExpression
|
||||||
|
$this->_AST = $this->AST('IndexBy');
|
||||||
|
|
||||||
|
$this->_parser->match(Doctrine_Query_Token::T_INDEX);
|
||||||
|
$this->_parser->match(Doctrine_Query_Token::T_BY);
|
||||||
|
|
||||||
|
$this->_AST->setSimpleStateFieldPathExpression($this->parse('SimpleStateFieldPathExpression', $paramHolder));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function semantical($paramHolder)
|
||||||
|
{
|
||||||
|
$parserResult = $this->_parser->getParserResult();
|
||||||
|
$componentAlias = $this->_AST->getSimpleStateFieldPathExpression()
|
||||||
|
->getIdentificationVariable()->getComponentAlias();
|
||||||
|
$componentFieldName = $this->_AST->getSimpleStateFieldPathExpression()
|
||||||
|
->getSimpleStateField()->getFieldName();
|
||||||
|
|
||||||
|
// Check if we have same component being used in index
|
||||||
|
if ($componentAlias !== $paramHolder->get('componentAlias')) {
|
||||||
|
$message = "Invalid alising. Cannot index by '" . $paramHolder->get('componentAlias')
|
||||||
|
. "' inside '" . $componentAlias . "' scope.";
|
||||||
|
|
||||||
|
$this->_parser->semanticalError($message);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Retrieving required information
|
||||||
|
try {
|
||||||
|
$queryComponent = $parserResult->getQueryComponent($componentAlias);
|
||||||
|
$classMetadata = $queryComponent['metadata'];
|
||||||
|
} catch (Doctrine_Exception $e) {
|
||||||
|
$this->_parser->semanticalError($e->getMessage());
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The INDEXBY field must be either the (primary && not part of composite pk) || (unique && notnull)
|
||||||
|
$columnMapping = $classMetadata->getFieldMapping($componentFieldName);
|
||||||
|
|
||||||
|
if (
|
||||||
|
! $classMetadata->isIdentifier($componentFieldName) &&
|
||||||
|
! $classMetadata->isUniqueField($componentFieldName) &&
|
||||||
|
! $classMetadata->isNotNull($componentFieldName)
|
||||||
|
) {
|
||||||
|
$this->_parser->semanticalError(
|
||||||
|
"Field '" . $componentFieldName . "' of component '" . $classMetadata->getClassName() .
|
||||||
|
"' must be unique and notnull to be used as index.",
|
||||||
|
$this->_parser->token
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($classMetadata->isIdentifier($componentFieldName) && $classMetadata->isIdentifierComposite()) {
|
||||||
|
$this->_parser->semanticalError(
|
||||||
|
"Field '" . $componentFieldName . "' of component '" . $classMetadata->getClassName() .
|
||||||
|
"' must be primary and not part of a composite primary key to be used as index.",
|
||||||
|
$this->_parser->token
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
$queryComponent['map'] = $componentFieldName;
|
||||||
|
$parserResult->setQueryComponent($componentAlias, $queryComponent);
|
||||||
|
|
||||||
|
// Return AST node
|
||||||
|
return $this->_AST;
|
||||||
|
}
|
||||||
|
}
|
57
lib/Doctrine/Query/Parser/QueryLanguage.php
Normal file
57
lib/Doctrine/Query/Parser/QueryLanguage.php
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
<?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>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* QueryLanguage ::= SelectStatement | UpdateStatement | DeleteStatement
|
||||||
|
*
|
||||||
|
* @package Doctrine
|
||||||
|
* @subpackage Query
|
||||||
|
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
|
||||||
|
* @author Janne Vanhala <jpvanhal@cc.hut.fi>
|
||||||
|
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||||
|
* @link http://www.phpdoctrine.org
|
||||||
|
* @since 2.0
|
||||||
|
* @version $Revision$
|
||||||
|
*/
|
||||||
|
class Doctrine_Query_Parser_QueryLanguage extends Doctrine_Query_ParserRule
|
||||||
|
{
|
||||||
|
public function syntax($paramHolder)
|
||||||
|
{
|
||||||
|
// QueryLanguage ::= SelectStatement | UpdateStatement | DeleteStatement
|
||||||
|
switch ($this->_parser->lookahead['type']) {
|
||||||
|
case Doctrine_Query_Token::T_SELECT:
|
||||||
|
return $this->parse('SelectStatement', $paramHolder);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Doctrine_Query_Token::T_UPDATE:
|
||||||
|
return $this->parse('UpdateStatement', $paramHolder);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Doctrine_Query_Token::T_DELETE:
|
||||||
|
return $this->parse('DeleteStatement', $paramHolder);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
$this->_parser->syntaxError('SELECT, UPDATE or DELETE');
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
98
lib/Doctrine/Query/Parser/RangeVariableDeclaration.php
Normal file
98
lib/Doctrine/Query/Parser/RangeVariableDeclaration.php
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
<?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>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* RangeVariableDeclaration ::= AbstractSchemaName ["AS"] AliasIdentificationVariable
|
||||||
|
*
|
||||||
|
* @package Doctrine
|
||||||
|
* @subpackage Query
|
||||||
|
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
|
||||||
|
* @author Janne Vanhala <jpvanhal@cc.hut.fi>
|
||||||
|
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||||
|
* @link http://www.phpdoctrine.org
|
||||||
|
* @since 1.0
|
||||||
|
* @version $Revision$
|
||||||
|
*/
|
||||||
|
class Doctrine_Query_Parser_RangeVariableDeclaration extends Doctrine_Query_ParserRule
|
||||||
|
{
|
||||||
|
protected $_AST = null;
|
||||||
|
|
||||||
|
|
||||||
|
public function syntax($paramHolder)
|
||||||
|
{
|
||||||
|
// RangeVariableDeclaration ::= AbstractSchemaName ["AS"] AliasIdentificationVariable
|
||||||
|
$this->_AST = $this->AST('RangeVariableDeclaration');
|
||||||
|
|
||||||
|
$this->_AST->setAbstractSchemaName($this->parse('AbstractSchemaName', $paramHolder));
|
||||||
|
|
||||||
|
if ($this->_isNextToken(Doctrine_Query_Token::T_AS)) {
|
||||||
|
$this->_parser->match(Doctrine_Query_Token::T_AS);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->_isNextToken(Doctrine_Query_Token::T_IDENTIFIER)) {
|
||||||
|
$this->_AST->setAliasIdentificationVariable($this->parse('AliasIdentificationVariable', $paramHolder));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function semantical($paramHolder)
|
||||||
|
{
|
||||||
|
$parserResult = $this->_parser->getParserResult();
|
||||||
|
$componentName = $this->_AST->getAbstractSchemaName()->getComponentName();
|
||||||
|
$componentAlias = $this->_AST->getAliasIdentificationVariable()->getComponentAlias();
|
||||||
|
|
||||||
|
// Check if we already have a component defined without an alias
|
||||||
|
if ($componentAlias === null && $parserResult->hasQueryComponent($componentName)) {
|
||||||
|
$this->_parser->semanticalError(
|
||||||
|
"Cannot re-declare component '{$componentName}'. Please assign an alias to it."
|
||||||
|
);
|
||||||
|
// Define new queryComponent since it does not exist yet
|
||||||
|
} else {
|
||||||
|
// Retrieving ClassMetadata and Mapper
|
||||||
|
try {
|
||||||
|
$classMetadata = $this->_em->getClassMetadata($componentName);
|
||||||
|
|
||||||
|
// Building queryComponent
|
||||||
|
$queryComponent = array(
|
||||||
|
'metadata' => $classMetadata,
|
||||||
|
'parent' => null,
|
||||||
|
'relation' => null,
|
||||||
|
'map' => null,
|
||||||
|
'scalar' => null,
|
||||||
|
);
|
||||||
|
} catch (Doctrine_Exception $e) {
|
||||||
|
$this->_parser->semanticalError($e->getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Inspect for possible non-aliasing
|
||||||
|
if ($componentAlias === null) {
|
||||||
|
$componentAlias = $componentName;
|
||||||
|
}
|
||||||
|
|
||||||
|
$tableAlias = $parserResult->generateTableAlias($classMetadata->getClassName());
|
||||||
|
$parserResult->setQueryComponent($componentAlias, $queryComponent);
|
||||||
|
$parserResult->setTableAlias($tableAlias, $componentAlias);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return AST node
|
||||||
|
return $this->_AST;
|
||||||
|
}
|
||||||
|
}
|
76
lib/Doctrine/Query/Parser/SelectClause.php
Normal file
76
lib/Doctrine/Query/Parser/SelectClause.php
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
<?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>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SelectClause ::= "SELECT" ["DISTINCT"] SelectExpression {"," SelectExpression}
|
||||||
|
*
|
||||||
|
* @package Doctrine
|
||||||
|
* @subpackage Query
|
||||||
|
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
|
||||||
|
* @author Janne Vanhala <jpvanhal@cc.hut.fi>
|
||||||
|
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||||
|
* @link http://www.phpdoctrine.org
|
||||||
|
* @since 2.0
|
||||||
|
* @version $Revision$
|
||||||
|
*/
|
||||||
|
class Doctrine_Query_Parser_SelectClause extends Doctrine_Query_ParserRule
|
||||||
|
{
|
||||||
|
protected $_AST = null;
|
||||||
|
|
||||||
|
protected $_selectExpressions = array();
|
||||||
|
|
||||||
|
|
||||||
|
public function syntax($paramHolder)
|
||||||
|
{
|
||||||
|
// SelectClause ::= "SELECT" ["DISTINCT"] SelectExpression {"," SelectExpression}
|
||||||
|
$this->_AST = $this->AST('SelectClause');
|
||||||
|
|
||||||
|
$this->_parser->match(Doctrine_Query_Token::T_SELECT);
|
||||||
|
|
||||||
|
// Inspecting if we are in a DISTINCT query
|
||||||
|
if ($this->_isNextToken(Doctrine_Query_Token::T_DISTINCT)) {
|
||||||
|
$this->_parser->match(Doctrine_Query_Token::T_DISTINCT);
|
||||||
|
|
||||||
|
$this->_AST->setIsDistinct(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process SelectExpressions (1..N)
|
||||||
|
$this->_selectExpressions[] = $this->parse('SelectExpression', $paramHolder);
|
||||||
|
|
||||||
|
while ($this->_isNextToken(',')) {
|
||||||
|
$this->_parser->match(',');
|
||||||
|
|
||||||
|
$this->_selectExpressions[] = $this->parse('SelectExpression', $paramHolder);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function semantical($paramHolder)
|
||||||
|
{
|
||||||
|
// We need to validate each SelectExpression
|
||||||
|
for ($i = 0, $l = count($this->_selectExpressions); $i < $l; $i++) {
|
||||||
|
$this->_AST->addSelectExpression($this->_selectExpressions[$i]->semantical($paramHolder));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return AST node
|
||||||
|
return $this->_AST;
|
||||||
|
}
|
||||||
|
}
|
82
lib/Doctrine/Query/Parser/SelectExpression.php
Normal file
82
lib/Doctrine/Query/Parser/SelectExpression.php
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
<?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>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SelectExpression ::= IdentificationVariable ["." "*"] |
|
||||||
|
* (StateFieldPathExpression | AggregateExpression | "(" Subselect ")" )
|
||||||
|
* [["AS"] FieldIdentificationVariable]
|
||||||
|
*
|
||||||
|
* @package Doctrine
|
||||||
|
* @subpackage Query
|
||||||
|
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
|
||||||
|
* @author Janne Vanhala <jpvanhal@cc.hut.fi>
|
||||||
|
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||||
|
* @link http://www.phpdoctrine.org
|
||||||
|
* @since 1.0
|
||||||
|
* @version $Revision$
|
||||||
|
*/
|
||||||
|
class Doctrine_Query_Parser_SelectExpression extends Doctrine_Query_ParserRule
|
||||||
|
{
|
||||||
|
protected $_AST = null;
|
||||||
|
|
||||||
|
|
||||||
|
public function syntax($paramHolder)
|
||||||
|
{
|
||||||
|
// SelectExpression ::= IdentificationVariable ["." "*"] |
|
||||||
|
// (StateFieldPathExpression | AggregateExpression | "(" Subselect ")" )
|
||||||
|
// [["AS"] FieldIdentificationVariable]
|
||||||
|
|
||||||
|
// First we recognize for an IdentificationVariable (Component alias)
|
||||||
|
if ($this->_isIdentificationVariable()) {
|
||||||
|
$identificationVariable = $this->parse('IdentificationVariable', $paramHolder);
|
||||||
|
|
||||||
|
// Inspecting if we are in a ["." "*"]
|
||||||
|
if ($this->_isNextToken('.')) {
|
||||||
|
$this->_parser->match('.');
|
||||||
|
$this->_parser->match('*');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $identificationVariable;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected function _isIdentificationVariable()
|
||||||
|
{
|
||||||
|
// Retrying to recoginize this grammar: IdentificationVariable ["." "*"]
|
||||||
|
$token = $this->_parser->lookahead;
|
||||||
|
$this->_parser->getScanner()->resetPeek();
|
||||||
|
|
||||||
|
// We have an identifier here
|
||||||
|
if ($token['type'] === Doctrine_Query_Token::T_IDENTIFIER) {
|
||||||
|
$token = $this->_parser->getScanner()->peek();
|
||||||
|
|
||||||
|
// If we have a dot ".", then next char must be the "*"
|
||||||
|
if ($token['value'] === '.') {
|
||||||
|
$token = $this->_parser->getScanner()->peek();
|
||||||
|
|
||||||
|
return $token['value'] === '*';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
83
lib/Doctrine/Query/Parser/SelectStatement.php
Normal file
83
lib/Doctrine/Query/Parser/SelectStatement.php
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
<?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>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SelectStatement ::= SelectClause FromClause [WhereClause] [GroupByClause] [HavingClause] [OrderByClause]
|
||||||
|
*
|
||||||
|
* @package Doctrine
|
||||||
|
* @subpackage Query
|
||||||
|
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
|
||||||
|
* @author Janne Vanhala <jpvanhal@cc.hut.fi>
|
||||||
|
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||||
|
* @link http://www.phpdoctrine.org
|
||||||
|
* @since 2.0
|
||||||
|
* @version $Revision$
|
||||||
|
*/
|
||||||
|
class Doctrine_Query_Parser_SelectStatement extends Doctrine_Query_ParserRule
|
||||||
|
{
|
||||||
|
protected $_AST = null;
|
||||||
|
|
||||||
|
protected $_selectClause = null;
|
||||||
|
|
||||||
|
|
||||||
|
public function syntax($paramHolder)
|
||||||
|
{
|
||||||
|
// SelectStatement ::= SelectClause FromClause [WhereClause] [GroupByClause] [HavingClause] [OrderByClause]
|
||||||
|
$this->_AST = $this->AST('SelectStatement');
|
||||||
|
|
||||||
|
// 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).
|
||||||
|
$paramHolder->set('semanticalCheck', false);
|
||||||
|
$this->_selectClause = $this->parse('SelectClause', $paramHolder);
|
||||||
|
$paramHolder->remove('semanticalCheck');
|
||||||
|
|
||||||
|
$this->_AST->setFromClause($this->parse('FromClause', $paramHolder));
|
||||||
|
|
||||||
|
if ($this->_isNextToken(Doctrine_Query_Token::T_WHERE)) {
|
||||||
|
$this->_AST->setWhereClause($this->parse('WhereClause', $paramHolder));
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->_isNextToken(Doctrine_Query_Token::T_GROUP)) {
|
||||||
|
$this->_AST->setGroupByClause($this->parse('GroupByClause', $paramHolder));
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->_isNextToken(Doctrine_Query_Token::T_HAVING)) {
|
||||||
|
$this->_AST->setHavingClause($this->parse('HavingClause', $paramHolder));
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->_isNextToken(Doctrine_Query_Token::T_ORDER)) {
|
||||||
|
$this->_AST->setOrderByClause($this->parse('OrderByClause', $paramHolder));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function semantical($paramHolder)
|
||||||
|
{
|
||||||
|
// We need to invoke the semantical check of SelectClause here, since
|
||||||
|
// it was not yet checked.
|
||||||
|
// The semantical checks will be forwarded to all SelectClause dependant grammar rules
|
||||||
|
$this->_AST->setSelectClause($this->_selectClause->semantical($paramHolder));
|
||||||
|
|
||||||
|
// Return AST node
|
||||||
|
return $this->_AST;
|
||||||
|
}
|
||||||
|
}
|
44
lib/Doctrine/Query/Parser/SimpleStateField.php
Normal file
44
lib/Doctrine/Query/Parser/SimpleStateField.php
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
<?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>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SimpleStateField ::= FieldIdentificationVariable
|
||||||
|
*
|
||||||
|
* @package Doctrine
|
||||||
|
* @subpackage Query
|
||||||
|
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
|
||||||
|
* @author Janne Vanhala <jpvanhal@cc.hut.fi>
|
||||||
|
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||||
|
* @link http://www.phpdoctrine.org
|
||||||
|
* @since 2.0
|
||||||
|
* @version $Revision$
|
||||||
|
*/
|
||||||
|
class Doctrine_Query_Parser_SimpleStateField extends Doctrine_Query_ParserRule
|
||||||
|
{
|
||||||
|
protected $_AST = null;
|
||||||
|
|
||||||
|
|
||||||
|
public function syntax($paramHolder)
|
||||||
|
{
|
||||||
|
// SimpleStateField ::= FieldIdentificationVariable
|
||||||
|
return $this->parse('FieldIdentificationVariable', $paramHolder);
|
||||||
|
}
|
||||||
|
}
|
79
lib/Doctrine/Query/Parser/SimpleStateFieldPathExpression.php
Normal file
79
lib/Doctrine/Query/Parser/SimpleStateFieldPathExpression.php
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
<?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>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SimpleStateFieldPathExpression ::= IdentificationVariable "." SimpleStateField
|
||||||
|
*
|
||||||
|
* @package Doctrine
|
||||||
|
* @subpackage Query
|
||||||
|
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
|
||||||
|
* @author Janne Vanhala <jpvanhal@cc.hut.fi>
|
||||||
|
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||||
|
* @link http://www.phpdoctrine.org
|
||||||
|
* @since 2.0
|
||||||
|
* @version $Revision$
|
||||||
|
*/
|
||||||
|
class Doctrine_Query_Parser_SimpleStateFieldPathExpression extends Doctrine_Query_ParserRule
|
||||||
|
{
|
||||||
|
protected $_AST = null;
|
||||||
|
|
||||||
|
|
||||||
|
public function syntax($paramHolder)
|
||||||
|
{
|
||||||
|
// SimpleStateFieldPathExpression ::= IdentificationVariable "." SimpleStateField
|
||||||
|
$this->_AST = $this->AST('SimpleStateFieldPathExpression');
|
||||||
|
|
||||||
|
$this->_AST->setIdentificationVariable($this->parse('IdentificationVariable', $paramHolder));
|
||||||
|
|
||||||
|
$this->_parser->match('.');
|
||||||
|
|
||||||
|
$this->_AST->setSimpleStateField($this->parse('SimpleStateField', $paramHolder));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function semantical($paramHolder)
|
||||||
|
{
|
||||||
|
$parserResult = $this->_parser->getParserResult();
|
||||||
|
$componentAlias = $this->_AST->getIdentificationVariable()->getComponentAlias();
|
||||||
|
$componentFieldName = $this->_AST->getSimpleStateField()->getFieldName();
|
||||||
|
|
||||||
|
// We need to make sure field exists
|
||||||
|
try {
|
||||||
|
$queryComponent = $parserResult->getQueryComponent($componentAlias);
|
||||||
|
$classMetadata = $queryComponent['metadata'];
|
||||||
|
} catch (Doctrine_Exception $e) {
|
||||||
|
$this->_parser->semanticalError($e->getMessage());
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($classMetadata instanceof Doctrine_ClassMetadata && ! $classMetadata->hasField($componentFieldName)) {
|
||||||
|
$this->_parser->semanticalError(
|
||||||
|
"Cannot use key mapping. Field '" . $componentFieldName . "' " .
|
||||||
|
"does not exist in component '" . $classMetadata->getClassName() . "'.",
|
||||||
|
$this->_parser->token
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return AST node
|
||||||
|
return $this->_AST;
|
||||||
|
}
|
||||||
|
}
|
53
lib/Doctrine/Query/Parser/UpdateStatement.php
Normal file
53
lib/Doctrine/Query/Parser/UpdateStatement.php
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
<?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>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* UpdateStatement ::= UpdateClause [WhereClause]
|
||||||
|
*
|
||||||
|
* @package Doctrine
|
||||||
|
* @subpackage Query
|
||||||
|
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
|
||||||
|
* @author Janne Vanhala <jpvanhal@cc.hut.fi>
|
||||||
|
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||||
|
* @link http://www.phpdoctrine.org
|
||||||
|
* @since 2.0
|
||||||
|
* @version $Revision$
|
||||||
|
*/
|
||||||
|
class Doctrine_Query_Parser_UpdateStatement extends Doctrine_Query_Parser
|
||||||
|
{
|
||||||
|
protected $_AST = null;
|
||||||
|
|
||||||
|
|
||||||
|
public function syntax($paramHolder)
|
||||||
|
{
|
||||||
|
// UpdateStatement ::= UpdateClause [WhereClause]
|
||||||
|
$this->_AST = $this->AST('UpdateStatement');
|
||||||
|
|
||||||
|
$this->_AST->setUpdateClause($this->parse('UpdateClause', $paramHolder));
|
||||||
|
|
||||||
|
if ($this->_isNextToken(Doctrine_Query_Token::T_WHERE)) {
|
||||||
|
$this->_AST->setWhereClause($this->parse('WhereClause', $paramHolder));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return AST node
|
||||||
|
return $this->_AST;
|
||||||
|
}
|
||||||
|
}
|
@ -32,7 +32,7 @@
|
|||||||
* @since 2.0
|
* @since 2.0
|
||||||
* @version $Revision$
|
* @version $Revision$
|
||||||
*/
|
*/
|
||||||
class Doctrine_Query_ProductionParamHolder
|
class Doctrine_Query_ParserParamHolder
|
||||||
{
|
{
|
||||||
protected static $_instance;
|
protected static $_instance;
|
||||||
|
|
@ -33,6 +33,13 @@
|
|||||||
*/
|
*/
|
||||||
class Doctrine_Query_ParserResult extends Doctrine_Query_AbstractResult
|
class Doctrine_Query_ParserResult extends Doctrine_Query_AbstractResult
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* The EntityManager.
|
||||||
|
*
|
||||||
|
* @var Doctrine_EntityManager
|
||||||
|
*/
|
||||||
|
protected $_em;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A simple array keys representing table aliases and values table alias
|
* A simple array keys representing table aliases and values table alias
|
||||||
* seeds. The seeds are used for generating short table aliases.
|
* seeds. The seeds are used for generating short table aliases.
|
||||||
@ -47,6 +54,28 @@ class Doctrine_Query_ParserResult extends Doctrine_Query_AbstractResult
|
|||||||
* @var array $_queryFields
|
* @var array $_queryFields
|
||||||
*/
|
*/
|
||||||
protected $_queryFields = array();
|
protected $_queryFields = array();
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the Entity Manager.
|
||||||
|
*
|
||||||
|
* @param Doctrine_EntityManager $em The Entity Manager.
|
||||||
|
*/
|
||||||
|
public function setEntityManager($em)
|
||||||
|
{
|
||||||
|
$this->_em = $em;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the Entity Manager.
|
||||||
|
*
|
||||||
|
* @return Doctrine_EntityManager
|
||||||
|
*/
|
||||||
|
public function getEntityManager()
|
||||||
|
{
|
||||||
|
return $this->_em;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -32,7 +32,7 @@
|
|||||||
* @since 2.0
|
* @since 2.0
|
||||||
* @version $Revision$
|
* @version $Revision$
|
||||||
*/
|
*/
|
||||||
abstract class Doctrine_Query_Production
|
abstract class Doctrine_Query_ParserRule
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @nodoc
|
* @nodoc
|
||||||
@ -97,27 +97,27 @@ abstract class Doctrine_Query_Production
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Executes the production AST using the specified parameters.
|
* Executes the grammar rule using the specified parameters.
|
||||||
*
|
*
|
||||||
* @param string $AstName Production AST name
|
* @param string $RuleName BNF Grammar Rule name
|
||||||
* @param array $paramHolder Production parameter holder
|
* @param array $paramHolder Production parameter holder
|
||||||
* @return Doctrine_Query_Production
|
* @return Doctrine_Query_ParserRule
|
||||||
*/
|
*/
|
||||||
public function AST($AstName, $paramHolder)
|
public function parse($RuleName, $paramHolder)
|
||||||
{
|
{
|
||||||
$AST = $this->_getProduction($AstName);
|
$BNFGrammarRule = $this->_getGrammarRule($RuleName);
|
||||||
|
|
||||||
//echo "Processing class: " . get_class($AST) . "...\n";
|
//echo "Processing class: " . get_class($BNFGrammarRule) . "...\n";
|
||||||
//echo "Params: " . var_export($paramHolder, true) . "\n";
|
//echo "Params: " . var_export($paramHolder, true) . "\n";
|
||||||
|
|
||||||
// Syntax check
|
// Syntax check
|
||||||
if ( ! $paramHolder->has('syntaxCheck') || $paramHolder->get('syntaxCheck') === true) {
|
if ( ! $paramHolder->has('syntaxCheck') || $paramHolder->get('syntaxCheck') === true) {
|
||||||
//echo "Processing syntax checks of " . $AstName . "...\n";
|
//echo "Processing syntax checks of " . $RuleName . "...\n";
|
||||||
|
|
||||||
$return = $AST->syntax($paramHolder);
|
$return = $BNFGrammarRule->syntax($paramHolder);
|
||||||
|
|
||||||
if ($return !== null) {
|
if ($return !== null) {
|
||||||
//echo "Returning AST class: " . (is_object($return) ? get_class($return) : $return) . "...\n";
|
//echo "Returning Gramma Rule class: " . (is_object($return) ? get_class($return) : $return) . "...\n";
|
||||||
|
|
||||||
return $return;
|
return $return;
|
||||||
}
|
}
|
||||||
@ -125,87 +125,64 @@ abstract class Doctrine_Query_Production
|
|||||||
|
|
||||||
// Semantical check
|
// Semantical check
|
||||||
if ( ! $paramHolder->has('semanticalCheck') || $paramHolder->get('semanticalCheck') === true) {
|
if ( ! $paramHolder->has('semanticalCheck') || $paramHolder->get('semanticalCheck') === true) {
|
||||||
//echo "Processing semantical checks of " . $AstName . "...\n";
|
//echo "Processing semantical checks of " . $RuleName . "...\n";
|
||||||
|
|
||||||
$return = $AST->semantical($paramHolder);
|
$return = $BNFGrammarRule->semantical($paramHolder);
|
||||||
|
|
||||||
if ($return !== null) {
|
if ($return !== null) {
|
||||||
//echo "Returning AST class: " . (is_object($return) ? get_class($return) : $return) . "...\n";
|
//echo "Returning Gramma Rule class: " . (is_object($return) ? get_class($return) : $return) . "...\n";
|
||||||
|
|
||||||
return $return;
|
return $return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//echo "Returning AST class: " . get_class($AST) . "...\n";
|
return $BNFGrammarRule;
|
||||||
|
|
||||||
return $AST;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a production object with the given name.
|
* Returns a grammar rule object with the given name.
|
||||||
*
|
*
|
||||||
* @param string $name production name
|
* @param string $name grammar rule name
|
||||||
* @return Doctrine_Query_Production
|
* @return Doctrine_Query_ParserRule
|
||||||
*/
|
*/
|
||||||
protected function _getProduction($name)
|
protected function _getGrammarRule($name)
|
||||||
{
|
{
|
||||||
$class = 'Doctrine_Query_Production_' . $name;
|
$class = 'Doctrine_Query_Parser_' . $name;
|
||||||
|
|
||||||
|
//echo $class . "\r\n";
|
||||||
|
|
||||||
|
if ( ! class_exists($class)) {
|
||||||
|
throw new Doctrine_Query_Parser_Exception(
|
||||||
|
"Unknown Grammar Rule '$name'. Could not find related compiler class."
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return new $class($this->_parser);
|
return new $class($this->_parser);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Executes this production using the specified parameters.
|
* Creates an AST node with the given name.
|
||||||
*
|
*
|
||||||
* @param array $paramHolder Production parameter holder
|
* @param string $AstName AST node name
|
||||||
* @return Doctrine_Query_Production
|
* @return Doctrine_Query_AST
|
||||||
*/
|
*/
|
||||||
public function execute($paramHolder)
|
public function AST($AstName)
|
||||||
{
|
{
|
||||||
//echo "Processing class: " . get_class($this) . " params: \n" . var_export($paramHolder, true) . "\n";
|
$class = 'Doctrine_Query_AST_' . $AstName;
|
||||||
|
|
||||||
// Syntax check
|
//echo $class . "\r\n";
|
||||||
if ( ! $paramHolder->has('syntaxCheck') || $paramHolder->get('syntaxCheck') === true) {
|
|
||||||
//echo "Processing syntax checks of " . get_class($this) . "...\n";
|
|
||||||
|
|
||||||
$return = $this->syntax($paramHolder);
|
if ( ! class_exists($class)) {
|
||||||
|
throw new Doctrine_Query_Parser_Exception(
|
||||||
if ($return !== null) {
|
"Unknown AST node '" . $AstName . "'. Could not find related compiler class."
|
||||||
return $return;
|
);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Semantical check
|
return new $class($this->_parser->getParserResult());
|
||||||
if ( ! $paramHolder->has('semanticalCheck') || $paramHolder->get('semanticalCheck') === true) {
|
|
||||||
//echo "Processing semantical checks of " . get_class($this) . "...\n";
|
|
||||||
|
|
||||||
$return = $this->semantical($paramHolder);
|
|
||||||
|
|
||||||
if ($return !== null) {
|
|
||||||
return $return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return AST instance
|
|
||||||
return $this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Executes this sql builder using the specified parameters.
|
|
||||||
*
|
|
||||||
* @return string Sql piece
|
|
||||||
*/
|
|
||||||
/*public function buildSql()
|
|
||||||
{
|
|
||||||
$className = get_class($this);
|
|
||||||
$methodName = substr($className, strrpos($className, '_'));
|
|
||||||
|
|
||||||
$this->_sqlBuilder->$methodName($this);
|
|
||||||
}*/
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @nodoc
|
* @nodoc
|
||||||
*/
|
*/
|
@ -70,7 +70,6 @@ class Doctrine_Query_Production_UpdateStatement extends Doctrine_Query_Productio
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Getters */
|
/* Getters */
|
||||||
|
|
||||||
public function getUpdateClause()
|
public function getUpdateClause()
|
||||||
{
|
{
|
||||||
return $this->_updateClause;
|
return $this->_updateClause;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
<?php
|
<?php
|
||||||
/*
|
/*
|
||||||
* $Id$
|
* $Id$
|
||||||
*
|
*
|
||||||
@ -35,7 +35,7 @@ abstract class Doctrine_Query_SqlExecutor_Abstract implements Serializable
|
|||||||
|
|
||||||
protected $_sqlStatements;
|
protected $_sqlStatements;
|
||||||
|
|
||||||
public function __construct(Doctrine_Query_Production $AST)
|
public function __construct(Doctrine_Query_AST $AST)
|
||||||
{
|
{
|
||||||
// [TODO] Remove me later!
|
// [TODO] Remove me later!
|
||||||
//$this->AST = $AST;
|
//$this->AST = $AST;
|
||||||
@ -66,10 +66,10 @@ abstract class Doctrine_Query_SqlExecutor_Abstract implements Serializable
|
|||||||
* @param Doctrine_Query_Production $AST The root node of the AST.
|
* @param Doctrine_Query_Production $AST The root node of the AST.
|
||||||
* @return Doctrine_Query_SqlExecutor_Abstract The executor that is suitable for the given AST.
|
* @return Doctrine_Query_SqlExecutor_Abstract The executor that is suitable for the given AST.
|
||||||
*/
|
*/
|
||||||
public static function create(Doctrine_Query_Production $AST)
|
public static function create(Doctrine_Query_AST $AST)
|
||||||
{
|
{
|
||||||
$isDeleteStatement = $AST instanceof Doctrine_Query_Production_DeleteStatement;
|
$isDeleteStatement = $AST instanceof Doctrine_Query_AST_DeleteStatement;
|
||||||
$isUpdateStatement = $AST instanceof Doctrine_Query_Production_UpdateStatement;
|
$isUpdateStatement = $AST instanceof Doctrine_Query_AST_UpdateStatement;
|
||||||
|
|
||||||
if ($isUpdateStatement || $isDeleteStatement) {
|
if ($isUpdateStatement || $isDeleteStatement) {
|
||||||
// TODO: Inspect the $AST and create the proper executor like so (pseudo-code):
|
// TODO: Inspect the $AST and create the proper executor like so (pseudo-code):
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
<?php
|
<?php
|
||||||
/*
|
/*
|
||||||
* $Id$
|
* $Id$
|
||||||
*
|
*
|
||||||
@ -39,7 +39,7 @@ class Doctrine_Query_SqlExecutor_MultiTableDelete extends Doctrine_Query_SqlExec
|
|||||||
*
|
*
|
||||||
* @param Doctrine_Query_Production $AST
|
* @param Doctrine_Query_Production $AST
|
||||||
*/
|
*/
|
||||||
public function __construct(Doctrine_Query_Production $AST)
|
public function __construct(Doctrine_Query_AST $AST)
|
||||||
{
|
{
|
||||||
// TODO: Inspect the AST, create the necessary SQL queries and store them
|
// TODO: Inspect the AST, create the necessary SQL queries and store them
|
||||||
// in $this->_sqlStatements
|
// in $this->_sqlStatements
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
<?php
|
<?php
|
||||||
/*
|
/*
|
||||||
* $Id$
|
* $Id$
|
||||||
*
|
*
|
||||||
@ -34,7 +34,7 @@
|
|||||||
*/
|
*/
|
||||||
class Doctrine_Query_SqlExecutor_MultiTableUpdate extends Doctrine_Query_SqlExecutor_Abstract
|
class Doctrine_Query_SqlExecutor_MultiTableUpdate extends Doctrine_Query_SqlExecutor_Abstract
|
||||||
{
|
{
|
||||||
public function __construct(Doctrine_Query_Production $AST)
|
public function __construct(Doctrine_Query_AST $AST)
|
||||||
{
|
{
|
||||||
// TODO: Inspect the AST, create the necessary SQL queries and store them
|
// TODO: Inspect the AST, create the necessary SQL queries and store them
|
||||||
// in $this->_sqlStatements
|
// in $this->_sqlStatements
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
<?php
|
<?php
|
||||||
/*
|
/*
|
||||||
* $Id$
|
* $Id$
|
||||||
*
|
*
|
||||||
@ -30,7 +30,7 @@
|
|||||||
*/
|
*/
|
||||||
class Doctrine_Query_SqlExecutor_SingleSelect extends Doctrine_Query_SqlExecutor_Abstract
|
class Doctrine_Query_SqlExecutor_SingleSelect extends Doctrine_Query_SqlExecutor_Abstract
|
||||||
{
|
{
|
||||||
public function __construct(Doctrine_Query_Production $AST)
|
public function __construct(Doctrine_Query_AST $AST)
|
||||||
{
|
{
|
||||||
parent::__construct($AST);
|
parent::__construct($AST);
|
||||||
$this->_sqlStatements = $AST->buildSql();
|
$this->_sqlStatements = $AST->buildSql();
|
||||||
|
@ -32,7 +32,7 @@
|
|||||||
*/
|
*/
|
||||||
class Doctrine_Query_SqlExecutor_SingleTableDeleteUpdate extends Doctrine_Query_SqlExecutor_Abstract
|
class Doctrine_Query_SqlExecutor_SingleTableDeleteUpdate extends Doctrine_Query_SqlExecutor_Abstract
|
||||||
{
|
{
|
||||||
public function __construct(Doctrine_Query_Production $AST)
|
public function __construct(Doctrine_Query_AST $AST)
|
||||||
{
|
{
|
||||||
parent::__construct($AST);
|
parent::__construct($AST);
|
||||||
$this->_sqlStatements = $AST->buildSql();
|
$this->_sqlStatements = $AST->buildSql();
|
||||||
|
@ -1,151 +1,153 @@
|
|||||||
<?php
|
<?php
|
||||||
/*
|
/*
|
||||||
* $Id$
|
* $Id$
|
||||||
*
|
*
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* This software consists of voluntary contributions made by many individuals
|
* This software consists of voluntary contributions made by many individuals
|
||||||
* and is licensed under the LGPL. For more information, see
|
* and is licensed under the LGPL. For more information, see
|
||||||
* <http://www.phpdoctrine.org>.
|
* <http://www.phpdoctrine.org>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Container for token type constants of Doctrine Query Language.
|
* Container for token type constants of Doctrine Query Language.
|
||||||
*
|
*
|
||||||
* @package Doctrine
|
* @package Doctrine
|
||||||
* @subpackage Query
|
* @subpackage Query
|
||||||
* @author Janne Vanhala <jpvanhal@cc.hut.fi>
|
* @author Janne Vanhala <jpvanhal@cc.hut.fi>
|
||||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||||
* @link http://www.phpdoctrine.org
|
* @link http://www.phpdoctrine.org
|
||||||
* @since 2.0
|
* @since 2.0
|
||||||
* @version $Revision$
|
* @version $Revision$
|
||||||
*/
|
*/
|
||||||
final class Doctrine_Query_Token
|
final class Doctrine_Query_Token
|
||||||
{
|
{
|
||||||
const T_NONE = 1;
|
const T_NONE = 1;
|
||||||
const T_IDENTIFIER = 2;
|
const T_IDENTIFIER = 2;
|
||||||
const T_INTEGER = 3;
|
const T_INTEGER = 3;
|
||||||
const T_STRING = 4;
|
const T_STRING = 4;
|
||||||
const T_INPUT_PARAMETER = 5;
|
const T_INPUT_PARAMETER = 5;
|
||||||
const T_FLOAT = 6;
|
const T_FLOAT = 6;
|
||||||
|
|
||||||
const T_ALL = 101;
|
const T_ALL = 101;
|
||||||
const T_AND = 102;
|
const T_AND = 102;
|
||||||
const T_ANY = 103;
|
const T_ANY = 103;
|
||||||
const T_AS = 104;
|
const T_AS = 104;
|
||||||
const T_ASC = 105;
|
const T_ASC = 105;
|
||||||
const T_AVG = 106;
|
const T_AVG = 106;
|
||||||
const T_BETWEEN = 107;
|
const T_BETWEEN = 107;
|
||||||
const T_BY = 108;
|
const T_BY = 108;
|
||||||
const T_COUNT = 109;
|
const T_COUNT = 109;
|
||||||
const T_DELETE = 110;
|
const T_DELETE = 110;
|
||||||
const T_DESC = 111;
|
const T_DESC = 111;
|
||||||
const T_DISTINCT = 112;
|
const T_DISTINCT = 112;
|
||||||
const T_ESCAPE = 113;
|
const T_ESCAPE = 113;
|
||||||
const T_EXISTS = 114;
|
const T_EXISTS = 114;
|
||||||
const T_FROM = 115;
|
const T_FROM = 115;
|
||||||
const T_GROUP = 116;
|
const T_GROUP = 116;
|
||||||
const T_HAVING = 117;
|
const T_HAVING = 117;
|
||||||
const T_IN = 118;
|
const T_IN = 118;
|
||||||
const T_INDEX = 119;
|
const T_INDEX = 119;
|
||||||
const T_INNER = 120;
|
const T_INNER = 120;
|
||||||
const T_IS = 121;
|
const T_IS = 121;
|
||||||
const T_JOIN = 122;
|
const T_JOIN = 122;
|
||||||
const T_LEFT = 123;
|
const T_LEFT = 123;
|
||||||
const T_LIKE = 124;
|
const T_LIKE = 124;
|
||||||
const T_LIMIT = 125;
|
const T_LIMIT = 125;
|
||||||
const T_MAX = 126;
|
const T_MAX = 126;
|
||||||
const T_MIN = 127;
|
const T_MIN = 127;
|
||||||
const T_MOD = 128;
|
const T_MOD = 128;
|
||||||
const T_NOT = 129;
|
const T_NOT = 129;
|
||||||
const T_NULL = 130;
|
const T_NULL = 130;
|
||||||
const T_OFFSET = 131;
|
const T_OFFSET = 131;
|
||||||
const T_ON = 132;
|
const T_ON = 132;
|
||||||
const T_OR = 133;
|
const T_OR = 133;
|
||||||
const T_ORDER = 134;
|
const T_ORDER = 134;
|
||||||
const T_SELECT = 135;
|
const T_SELECT = 135;
|
||||||
const T_SET = 136;
|
const T_SET = 136;
|
||||||
const T_SIZE = 137;
|
const T_SIZE = 137;
|
||||||
const T_SOME = 138;
|
const T_SOME = 138;
|
||||||
const T_SUM = 139;
|
const T_SUM = 139;
|
||||||
const T_UPDATE = 140;
|
const T_UPDATE = 140;
|
||||||
const T_WHERE = 141;
|
const T_WHERE = 141;
|
||||||
const T_WITH = 142;
|
const T_WITH = 142;
|
||||||
|
|
||||||
const T_TRUE = 143;
|
const T_TRUE = 143;
|
||||||
const T_FALSE = 144;
|
const T_FALSE = 144;
|
||||||
|
|
||||||
|
|
||||||
protected $_keywordsTable = array();
|
protected $_keywordsTable = array();
|
||||||
|
|
||||||
|
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
$this->addKeyword(self::T_ALL, "ALL");
|
$this->addKeyword(self::T_ALL, "ALL");
|
||||||
$this->addKeyword(self::T_AND, "AND");
|
$this->addKeyword(self::T_AND, "AND");
|
||||||
$this->addKeyword(self::T_ANY, "ANY");
|
$this->addKeyword(self::T_ANY, "ANY");
|
||||||
$this->addKeyword(self::T_AS, "AS");
|
$this->addKeyword(self::T_AS, "AS");
|
||||||
$this->addKeyword(self::T_ASC, "ASC");
|
$this->addKeyword(self::T_ASC, "ASC");
|
||||||
$this->addKeyword(self::T_AVG, "AVG");
|
$this->addKeyword(self::T_AVG, "AVG");
|
||||||
$this->addKeyword(self::T_BETWEEN, "BETWEEN");
|
$this->addKeyword(self::T_BETWEEN, "BETWEEN");
|
||||||
$this->addKeyword(self::T_BY, "BY");
|
$this->addKeyword(self::T_BY, "BY");
|
||||||
$this->addKeyword(self::T_COUNT, "COUNT");
|
$this->addKeyword(self::T_COUNT, "COUNT");
|
||||||
$this->addKeyword(self::T_DELETE, "DELETE");
|
$this->addKeyword(self::T_DELETE, "DELETE");
|
||||||
$this->addKeyword(self::T_DESC, "DESC");
|
$this->addKeyword(self::T_DESC, "DESC");
|
||||||
$this->addKeyword(self::T_DISTINCT, "DISTINCT");
|
$this->addKeyword(self::T_DISTINCT, "DISTINCT");
|
||||||
$this->addKeyword(self::T_ESCAPE, "ESPACE");
|
$this->addKeyword(self::T_ESCAPE, "ESPACE");
|
||||||
$this->addKeyword(self::T_EXISTS, "EXISTS");
|
$this->addKeyword(self::T_EXISTS, "EXISTS");
|
||||||
$this->addKeyword(self::T_FALSE, "FALSE");
|
$this->addKeyword(self::T_FALSE, "FALSE");
|
||||||
$this->addKeyword(self::T_FROM, "FROM");
|
$this->addKeyword(self::T_FROM, "FROM");
|
||||||
$this->addKeyword(self::T_GROUP, "GROUP");
|
$this->addKeyword(self::T_GROUP, "GROUP");
|
||||||
$this->addKeyword(self::T_HAVING, "HAVING");
|
$this->addKeyword(self::T_HAVING, "HAVING");
|
||||||
$this->addKeyword(self::T_IN, "IN");
|
$this->addKeyword(self::T_IN, "IN");
|
||||||
$this->addKeyword(self::T_INDEX, "INDEX");
|
$this->addKeyword(self::T_INDEX, "INDEX");
|
||||||
$this->addKeyword(self::T_INNER, "INNER");
|
$this->addKeyword(self::T_INNER, "INNER");
|
||||||
$this->addKeyword(self::T_IS, "IS");
|
$this->addKeyword(self::T_IS, "IS");
|
||||||
$this->addKeyword(self::T_JOIN, "JOIN");
|
$this->addKeyword(self::T_JOIN, "JOIN");
|
||||||
$this->addKeyword(self::T_LEFT, "LEFT");
|
$this->addKeyword(self::T_LEFT, "LEFT");
|
||||||
$this->addKeyword(self::T_LIKE, "LIKE");
|
$this->addKeyword(self::T_LIKE, "LIKE");
|
||||||
$this->addKeyword(self::T_LIMIT, "LIMIT");
|
$this->addKeyword(self::T_LIMIT, "LIMIT");
|
||||||
$this->addKeyword(self::T_MAX, "MAX");
|
$this->addKeyword(self::T_MAX, "MAX");
|
||||||
$this->addKeyword(self::T_MIN, "MIN");
|
$this->addKeyword(self::T_MIN, "MIN");
|
||||||
$this->addKeyword(self::T_MOD, "MOD");
|
$this->addKeyword(self::T_MOD, "MOD");
|
||||||
$this->addKeyword(self::T_NOT, "NOT");
|
$this->addKeyword(self::T_NOT, "NOT");
|
||||||
$this->addKeyword(self::T_NULL, "NULL");
|
$this->addKeyword(self::T_NULL, "NULL");
|
||||||
$this->addKeyword(self::T_OFFSET, "OFFSET");
|
$this->addKeyword(self::T_OFFSET, "OFFSET");
|
||||||
$this->addKeyword(self::T_ON, "ON");
|
$this->addKeyword(self::T_ON, "ON");
|
||||||
$this->addKeyword(self::T_OR, "OR");
|
$this->addKeyword(self::T_OR, "OR");
|
||||||
$this->addKeyword(self::T_ORDER, "ORDER");
|
$this->addKeyword(self::T_ORDER, "ORDER");
|
||||||
$this->addKeyword(self::T_SELECT, "SELECT");
|
$this->addKeyword(self::T_SELECT, "SELECT");
|
||||||
$this->addKeyword(self::T_SET, "SET");
|
$this->addKeyword(self::T_SET, "SET");
|
||||||
$this->addKeyword(self::T_SIZE, "SIZE");
|
$this->addKeyword(self::T_SIZE, "SIZE");
|
||||||
$this->addKeyword(self::T_SOME, "SOME");
|
$this->addKeyword(self::T_SOME, "SOME");
|
||||||
$this->addKeyword(self::T_SUM, "SUM");
|
$this->addKeyword(self::T_SUM, "SUM");
|
||||||
$this->addKeyword(self::T_TRUE, "TRUE");
|
$this->addKeyword(self::T_TRUE, "TRUE");
|
||||||
$this->addKeyword(self::T_UPDATE, "UPDATE");
|
$this->addKeyword(self::T_UPDATE, "UPDATE");
|
||||||
$this->addKeyword(self::T_WHERE, "WHERE");
|
$this->addKeyword(self::T_WHERE, "WHERE");
|
||||||
$this->addKeyword(self::T_WITH, "WITH");
|
$this->addKeyword(self::T_WITH, "WITH");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
protected function addKeyword($token, $value)
|
protected function addKeyword($token, $value)
|
||||||
{
|
{
|
||||||
$this->_keywordsTable[$token] = $value;
|
$this->_keywordsTable[$token] = $value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public function getLiteral($token)
|
public function getLiteral($token)
|
||||||
{
|
{
|
||||||
return isset($this->_keywordsTable[$token]) ? $this->_keywordsTable[$token] : '';
|
return isset($this->_keywordsTable[$token])
|
||||||
}
|
? $this->_keywordsTable[$token]
|
||||||
}
|
: (is_string($token) ? $token : '');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,250 +1,257 @@
|
|||||||
/* Context-free grammar for Doctrine Query Language
|
/* Context-free grammar for Doctrine Query Language
|
||||||
*
|
*
|
||||||
* Document syntax:
|
* Document syntax:
|
||||||
* - non-terminals begin with an upper case character
|
* - non-terminals begin with an upper case character
|
||||||
* - terminals begin with a lower case character
|
* - terminals begin with a lower case character
|
||||||
* - parentheses (...) are used for grouping
|
* - parentheses (...) are used for grouping
|
||||||
* - square brackets [...] are used for defining an optional part, eg. zero or
|
* - square brackets [...] are used for defining an optional part, eg. zero or
|
||||||
* one time
|
* one time
|
||||||
* - curly brackets {...} are used for repetion, eg. zero or more times
|
* - curly brackets {...} are used for repetion, eg. zero or more times
|
||||||
* - double quotation marks "..." define a terminal string
|
* - double quotation marks "..." define a terminal string
|
||||||
* - a vertical bar | represents an alternative
|
* - a vertical bar | represents an alternative
|
||||||
*
|
*
|
||||||
* At a first glance we'll support SQL-99 based queries
|
* At a first glance we'll support SQL-99 based queries
|
||||||
* Initially Select and Sub-select DQL will not support LIMIT and OFFSET (due to limit-subquery algorithm)
|
* Initially Select and Sub-select DQL will not support LIMIT and OFFSET (due to limit-subquery algorithm)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* TERMINALS
|
* TERMINALS
|
||||||
*
|
*
|
||||||
* identifier (name, email, ...)
|
* identifier (name, email, ...)
|
||||||
* string ('foo', 'bar''s house', '%ninja%', ...)
|
* string ('foo', 'bar''s house', '%ninja%', ...)
|
||||||
* char ('/', '\\', ' ', ...)
|
* char ('/', '\\', ' ', ...)
|
||||||
* integer (-1, 0, 1, 34, ...)
|
* integer (-1, 0, 1, 34, ...)
|
||||||
* float (-0.23, 0.007, 1.245342E+8, ...)
|
* float (-0.23, 0.007, 1.245342E+8, ...)
|
||||||
* boolean (false, true)
|
* boolean (false, true)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* QUERY LANGUAGE (START)
|
* QUERY LANGUAGE (START)
|
||||||
*/
|
*/
|
||||||
QueryLanguage ::= SelectStatement | UpdateStatement | DeleteStatement
|
QueryLanguage ::= SelectStatement | UpdateStatement | DeleteStatement
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* STATEMENTS
|
* STATEMENTS
|
||||||
*/
|
*/
|
||||||
SelectStatement ::= SelectClause FromClause [WhereClause] [GroupByClause] [HavingClause] [OrderByClause]
|
SelectStatement ::= SelectClause FromClause [WhereClause] [GroupByClause] [HavingClause] [OrderByClause]
|
||||||
UpdateStatement ::= UpdateClause [WhereClause]
|
UpdateStatement ::= UpdateClause [WhereClause]
|
||||||
DeleteStatement ::= DeleteClause [WhereClause]
|
DeleteStatement ::= DeleteClause [WhereClause]
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* IDENTIFIERS
|
* IDENTIFIERS
|
||||||
*/
|
*/
|
||||||
IdentificationVariable ::= identifier
|
|
||||||
|
/* Alias Identification usage */
|
||||||
/* identifier that must be a class name */
|
IdentificationVariable ::= identifier
|
||||||
AbstractSchemaName ::= identifier
|
|
||||||
|
/* Alias Identification declaration */
|
||||||
/* identifier that must be a field */
|
AliasIdentificationVariable :: = identifier
|
||||||
FieldIdentificationVariable ::= identifier
|
|
||||||
|
/* identifier that must be a class name */
|
||||||
/* identifier that must be a collection-valued association field (to-many) */
|
AbstractSchemaName ::= identifier
|
||||||
CollectionValuedAssociationField ::= FieldIdentificationVariable
|
|
||||||
|
/* identifier that must be a field */
|
||||||
/* identifier that must be a single-valued association field (to-one) */
|
FieldIdentificationVariable ::= identifier
|
||||||
SingleValuedAssociationField ::= FieldIdentificationVariable
|
|
||||||
|
/* identifier that must be a collection-valued association field (to-many) */
|
||||||
/* identifier that must be an embedded class state field (for the future) */
|
CollectionValuedAssociationField ::= FieldIdentificationVariable
|
||||||
EmbeddedClassStateField ::= FieldIdentificationVariable
|
|
||||||
|
/* identifier that must be a single-valued association field (to-one) */
|
||||||
/* identifier that must be a simple state field (name, email, ...) */
|
SingleValuedAssociationField ::= FieldIdentificationVariable
|
||||||
SimpleStateField ::= FieldIdentificationVariable
|
|
||||||
|
/* identifier that must be an embedded class state field (for the future) */
|
||||||
|
EmbeddedClassStateField ::= FieldIdentificationVariable
|
||||||
/*
|
|
||||||
* PATH EXPRESSIONS
|
/* identifier that must be a simple state field (name, email, ...) */
|
||||||
*/
|
SimpleStateField ::= FieldIdentificationVariable
|
||||||
JoinAssociationPathExpression ::= JoinCollectionValuedPathExpression | JoinSingleValuedAssociationPathExpression
|
|
||||||
JoinCollectionValuedPathExpression ::= IdentificationVariable "." CollectionValuedAssociationField
|
|
||||||
JoinSingleValuedAssociationPathExpression ::= IdentificationVariable "." SingleValuedAssociationField
|
/*
|
||||||
AssociationPathExpression ::= CollectionValuedPathExpression | SingleValuedAssociationPathExpression
|
* PATH EXPRESSIONS
|
||||||
SingleValuedPathExpression ::= StateFieldPathExpression | SingleValuedAssociationPathExpression
|
*/
|
||||||
StateFieldPathExpression ::= {IdentificationVariable | SingleValuedAssociationPathExpression} "." StateField
|
JoinAssociationPathExpression ::= JoinCollectionValuedPathExpression | JoinSingleValuedAssociationPathExpression
|
||||||
SingleValuedAssociationPathExpression ::= IdentificationVariable "." {SingleValuedAssociationField "."}* SingleValuedAssociationField
|
JoinCollectionValuedPathExpression ::= IdentificationVariable "." CollectionValuedAssociationField
|
||||||
CollectionValuedPathExpression ::= IdentificationVariable "." {SingleValuedAssociationField "."}* CollectionValuedAssociationField
|
JoinSingleValuedAssociationPathExpression ::= IdentificationVariable "." SingleValuedAssociationField
|
||||||
StateField ::= {EmbeddedClassStateField "."}* SimpleStateField
|
AssociationPathExpression ::= CollectionValuedPathExpression | SingleValuedAssociationPathExpression
|
||||||
|
SingleValuedPathExpression ::= StateFieldPathExpression | SingleValuedAssociationPathExpression
|
||||||
|
StateFieldPathExpression ::= SimpleStateFieldPathExpression | SimpleStateFieldAssociationPathExpression
|
||||||
/*
|
SingleValuedAssociationPathExpression ::= IdentificationVariable "." {SingleValuedAssociationField "."}* SingleValuedAssociationField
|
||||||
* CLAUSES
|
CollectionValuedPathExpression ::= IdentificationVariable "." {SingleValuedAssociationField "."}* CollectionValuedAssociationField
|
||||||
*/
|
StateField ::= {EmbeddedClassStateField "."}* SimpleStateField
|
||||||
SelectClause ::= "SELECT" ["ALL" | "DISTINCT"] SelectExpression {"," SelectExpression}*
|
SimpleStateFieldPathExpression ::= IdentificationVariable "." SimpleStateField
|
||||||
SimpleSelectClause ::= "SELECT" ["ALL" | "DISTINCT"] SimpleSelectExpression
|
SimpleStateFieldAssociationPathExpression ::= SingleValuedAssociationPathExpression "." StateField
|
||||||
DeleteClause ::= "DELETE" ["FROM"] AbstractSchemaName [["AS"] IdentificationVariable]
|
|
||||||
WhereClause ::= "WHERE" ConditionalExpression
|
|
||||||
FromClause ::= "FROM" IdentificationVariableDeclaration {"," IdentificationVariableDeclaration}*
|
/*
|
||||||
SubselectFromClause ::= "FROM" SubselectIdentificationVariableDeclaration {"," SubselectIdentificationVariableDeclaration}*
|
* CLAUSES
|
||||||
HavingClause ::= "HAVING" ConditionalExpression
|
*/
|
||||||
GroupByClause ::= "GROUP" "BY" GroupByItem {"," GroupByItem}*
|
SelectClause ::= "SELECT" ["ALL" | "DISTINCT"] SelectExpression {"," SelectExpression}*
|
||||||
OrderByClause ::= "ORDER" "BY" OrderByItem {"," OrderByItem}*
|
SimpleSelectClause ::= "SELECT" ["ALL" | "DISTINCT"] SimpleSelectExpression
|
||||||
LimitClause ::= "LIMIT" integer
|
DeleteClause ::= "DELETE" ["FROM"] AbstractSchemaName [["AS"] AliasIdentificationVariable]
|
||||||
OffsetClause ::= "OFFSET" integer
|
WhereClause ::= "WHERE" ConditionalExpression
|
||||||
UpdateClause ::= "UPDATE" AbstractSchemaName [["AS"] IdentificationVariable] "SET" UpdateItem {"," UpdateItem}*
|
FromClause ::= "FROM" IdentificationVariableDeclaration {"," IdentificationVariableDeclaration}*
|
||||||
Subselect ::= SimpleSelectClause SubselectFromClause [WhereClause] [GroupByClause] [HavingClause] [OrderByClause]
|
SubselectFromClause ::= "FROM" SubselectIdentificationVariableDeclaration {"," SubselectIdentificationVariableDeclaration}*
|
||||||
|
HavingClause ::= "HAVING" ConditionalExpression
|
||||||
|
GroupByClause ::= "GROUP" "BY" GroupByItem {"," GroupByItem}*
|
||||||
/*
|
OrderByClause ::= "ORDER" "BY" OrderByItem {"," OrderByItem}*
|
||||||
* ITEMS
|
LimitClause ::= "LIMIT" integer
|
||||||
*/
|
OffsetClause ::= "OFFSET" integer
|
||||||
OrderByItem ::= StateFieldPathExpression ["ASC" | "DESC"]
|
UpdateClause ::= "UPDATE" AbstractSchemaName [["AS"] AliasIdentificationVariable] "SET" UpdateItem {"," UpdateItem}*
|
||||||
GroupByItem ::= SingleValuedPathExpression
|
Subselect ::= SimpleSelectClause SubselectFromClause [WhereClause] [GroupByClause] [HavingClause] [OrderByClause]
|
||||||
UpdateItem ::= [IdentificationVariable"."]{StateField | SingleValuedAssociationField} "=" NewValue
|
|
||||||
NewValue ::= SimpleArithmeticExpression | StringPrimary | DatetimePrimary | BooleanPrimary |
|
|
||||||
EnumPrimary | SimpleEntityExpression | "NULL"
|
/*
|
||||||
|
* ITEMS
|
||||||
|
*/
|
||||||
/*
|
OrderByItem ::= StateFieldPathExpression ["ASC" | "DESC"]
|
||||||
* FROM/JOIN/INDEX BY
|
GroupByItem ::= SingleValuedPathExpression
|
||||||
*/
|
UpdateItem ::= [IdentificationVariable"."]{StateField | SingleValuedAssociationField} "=" NewValue
|
||||||
IdentificationVariableDeclaration ::= RangeVariableDeclaration [IndexBy] {JoinVariableDeclaration}*
|
NewValue ::= SimpleArithmeticExpression | StringPrimary | DatetimePrimary | BooleanPrimary |
|
||||||
SubselectIdentificationVariableDeclaration ::= IdentificationVariableDeclaration | AssociationPathExpression
|
EnumPrimary | SimpleEntityExpression | "NULL"
|
||||||
["AS"] IdentificationVariable
|
|
||||||
JoinVariableDeclaration ::= Join [IndexBy]
|
|
||||||
RangeVariableDeclaration ::= AbstractSchemaName ["AS"] IdentificationVariable
|
/*
|
||||||
Join ::= ["LEFT" ["OUTER"] | "INNER"] "JOIN" JoinAssociationPathExpression
|
* FROM/JOIN/INDEX BY
|
||||||
["AS"] IdentificationVariable [("ON" | "WITH") ConditionalExpression]
|
*/
|
||||||
IndexBy ::= "INDEX" "BY" StateFieldPathExpression
|
IdentificationVariableDeclaration ::= RangeVariableDeclaration [IndexBy] {JoinVariableDeclaration}*
|
||||||
|
SubselectIdentificationVariableDeclaration ::= IdentificationVariableDeclaration | AssociationPathExpression
|
||||||
|
["AS"] AliasIdentificationVariable
|
||||||
/*
|
JoinVariableDeclaration ::= Join [IndexBy]
|
||||||
* SELECT EXPRESSION
|
RangeVariableDeclaration ::= AbstractSchemaName ["AS"] AliasIdentificationVariable
|
||||||
*/
|
Join ::= ["LEFT" ["OUTER"] | "INNER"] "JOIN" JoinAssociationPathExpression
|
||||||
SelectExpression ::= IdentificationVariable ["." "*"] |
|
["AS"] AliasIdentificationVariable [("ON" | "WITH") ConditionalExpression]
|
||||||
(StateFieldPathExpression | AggregateExpression |
|
IndexBy ::= "INDEX" "BY" SimpleStateFieldPathExpression
|
||||||
"(" Subselect ")" ) [["AS"] FieldIdentificationVariable]
|
|
||||||
SimpleSelectExpression ::= SingleValuedPathExpression | IdentificationVariable | AggregateExpression
|
|
||||||
|
/*
|
||||||
|
* SELECT EXPRESSION
|
||||||
/*
|
*/
|
||||||
* CONDITIONAL EXPRESSIONS
|
SelectExpression ::= IdentificationVariable ["." "*"] |
|
||||||
*/
|
(StateFieldPathExpression | AggregateExpression |
|
||||||
ConditionalExpression ::= ConditionalTerm | ConditionalExpression "OR" ConditionalTerm
|
"(" Subselect ")" ) [["AS"] FieldIdentificationVariable]
|
||||||
ConditionalTerm ::= ConditionalFactor | ConditionalTerm "AND" ConditionalFactor
|
SimpleSelectExpression ::= SingleValuedPathExpression | IdentificationVariable | AggregateExpression
|
||||||
ConditionalFactor ::= ["NOT"] ConditionalPrimary
|
|
||||||
ConditionalPrimary ::= SimpleConditionalExpression | "(" ConditionalExpression ")"
|
|
||||||
SimpleConditionalExpression ::= ComparisonExpression | BetweenExpression | LikeExpression |
|
/*
|
||||||
InExpression | NullComparisonExpression | ExistsExpression |
|
* CONDITIONAL EXPRESSIONS
|
||||||
EmptyCollectionComparisonExpression | CollectionMemberExpression
|
*/
|
||||||
/* EmptyCollectionComparisonExpression and CollectionMemberExpression are for the future */
|
ConditionalExpression ::= ConditionalTerm | ConditionalExpression "OR" ConditionalTerm
|
||||||
|
ConditionalTerm ::= ConditionalFactor | ConditionalTerm "AND" ConditionalFactor
|
||||||
|
ConditionalFactor ::= ["NOT"] ConditionalPrimary
|
||||||
/*
|
ConditionalPrimary ::= SimpleConditionalExpression | "(" ConditionalExpression ")"
|
||||||
* COLLECTION EXPRESSIONS (FOR THE FUTURE)
|
SimpleConditionalExpression ::= ComparisonExpression | BetweenExpression | LikeExpression |
|
||||||
*/
|
InExpression | NullComparisonExpression | ExistsExpression |
|
||||||
EmptyCollectionComparisonExpression ::= CollectionValuedPathExpression "IS" ["NOT"] "EMPTY"
|
EmptyCollectionComparisonExpression | CollectionMemberExpression
|
||||||
CollectionMemberExpression ::= EntityExpression ["NOT"] "MEMBER" ["OF"] CollectionValuedPathExpression
|
/* EmptyCollectionComparisonExpression and CollectionMemberExpression are for the future */
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* LITERAL VALUES
|
* COLLECTION EXPRESSIONS (FOR THE FUTURE)
|
||||||
*/
|
*/
|
||||||
Literal ::= string | char | integer | float | boolean | InputParameter
|
EmptyCollectionComparisonExpression ::= CollectionValuedPathExpression "IS" ["NOT"] "EMPTY"
|
||||||
|
CollectionMemberExpression ::= EntityExpression ["NOT"] "MEMBER" ["OF"] CollectionValuedPathExpression
|
||||||
|
|
||||||
/*
|
|
||||||
* INPUT PARAMETER
|
/*
|
||||||
*/
|
* LITERAL VALUES
|
||||||
InputParameter ::= PositionalParameter | NamedParameter
|
*/
|
||||||
PositionalParameter ::= "?" integer
|
Literal ::= string | char | integer | float | boolean | InputParameter
|
||||||
NamedParameter ::= ":" string
|
|
||||||
|
|
||||||
|
/*
|
||||||
/*
|
* INPUT PARAMETER
|
||||||
* ARITHMETIC EXPRESSIONS
|
*/
|
||||||
*/
|
InputParameter ::= PositionalParameter | NamedParameter
|
||||||
ArithmeticExpression ::= SimpleArithmeticExpression | "(" Subselect ")"
|
PositionalParameter ::= "?" integer
|
||||||
SimpleArithmeticExpression ::= ArithmeticTerm | SimpleArithmeticExpression ("+"|"-") ArithmeticTerm
|
NamedParameter ::= ":" string
|
||||||
ArithmeticTerm ::= ArithmeticFactor | ArithmeticTerm ("*" |"/") ArithmeticFactor
|
|
||||||
ArithmeticFactor ::= [("+" | "-")] ArithmeticPrimary
|
|
||||||
ArithmeticPrimary ::= StateFieldPathExpression | Literal | "(" SimpleArithmeticExpression ")" | Function | AggregateExpression
|
/*
|
||||||
|
* ARITHMETIC EXPRESSIONS
|
||||||
|
*/
|
||||||
/*
|
ArithmeticExpression ::= SimpleArithmeticExpression | "(" Subselect ")"
|
||||||
* STRING/BOOLEAN/DATE/ENTITY/ENUM EXPRESSIONS
|
SimpleArithmeticExpression ::= ArithmeticTerm | SimpleArithmeticExpression ("+"|"-") ArithmeticTerm
|
||||||
*/
|
ArithmeticTerm ::= ArithmeticFactor | ArithmeticTerm ("*" |"/") ArithmeticFactor
|
||||||
StringExpression ::= StringPrimary | "(" Subselect ")"
|
ArithmeticFactor ::= [("+" | "-")] ArithmeticPrimary
|
||||||
StringPrimary ::= StateFieldPathExpression | string | InputParameter | FunctionsReturningStrings | AggregateExpression
|
ArithmeticPrimary ::= StateFieldPathExpression | Literal | "(" SimpleArithmeticExpression ")" | Function | AggregateExpression
|
||||||
BooleanExpression ::= BooleanPrimary | "(" Subselect ")"
|
|
||||||
BooleanPrimary ::= StateFieldPathExpression | boolean | InputParameter
|
|
||||||
EnumExpression ::= EnumPrimary | "(" Subselect ")"
|
/*
|
||||||
EnumPrimary ::= StateFieldPathExpression | string | InputParameter
|
* STRING/BOOLEAN/DATE/ENTITY/ENUM EXPRESSIONS
|
||||||
EntityExpression ::= SingleValuedAssociationPathExpression | SimpleEntityExpression
|
*/
|
||||||
SimpleEntityExpression ::= IdentificationVariable | InputParameter
|
StringExpression ::= StringPrimary | "(" Subselect ")"
|
||||||
DatetimeExpression ::= DatetimePrimary | "(" Subselect ")"
|
StringPrimary ::= StateFieldPathExpression | string | InputParameter | FunctionsReturningStrings | AggregateExpression
|
||||||
DatetimePrimary ::= StateFieldPathExpression | InputParameter | FunctionsReturningDatetime | AggregateExpression
|
BooleanExpression ::= BooleanPrimary | "(" Subselect ")"
|
||||||
|
BooleanPrimary ::= StateFieldPathExpression | boolean | InputParameter
|
||||||
|
EnumExpression ::= EnumPrimary | "(" Subselect ")"
|
||||||
/*
|
EnumPrimary ::= StateFieldPathExpression | string | InputParameter
|
||||||
* AGGREGATE EXPRESSION
|
EntityExpression ::= SingleValuedAssociationPathExpression | SimpleEntityExpression
|
||||||
*/
|
SimpleEntityExpression ::= IdentificationVariable | InputParameter
|
||||||
AggregateExpression ::= ("AVG" | "MAX" | "MIN" | "SUM") "(" ["DISTINCT"] StateFieldPathExpression ")" |
|
DatetimeExpression ::= DatetimePrimary | "(" Subselect ")"
|
||||||
"COUNT" "(" ["DISTINCT"] (IdentificationVariable | SingleValuedAssociationPathExpression | StateFieldPathExpression) ")"
|
DatetimePrimary ::= StateFieldPathExpression | InputParameter | FunctionsReturningDatetime | AggregateExpression
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* QUANTIFIED/BETWEEN/COMPARISON/LIKE/NULL/EXISTS EXPRESSIONS
|
* AGGREGATE EXPRESSION
|
||||||
*/
|
*/
|
||||||
QuantifiedExpression ::= ("ALL" | "ANY" | "SOME") "(" Subselect ")"
|
AggregateExpression ::= ("AVG" | "MAX" | "MIN" | "SUM") "(" ["DISTINCT"] StateFieldPathExpression ")" |
|
||||||
BetweenExpression ::= ArithmeticExpression ["NOT"] "BETWEEN" ArithmeticExpression "AND" ArithmeticExpression
|
"COUNT" "(" ["DISTINCT"] (IdentificationVariable | SingleValuedAssociationPathExpression | StateFieldPathExpression) ")"
|
||||||
ComparisonExpression ::= ArithmeticExpression ComparisonOperator ( QuantifiedExpression | ArithmeticExpression ) |
|
|
||||||
StringExpression ComparisonOperator (StringExpression | QuantifiedExpression) |
|
|
||||||
BooleanExpression ("=" | "<>") (BooleanExpression | QuantifiedExpression) |
|
/*
|
||||||
EnumExpression ("=" | "<>") (EnumExpression | QuantifiedExpression) |
|
* QUANTIFIED/BETWEEN/COMPARISON/LIKE/NULL/EXISTS EXPRESSIONS
|
||||||
DatetimeExpression ComparisonOperator (DatetimeExpression | QuantifiedExpression) |
|
*/
|
||||||
EntityExpression ("=" | "<>") (EntityExpression | QuantifiedExpression)
|
QuantifiedExpression ::= ("ALL" | "ANY" | "SOME") "(" Subselect ")"
|
||||||
InExpression ::= StateFieldPathExpression ["NOT"] "IN" "(" (Literal {"," Literal}* | Subselect) ")"
|
BetweenExpression ::= ArithmeticExpression ["NOT"] "BETWEEN" ArithmeticExpression "AND" ArithmeticExpression
|
||||||
LikeExpression ::= ["NOT"] "LIKE" string ["ESCAPE" char]
|
ComparisonExpression ::= ArithmeticExpression ComparisonOperator ( QuantifiedExpression | ArithmeticExpression ) |
|
||||||
NullComparisonExpression ::= (SingleValuedPathExpression | InputParameter) "IS" ["NOT"] "NULL"
|
StringExpression ComparisonOperator (StringExpression | QuantifiedExpression) |
|
||||||
ExistsExpression ::= ["NOT"] "EXISTS" "(" Subselect ")"
|
BooleanExpression ("=" | "<>" | "!=") (BooleanExpression | QuantifiedExpression) |
|
||||||
ComparisonOperator ::= "=" | "<" | "<=" | "<>" | ">" | ">=" | "!="
|
EnumExpression ("=" | "<>" | "!=") (EnumExpression | QuantifiedExpression) |
|
||||||
|
DatetimeExpression ComparisonOperator (DatetimeExpression | QuantifiedExpression) |
|
||||||
|
EntityExpression ("=" | "<>") (EntityExpression | QuantifiedExpression)
|
||||||
/*
|
InExpression ::= StateFieldPathExpression ["NOT"] "IN" "(" (Literal {"," Literal}* | Subselect) ")"
|
||||||
* FUNCTIONS
|
LikeExpression ::= ["NOT"] "LIKE" string ["ESCAPE" char]
|
||||||
*/
|
NullComparisonExpression ::= (SingleValuedPathExpression | InputParameter) "IS" ["NOT"] "NULL"
|
||||||
FunctionsReturningStrings ::= PortableFunctionsReturningStrings | OtherFunctionsReturningStrings
|
ExistsExpression ::= ["NOT"] "EXISTS" "(" Subselect ")"
|
||||||
FunctionsReturningNumerics ::= PortableFunctionsReturningNumerics | OtherFunctionsReturningNumerics
|
ComparisonOperator ::= "=" | "<" | "<=" | "<>" | ">" | ">=" | "!="
|
||||||
FunctionsReturningDateTime ::= PortableFunctionsReturningDateTime | OtherFunctionsReturningDateTime
|
|
||||||
|
|
||||||
|
/*
|
||||||
/*
|
* FUNCTIONS
|
||||||
* OTHER FUNCTIONS: List of all allowed (but not portable) functions here.
|
*/
|
||||||
*/
|
FunctionsReturningStrings ::= PortableFunctionsReturningStrings | OtherFunctionsReturningStrings
|
||||||
OtherFunctionsReturningStrings ::= ...
|
FunctionsReturningNumerics ::= PortableFunctionsReturningNumerics | OtherFunctionsReturningNumerics
|
||||||
OtherFunctionsReturningNumerics ::= ...
|
FunctionsReturningDateTime ::= PortableFunctionsReturningDateTime | OtherFunctionsReturningDateTime
|
||||||
OtherFunctionsReturningDateTime ::= ...
|
|
||||||
|
|
||||||
|
/*
|
||||||
/*
|
* OTHER FUNCTIONS: List of all allowed (but not portable) functions here.
|
||||||
* PORTABLE FUNCTIONS: List all portable functions here
|
*/
|
||||||
* @TODO add all supported portable functions here
|
OtherFunctionsReturningStrings ::= ...
|
||||||
*/
|
OtherFunctionsReturningNumerics ::= ...
|
||||||
PortableFunctionsReturningNumerics ::=
|
OtherFunctionsReturningDateTime ::= ...
|
||||||
"LENGTH" "(" StringPrimary ")" |
|
|
||||||
"LOCATE" "(" StringPrimary "," StringPrimary ["," SimpleArithmeticExpression]")" |
|
|
||||||
"ABS" "(" SimpleArithmeticExpression ")" | "SQRT" "(" SimpleArithmeticExpression ")" |
|
/*
|
||||||
"MOD" "(" SimpleArithmeticExpression "," SimpleArithmeticExpression ")" |
|
* PORTABLE FUNCTIONS: List all portable functions here
|
||||||
"SIZE" "(" CollectionValuedPathExpression ")"
|
* @TODO add all supported portable functions here
|
||||||
|
*/
|
||||||
PortableFunctionsReturningDateTime ::= "CURRENT_DATE" | "CURRENT_TIME" | "CURRENT_TIMESTAMP"
|
PortableFunctionsReturningNumerics ::=
|
||||||
|
"LENGTH" "(" StringPrimary ")" |
|
||||||
PortableFunctionsReturningStrings ::=
|
"LOCATE" "(" StringPrimary "," StringPrimary ["," SimpleArithmeticExpression]")" |
|
||||||
"CONCAT" "(" StringPrimary "," StringPrimary ")" |
|
"ABS" "(" SimpleArithmeticExpression ")" | "SQRT" "(" SimpleArithmeticExpression ")" |
|
||||||
"SUBSTRING" "(" StringPrimary "," SimpleArithmeticExpression "," SimpleArithmeticExpression ")" |
|
"MOD" "(" SimpleArithmeticExpression "," SimpleArithmeticExpression ")" |
|
||||||
"TRIM" "(" [["LEADING" | "TRAILING" | "BOTH"] [char] "FROM"] StringPrimary ")" |
|
"SIZE" "(" CollectionValuedPathExpression ")"
|
||||||
"LOWER" "(" StringPrimary ")" |
|
|
||||||
|
PortableFunctionsReturningDateTime ::= "CURRENT_DATE" | "CURRENT_TIME" | "CURRENT_TIMESTAMP"
|
||||||
|
|
||||||
|
PortableFunctionsReturningStrings ::=
|
||||||
|
"CONCAT" "(" StringPrimary "," StringPrimary ")" |
|
||||||
|
"SUBSTRING" "(" StringPrimary "," SimpleArithmeticExpression "," SimpleArithmeticExpression ")" |
|
||||||
|
"TRIM" "(" [["LEADING" | "TRAILING" | "BOTH"] [char] "FROM"] StringPrimary ")" |
|
||||||
|
"LOWER" "(" StringPrimary ")" |
|
||||||
"UPPER" "(" StringPrimary ")"
|
"UPPER" "(" StringPrimary ")"
|
@ -25,12 +25,12 @@ class Orm_Query_AllTests
|
|||||||
$suite = new Doctrine_TestSuite('Doctrine Orm Query');
|
$suite = new Doctrine_TestSuite('Doctrine Orm Query');
|
||||||
|
|
||||||
$suite->addTestSuite('Orm_Query_IdentifierRecognitionTest');
|
$suite->addTestSuite('Orm_Query_IdentifierRecognitionTest');
|
||||||
$suite->addTestSuite('Orm_Query_LanguageRecognitionTest');
|
/*$suite->addTestSuite('Orm_Query_LanguageRecognitionTest');
|
||||||
$suite->addTestSuite('Orm_Query_ScannerTest');
|
$suite->addTestSuite('Orm_Query_ScannerTest');
|
||||||
$suite->addTestSuite('Orm_Query_DqlGenerationTest');
|
$suite->addTestSuite('Orm_Query_DqlGenerationTest');
|
||||||
$suite->addTestSuite('Orm_Query_DeleteSqlGenerationTest');
|
$suite->addTestSuite('Orm_Query_DeleteSqlGenerationTest');
|
||||||
$suite->addTestSuite('Orm_Query_UpdateSqlGenerationTest');
|
$suite->addTestSuite('Orm_Query_UpdateSqlGenerationTest');
|
||||||
$suite->addTestSuite('Orm_Query_SelectSqlGenerationTest');
|
$suite->addTestSuite('Orm_Query_SelectSqlGenerationTest');*/
|
||||||
|
|
||||||
return $suite;
|
return $suite;
|
||||||
}
|
}
|
||||||
|
@ -55,7 +55,7 @@ class Orm_Query_IdentifierRecognitionTest extends Doctrine_OrmTestCase
|
|||||||
public function testSingleAliasDeclarationWithIndexByIsSupported()
|
public function testSingleAliasDeclarationWithIndexByIsSupported()
|
||||||
{
|
{
|
||||||
$entityManager = $this->_em;
|
$entityManager = $this->_em;
|
||||||
$query = $entityManager->createQuery('SELECT u.* FROM CmsUser u INDEX BY id');
|
$query = $entityManager->createQuery('SELECT u.* FROM CmsUser u INDEX BY u.id');
|
||||||
$parserResult = $query->parse();
|
$parserResult = $query->parse();
|
||||||
|
|
||||||
$decl = $parserResult->getQueryComponent('u');
|
$decl = $parserResult->getQueryComponent('u');
|
||||||
|
@ -1,6 +1,11 @@
|
|||||||
<?php
|
<?php
|
||||||
require_once 'PHPUnit/Framework.php';
|
require_once 'PHPUnit/Framework.php';
|
||||||
require_once 'PHPUnit/TextUI/TestRunner.php';
|
require_once 'PHPUnit/TextUI/TestRunner.php';
|
||||||
|
|
||||||
|
require_once '../lib/Doctrine.php';
|
||||||
|
spl_autoload_register(array('Doctrine', 'autoload'));
|
||||||
|
|
||||||
|
// Some of these classes depends on Doctrine_* classes
|
||||||
require_once 'Doctrine_TestCase.php';
|
require_once 'Doctrine_TestCase.php';
|
||||||
require_once 'Doctrine_TestUtil.php';
|
require_once 'Doctrine_TestUtil.php';
|
||||||
require_once 'Doctrine_DbalTestCase.php';
|
require_once 'Doctrine_DbalTestCase.php';
|
||||||
@ -11,9 +16,6 @@ require_once 'Doctrine_OrmTestSuite.php';
|
|||||||
require_once 'Doctrine_OrmFunctionalTestSuite.php';
|
require_once 'Doctrine_OrmFunctionalTestSuite.php';
|
||||||
require_once 'Doctrine_DbalTestSuite.php';
|
require_once 'Doctrine_DbalTestSuite.php';
|
||||||
|
|
||||||
require_once '../lib/Doctrine.php';
|
|
||||||
spl_autoload_register(array('Doctrine', 'autoload'));
|
|
||||||
|
|
||||||
$modelDir = dirname(__FILE__) . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'models';
|
$modelDir = dirname(__FILE__) . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'models';
|
||||||
Doctrine_Manager::getInstance()->setAttribute(Doctrine::ATTR_MODEL_LOADING, Doctrine::MODEL_LOADING_CONSERVATIVE);
|
Doctrine_Manager::getInstance()->setAttribute(Doctrine::ATTR_MODEL_LOADING, Doctrine::MODEL_LOADING_CONSERVATIVE);
|
||||||
Doctrine::loadModels($modelDir);
|
Doctrine::loadModels($modelDir);
|
||||||
|
@ -1,4 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
require_once 'lib/mocks/Doctrine_ConnectionMock.php';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base testcase class for all orm testcases.
|
* Base testcase class for all orm testcases.
|
||||||
*
|
*
|
||||||
@ -15,7 +18,7 @@ class Doctrine_OrmTestCase extends Doctrine_TestCase
|
|||||||
$config = new Doctrine_Configuration();
|
$config = new Doctrine_Configuration();
|
||||||
$eventManager = new Doctrine_EventManager();
|
$eventManager = new Doctrine_EventManager();
|
||||||
$connectionOptions = array(
|
$connectionOptions = array(
|
||||||
'driver' => 'Doctrine_ConnectionMock',
|
'driverClass' => 'Doctrine_ConnectionMock',
|
||||||
'user' => 'john',
|
'user' => 'john',
|
||||||
'password' => 'wayne'
|
'password' => 'wayne'
|
||||||
);
|
);
|
||||||
|
@ -8,7 +8,7 @@ class Doctrine_EntityPersisterMock extends Doctrine_EntityPersister_Standard
|
|||||||
|
|
||||||
private $_identityColumnValueCounter = 0;
|
private $_identityColumnValueCounter = 0;
|
||||||
|
|
||||||
public function insert($entity)
|
public function insert(Doctrine_Entity $entity)
|
||||||
{
|
{
|
||||||
if ($entity->getClass()->isIdGeneratorIdentity()) {
|
if ($entity->getClass()->isIdGeneratorIdentity()) {
|
||||||
$entity->_assignIdentifier($this->_identityColumnValueCounter++);
|
$entity->_assignIdentifier($this->_identityColumnValueCounter++);
|
||||||
@ -18,12 +18,12 @@ class Doctrine_EntityPersisterMock extends Doctrine_EntityPersister_Standard
|
|||||||
$this->_inserts[] = $entity;
|
$this->_inserts[] = $entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function update($entity)
|
public function update(Doctrine_Entity $entity)
|
||||||
{
|
{
|
||||||
$this->_updates[] = $entity;
|
$this->_updates[] = $entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function delete($entity)
|
public function delete(Doctrine_Entity $entity)
|
||||||
{
|
{
|
||||||
$this->_deletes[] = $entity;
|
$this->_deletes[] = $entity;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user