Commit ec4ea31d authored by jepso's avatar jepso

updates to the lexer of the new dql parser

parent 3fcf1fb8
...@@ -56,6 +56,20 @@ abstract class Doctrine_Query_Production ...@@ -56,6 +56,20 @@ abstract class Doctrine_Query_Production
return ($la['type'] === $token || $la['value'] === $token); return ($la['type'] === $token || $la['value'] === $token);
} }
protected function _isFunction()
{
$la = $this->_parser->lookahead;
$next = $this->_parser->getScanner()->peek();
return ($la['type'] === Doctrine_Query_Token::T_IDENTIFIER && $next['value'] === '(');
}
protected function _isSubselect()
{
$la = $this->_parser->lookahead;
$next = $this->_parser->getScanner()->peek();
return ($la['value'] === '(' && $next['type'] === Doctrine_Query_Token::T_SELECT);
}
/** /**
* Executes a production with specified name and parameters. * Executes a production with specified name and parameters.
* *
......
...@@ -32,19 +32,11 @@ ...@@ -32,19 +32,11 @@
*/ */
class Doctrine_Query_Production_ComparisonExpression extends Doctrine_Query_Production class Doctrine_Query_Production_ComparisonExpression extends Doctrine_Query_Production
{ {
private function _isSubquery()
{
$lookahead = $this->_parser->lookahead;
$next = $this->_parser->getScanner()->peek();
return $lookahead['value'] === '(' && $next['type'] === Doctrine_Query_Token::T_SELECT;
}
public function execute(array $params = array()) public function execute(array $params = array())
{ {
$this->ComparisonOperator(); $this->ComparisonOperator();
if ($this->_isSubquery()) { if ($this->_isSubselect()) {
$this->_parser->match('('); $this->_parser->match('(');
$this->Subselect(); $this->Subselect();
$this->_parser->match(')'); $this->_parser->match(')');
......
...@@ -32,9 +32,52 @@ ...@@ -32,9 +32,52 @@
*/ */
class Doctrine_Query_Production_ConditionalPrimary extends Doctrine_Query_Production class Doctrine_Query_Production_ConditionalPrimary extends Doctrine_Query_Production
{ {
private function _isConditionalExpression()
{
$token = $this->_parser->lookahead;
$parenthesis = 0;
if ($token['value'] === '(') {
$parenthesis++;
}
while ($parenthesis > 0) {
$token = $this->_parser->getScanner()->peek();
if ($token['value'] === '(') {
$parenthesis++;
} elseif ($token['value'] === ')') {
$parenthesis--;
} else {
switch ($token['type']) {
case Doctrine_Query_Token::T_NOT:
case Doctrine_Query_Token::T_AND:
case Doctrine_Query_Token::T_OR:
case Doctrine_Query_Token::T_BETWEEN:
case Doctrine_Query_Token::T_LIKE:
case Doctrine_Query_Token::T_IN:
case Doctrine_Query_Token::T_IS:
case Doctrine_Query_Token::T_EXISTS:
return true;
case Doctrine_Query_Token::T_NONE:
switch ($token['value']) {
case '=':
case '<':
case '>':
return true;
}
break;
}
}
}
return false;
}
public function execute(array $params = array()) public function execute(array $params = array())
{ {
if ($this->_isNextToken('(')) { if ($this->_isConditionalExpression()) {
$this->_parser->match('('); $this->_parser->match('(');
$this->ConditionalExpression(); $this->ConditionalExpression();
$this->_parser->match(')'); $this->_parser->match(')');
......
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
*/ */
/** /**
* DeleteStatement = DeleteClause [WhereClause] [OrderByClause] [LimitClause] * DeleteStatement = DeleteClause [WhereClause] [OrderByClause] [LimitClause] [OffsetClause]
* *
* @package Doctrine * @package Doctrine
* @subpackage Query * @subpackage Query
...@@ -47,5 +47,9 @@ class Doctrine_Query_Production_DeleteStatement extends Doctrine_Query_Productio ...@@ -47,5 +47,9 @@ class Doctrine_Query_Production_DeleteStatement extends Doctrine_Query_Productio
if ($this->_isNextToken(Doctrine_Query_Token::T_LIMIT)) { if ($this->_isNextToken(Doctrine_Query_Token::T_LIMIT)) {
$this->LimitClause(); $this->LimitClause();
} }
if ($this->_isNextToken(Doctrine_Query_Token::T_OFFSET)) {
$this->OffsetClause();
}
} }
} }
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
*/ */
/** /**
* ExistsExpression = ["NOT"] "EXISTS" "(" Subselect ")" * ExistsExpression = "EXISTS" "(" Subselect ")"
* *
* @package Doctrine * @package Doctrine
* @subpackage Query * @subpackage Query
...@@ -34,10 +34,6 @@ class Doctrine_Query_Production_ExistsExpression extends Doctrine_Query_Producti ...@@ -34,10 +34,6 @@ class Doctrine_Query_Production_ExistsExpression extends Doctrine_Query_Producti
{ {
public function execute(array $params = array()) public function execute(array $params = array())
{ {
if ($this->_isNextToken(Doctrine_Query_Token::T_NOT)) {
$this->_parser->match(Doctrine_Query_Token::T_NOT);
}
$this->_parser->match(Doctrine_Query_Token::T_EXISTS); $this->_parser->match(Doctrine_Query_Token::T_EXISTS);
$this->_parser->match('('); $this->_parser->match('(');
......
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
*/ */
/** /**
* Join = ["LEFT" ["OUTER"] | "INNER"] "JOIN" PathExpression "AS" identifier * Join = ["LEFT" | "INNER"] "JOIN" RangeVariableDeclaration [("ON" | "WITH") ConditionalExpression] [IndexBy]
* *
* @package Doctrine * @package Doctrine
* @subpackage Query * @subpackage Query
...@@ -36,11 +36,6 @@ class Doctrine_Query_Production_Join extends Doctrine_Query_Production ...@@ -36,11 +36,6 @@ class Doctrine_Query_Production_Join extends Doctrine_Query_Production
{ {
if ($this->_isNextToken(Doctrine_Query_Token::T_LEFT)) { if ($this->_isNextToken(Doctrine_Query_Token::T_LEFT)) {
$this->_parser->match(Doctrine_Query_Token::T_LEFT); $this->_parser->match(Doctrine_Query_Token::T_LEFT);
if ($this->_isNextToken(Doctrine_Query_Token::T_OUTER)) {
$this->_parser->match(Doctrine_Query_Token::T_OUTER);
}
} elseif ($this->_isNextToken(Doctrine_Query_Token::T_INNER)) { } elseif ($this->_isNextToken(Doctrine_Query_Token::T_INNER)) {
$this->_parser->match(Doctrine_Query_Token::T_INNER); $this->_parser->match(Doctrine_Query_Token::T_INNER);
} }
...@@ -49,7 +44,16 @@ class Doctrine_Query_Production_Join extends Doctrine_Query_Production ...@@ -49,7 +44,16 @@ class Doctrine_Query_Production_Join extends Doctrine_Query_Production
$this->RangeVariableDeclaration(); $this->RangeVariableDeclaration();
$this->_parser->match(Doctrine_Query_Token::T_AS); if ($this->_isNextToken(Doctrine_Query_Token::T_ON)) {
$this->_parser->match(Doctrine_Query_Token::T_IDENTIFIER); $this->_parser->match(Doctrine_Query_Token::T_ON);
$this->ConditionalExpression();
} elseif ($this->_isNextToken(Doctrine_Query_Token::T_WITH)) {
$this->_parser->match(Doctrine_Query_Token::T_WITH);
$this->ConditionalExpression();
}
if ($this->_isNextToken(Doctrine_Query_Token::T_INDEX)) {
$this->IndexBy();
}
} }
} }
<?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>.
*/
/**
* LimitClause = "LIMIT" Expression
*
* @package Doctrine
* @subpackage Query
* @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_Production_LimitClause extends Doctrine_Query_Production
{
public function execute(array $params = array())
{
$this->_parser->match(Doctrine_Query_Token::T_LIMIT);
$this->Expression();
}
}
<?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>.
*/
/**
* OffsetClause = "OFFSET" Expression
*
* @package Doctrine
* @subpackage Query
* @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_Production_OffsetClause extends Doctrine_Query_Production
{
public function execute(array $params = array())
{
$this->_parser->match(Doctrine_Query_Token::T_OFFSET);
$this->Expression();
}
}
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
*/ */
/** /**
* OrderByItem = PathExpression ["ASC" | "DESC"] * OrderByItem = Expression ["ASC" | "DESC"]
* *
* @package Doctrine * @package Doctrine
* @subpackage Query * @subpackage Query
...@@ -34,7 +34,7 @@ class Doctrine_Query_Production_OrderByItem extends Doctrine_Query_Production ...@@ -34,7 +34,7 @@ class Doctrine_Query_Production_OrderByItem extends Doctrine_Query_Production
{ {
public function execute(array $params = array()) public function execute(array $params = array())
{ {
$this->PathExpression(); $this->Expression();
if ($this->_isNextToken(Doctrine_Query_Token::T_ASC)) { if ($this->_isNextToken(Doctrine_Query_Token::T_ASC)) {
$this->_parser->match(Doctrine_Query_Token::T_ASC); $this->_parser->match(Doctrine_Query_Token::T_ASC);
......
...@@ -37,9 +37,7 @@ class Doctrine_Query_Production_Primary extends Doctrine_Query_Production ...@@ -37,9 +37,7 @@ class Doctrine_Query_Production_Primary extends Doctrine_Query_Production
{ {
switch ($this->_parser->lookahead['type']) { switch ($this->_parser->lookahead['type']) {
case Doctrine_Query_Token::T_IDENTIFIER: case Doctrine_Query_Token::T_IDENTIFIER:
$nextToken = $this->_parser->getScanner()->peek(); if ($this->_isFunction()) {
if ($nextToken['value'] === '(') {
$this->Function(); $this->Function();
} else { } else {
$this->PathExpression(); $this->PathExpression();
......
...@@ -45,19 +45,11 @@ class Doctrine_Query_Production_SelectExpression extends Doctrine_Query_Producti ...@@ -45,19 +45,11 @@ class Doctrine_Query_Production_SelectExpression extends Doctrine_Query_Producti
return $token['value'] === '*'; return $token['value'] === '*';
} }
private function _isSubquery()
{
$lookahead = $this->_parser->lookahead;
$next = $this->_parser->getScanner()->peek();
return $lookahead['value'] === '(' && $next['type'] === Doctrine_Query_Token::T_SELECT;
}
public function execute(array $params = array()) public function execute(array $params = array())
{ {
if ($this->_isPathExpressionEndingWithAsterisk()) { if ($this->_isPathExpressionEndingWithAsterisk()) {
$this->PathExpressionEndingWithAsterisk(); $this->PathExpressionEndingWithAsterisk();
} elseif ($this->_isSubquery()) { } elseif ($this->_isSubselect()) {
$this->_parser->match('('); $this->_parser->match('(');
$this->Subselect(); $this->Subselect();
$this->_parser->match(')'); $this->_parser->match(')');
......
...@@ -38,10 +38,10 @@ class Doctrine_Query_Production_UpdateClause extends Doctrine_Query_Production ...@@ -38,10 +38,10 @@ class Doctrine_Query_Production_UpdateClause extends Doctrine_Query_Production
$this->RangeVariableDeclaration(); $this->RangeVariableDeclaration();
$this->_parser->match(Doctrine_Query_Token::T_SET); $this->_parser->match(Doctrine_Query_Token::T_SET);
$this->RangeVariableDeclaration(); $this->UpdateItem();
while ($this->_isNextToken(',')) { while ($this->_isNextToken(',')) {
$this->_parser->match(','); $this->_parser->match(',');
$this->RangeVariableDeclaration(); $this->UpdateItem();
} }
} }
} }
<?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>.
*/
/**
* UpdateItem = PathExpression "=" (Expression | "NULL")
*
* @package Doctrine
* @subpackage Query
* @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_Production_UpdateItem extends Doctrine_Query_Production
{
public function execute(array $params = array())
{
$this->PathExpression();
$this->_parser->match('=');
if ($this->_isNextToken(Doctrine_Query_Token::T_NULL)) {
$this->_parser->match(Doctrine_Query_Token::T_NULL);
} else {
$this->Expression();
}
}
}
...@@ -47,7 +47,7 @@ final class Doctrine_Query_Token ...@@ -47,7 +47,7 @@ final class Doctrine_Query_Token
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 = 100; 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;
...@@ -56,27 +56,30 @@ final class Doctrine_Query_Token ...@@ -56,27 +56,30 @@ final class Doctrine_Query_Token
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_INNER = 119; const T_INDEX = 119;
const T_IS = 120; const T_INNER = 120;
const T_JOIN = 121; const T_IS = 121;
const T_LEFT = 122; const T_JOIN = 122;
const T_LIKE = 123; const T_LEFT = 123;
const T_LIMIT = 124; const T_LIKE = 124;
const T_MAX = 125; const T_LIMIT = 125;
const T_MIN = 126; const T_MAX = 126;
const T_NOT = 127; const T_MIN = 127;
const T_NULL = 128; const T_MOD = 128;
const T_OFFSET = 129; const T_NOT = 129;
const T_OR = 130; const T_NULL = 130;
const T_ORDER = 131; const T_OFFSET = 131;
const T_SELECT = 132; const T_ON = 132;
const T_SET = 133; const T_OR = 133;
const T_SOME = 134; const T_ORDER = 134;
const T_SUM = 135; const T_SELECT = 135;
const T_UPDATE = 136; const T_SET = 136;
const T_WHERE = 137; const T_SIZE = 137;
const T_MOD = 142; const T_SOME = 138;
const T_SIZE = 143; const T_SUM = 139;
const T_UPDATE = 140;
const T_WHERE = 141;
const T_WITH = 142;
private function __construct() {} private function __construct() {}
} }
...@@ -13,9 +13,9 @@ ...@@ -13,9 +13,9 @@
QueryLanguage = SelectStatement | UpdateStatement | DeleteStatement QueryLanguage = SelectStatement | UpdateStatement | DeleteStatement
SelectStatement = [SelectClause] FromClause [WhereClause] [GroupByClause] [HavingClause] [OrderByClause] [LimitClause] SelectStatement = [SelectClause] FromClause [WhereClause] [GroupByClause] [HavingClause] [OrderByClause] [LimitClause] [OffsetClause]
UpdateStatement = UpdateClause [WhereClause] [OrderByClause] [LimitClause] UpdateStatement = UpdateClause [WhereClause] [OrderByClause] [LimitClause] [OffsetClause]
DeleteStatement = DeleteClause [WhereClause] [OrderByClause] [LimitClause] DeleteStatement = DeleteClause [WhereClause] [OrderByClause] [LimitClause] [OffsetClause]
Subselect = SimpleSelectClause FromClause [WhereClause] [GroupByClause] [HavingClause] [OrderByClause] [LimitClause] [OffsetClause] Subselect = SimpleSelectClause FromClause [WhereClause] [GroupByClause] [HavingClause] [OrderByClause] [LimitClause] [OffsetClause]
SelectClause = "SELECT" ["ALL" | "DISTINCT"] SelectExpression {"," SelectExpression} SelectClause = "SELECT" ["ALL" | "DISTINCT"] SelectExpression {"," SelectExpression}
...@@ -26,7 +26,8 @@ FromClause = "FROM" IdentificationVariableDeclaration {"," IdentificationVa ...@@ -26,7 +26,8 @@ FromClause = "FROM" IdentificationVariableDeclaration {"," IdentificationVa
HavingClause = "HAVING" ConditionalExpression HavingClause = "HAVING" ConditionalExpression
GroupByClause = "GROUP" "BY" GroupByItem {"," GroupByItem} GroupByClause = "GROUP" "BY" GroupByItem {"," GroupByItem}
OrderByClause = "ORDER" "BY" OrderByItem {"," OrderByItem} OrderByClause = "ORDER" "BY" OrderByItem {"," OrderByItem}
LimitClause = "LIMIT" Expression ["OFFSET" Expression] LimitClause = "LIMIT" Expression
OffsetClause = "OFFSET" Expression
UpdateClause = "UPDATE" RangeVariableDeclaration "SET" UpdateItem {"," UpdateItem} UpdateClause = "UPDATE" RangeVariableDeclaration "SET" UpdateItem {"," UpdateItem}
OrderByItem = Expression ["ASC" | "DESC"] OrderByItem = Expression ["ASC" | "DESC"]
...@@ -67,6 +68,6 @@ ComparisonExpression = ComparisonOperator ( QuantifiedExpression | Expressio ...@@ -67,6 +68,6 @@ ComparisonExpression = ComparisonOperator ( QuantifiedExpression | Expressio
InExpression = ["NOT"] "IN" "(" (Atom {"," Atom} | Subselect) ")" InExpression = ["NOT"] "IN" "(" (Atom {"," Atom} | Subselect) ")"
LikeExpression = ["NOT"] "LIKE" Expression ["ESCAPE" string_literal] LikeExpression = ["NOT"] "LIKE" Expression ["ESCAPE" string_literal]
NullComparisonExpression = "IS" ["NOT"] "NULL" NullComparisonExpression = "IS" ["NOT"] "NULL"
ExistsExpression = ["NOT"] "EXISTS" "(" Subselect ")" ExistsExpression = "EXISTS" "(" Subselect ")"
Function = identifier "(" [Expression {"," Expression}] ")" Function = identifier "(" [Expression {"," Expression}] ")"
...@@ -25,6 +25,11 @@ class Doctrine_Query_LanguageRecognition_TestCase extends Doctrine_UnitTestCase ...@@ -25,6 +25,11 @@ class Doctrine_Query_LanguageRecognition_TestCase extends Doctrine_UnitTestCase
} }
} }
public function testEmptyQueryString()
{
$this->assertInvalidDql('');
}
public function testPlainFromClauseWithoutAlias() public function testPlainFromClauseWithoutAlias()
{ {
$this->assertValidDql('FROM User'); $this->assertValidDql('FROM User');
...@@ -99,4 +104,180 @@ class Doctrine_Query_LanguageRecognition_TestCase extends Doctrine_UnitTestCase ...@@ -99,4 +104,180 @@ class Doctrine_Query_LanguageRecognition_TestCase extends Doctrine_UnitTestCase
{ {
$this->assertValidDql('SELECT u.id FROM User u WHERE 1 IN (1, 2)'); $this->assertValidDql('SELECT u.id FROM User u WHERE 1 IN (1, 2)');
} }
public function testUpdateWorksWithOneColumn()
{
$this->assertValidDql("UPDATE User u SET u.name = 'someone'");
}
public function testUpdateWorksWithMultipleColumns()
{
$this->assertValidDql("UPDATE User u SET u.name = 'someone', u.email_id = 5");
}
public function testUpdateSupportsConditions()
{
$this->assertValidDql("UPDATE User u SET u.name = 'someone' WHERE u.id = 5");
}
public function testDeleteAll()
{
$this->assertValidDql('DELETE FROM Entity');
}
public function testDeleteWithCondition()
{
$this->assertValidDql('DELETE FROM Entity WHERE id = 3');
}
public function testDeleteWithLimit()
{
$this->assertValidDql('DELETE FROM Entity LIMIT 20');
}
public function testDeleteWithLimitAndOffset()
{
$this->assertValidDql('DELETE FROM Entity LIMIT 10 OFFSET 20');
}
public function testAdditionExpression()
{
$this->assertValidDql('SELECT u.*, (u.id + u.id) addition FROM User u');
}
public function testSubtractionExpression()
{
$this->assertValidDql('SELECT u.*, (u.id - u.id) subtraction FROM User u');
}
public function testDivisionExpression()
{
$this->assertValidDql('SELECT u.*, (u.id/u.id) division FROM User u');
}
public function testMultiplicationExpression()
{
$this->assertValidDql('SELECT u.*, (u.id * u.id) multiplication FROM User u');
}
public function testNegationExpression()
{
$this->assertValidDql('SELECT u.*, -u.id negation FROM User u');
}
public function testExpressionWithPrecedingPlusSign()
{
$this->assertValidDql('SELECT u.*, +u.id FROM User u');
}
public function testAggregateFunctionInHavingClause()
{
$this->assertValidDql('SELECT u.name FROM User u LEFT JOIN u.Phonenumber p HAVING COUNT(p.id) > 2');
$this->assertValidDql("SELECT u.name FROM User u LEFT JOIN u.Phonenumber p HAVING MAX(u.name) = 'zYne'");
}
public function testMultipleAggregateFunctionsInHavingClause()
{
$this->assertValidDql("SELECT u.name FROM User u LEFT JOIN u.Phonenumber p HAVING MAX(u.name) = 'zYne'");
}
public function testLeftJoin()
{
$this->assertValidDql('FROM User u LEFT JOIN u.Group');
}
public function testJoin()
{
$this->assertValidDql('FROM User u JOIN u.Group');
}
public function testInnerJoin()
{
$this->assertValidDql('FROM User u INNER JOIN u.Group');
}
public function testMultipleLeftJoin()
{
$this->assertValidDql('FROM User u LEFT JOIN u.Group LEFT JOIN u.Phonenumber');
}
public function testMultipleInnerJoin()
{
$this->assertValidDql('SELECT u.name FROM User u INNER JOIN u.Group INNER JOIN u.Phonenumber');
}
public function testMultipleInnerJoin2()
{
$this->assertValidDql('SELECT u.name FROM User u INNER JOIN u.Group, u.Phonenumber');
}
public function testMixingOfJoins()
{
$this->assertValidDql('SELECT u.name, g.name, p.phonenumber FROM User u INNER JOIN u.Group g LEFT JOIN u.Phonenumber p');
}
public function testMixingOfJoins2()
{
$this->assertValidDql('SELECT u.name, g.name, p.phonenumber FROM User u INNER JOIN u.Group.Phonenumber p');
}
public function testOrderBySingleColumn()
{
$this->assertValidDql('SELECT u.name FROM User u ORDER BY u.name');
}
public function testOrderBySingleColumnAscending()
{
$this->assertValidDql('SELECT u.name FROM User u ORDER BY u.name ASC');
}
public function testOrderBySingleColumnDescending()
{
$this->assertValidDql('SELECT u.name FROM User u ORDER BY u.name DESC');
}
public function testOrderByMultipleColumns()
{
$this->assertValidDql('SELECT u.firstname, u.lastname FROM User u ORDER BY u.lastname DESC, u.firstname DESC');
}
public function testOrderByWithFunctionExpression()
{
$this->assertValidDql('SELECT u.name FROM User u ORDER BY COALESCE(u.id, u.name) DESC');
}
public function testSubselectInInExpression()
{
$this->assertValidDql("FROM User u WHERE u.id NOT IN (SELECT u2.id FROM User u2 WHERE u2.name = 'zYne')");
}
public function testSubselectInSelectPart()
{
$this->assertValidDql("SELECT u.name, (SELECT COUNT(p.id) FROM Phonenumber p WHERE p.entity_id = u.id) pcount FROM User u WHERE u.name = 'zYne' LIMIT 1");
}
public function testInputParameter()
{
$this->assertValidDql('FROM User WHERE u.id = ?');
}
public function testNamedInputParameter()
{
$this->assertValidDql('FROM User WHERE u.id = :id');
}
public function testCustomJoinsAndWithKeywordSupported()
{
$this->assertValidDql('SELECT c.*, c2.*, d.* FROM Record_Country c INNER JOIN c.City c2 WITH c2.id = 2 WHERE c.id = 1');
}
public function testJoinConditionsSupported()
{
$this->assertValidDql("SELECT u.name, p.id FROM User u LEFT JOIN u.Phonenumber p ON p.phonenumber = '123 123'");
}
public function testIndexByClauseWithOneComponent()
{
$this->assertValidDql('FROM Record_City c INDEX BY c.name');
}
} }
...@@ -91,6 +91,24 @@ class Doctrine_Query_Scanner_TestCase extends Doctrine_UnitTestCase ...@@ -91,6 +91,24 @@ class Doctrine_Query_Scanner_TestCase extends Doctrine_UnitTestCase
$this->assertEqual("'abc''defg'''", $token['value']); $this->assertEqual("'abc''defg'''", $token['value']);
} }
public function testScannerRecognizesInputParameter()
{
$scanner = new Doctrine_Query_Scanner('?');
$token = $scanner->next();
$this->assertEqual(Doctrine_Query_Token::T_INPUT_PARAMETER, $token['type']);
$this->assertEqual('?', $token['value']);
}
public function testScannerRecognizesNamedInputParameter()
{
$scanner = new Doctrine_Query_Scanner(':name');
$token = $scanner->next();
$this->assertEqual(Doctrine_Query_Token::T_INPUT_PARAMETER, $token['type']);
$this->assertEqual(':name', $token['value']);
}
public function testScannerTokenizesASimpleQueryCorrectly() public function testScannerTokenizesASimpleQueryCorrectly()
{ {
$dql = "SELECT u.* FROM User u WHERE u.name = 'Jack O''Neil'"; $dql = "SELECT u.* FROM User u WHERE u.name = 'Jack O''Neil'";
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment