Commit 1ed28763 authored by guilhermeblanco's avatar guilhermeblanco

[2.0] More implementation under ORM/Query

parent dd1afc7e
...@@ -29,23 +29,20 @@ ...@@ -29,23 +29,20 @@
* @since 2.0 * @since 2.0
* @version $Revision$ * @version $Revision$
*/ */
class Doctrine_ORM_Query_Parser_DeleteStatement extends Doctrine_ORM_Query_Parser class Doctrine_ORM_Query_Parser_DeleteStatement extends Doctrine_ORM_Query_ParserRule
{ {
protected $_AST = null;
public function syntax() public function syntax()
{ {
// DeleteStatement ::= DeleteClause [WhereClause] // DeleteStatement ::= DeleteClause [WhereClause]
$this->_AST = $this->AST('DeleteStatement'); $AST = $this->AST('DeleteStatement');
$this->_AST->setDeleteClause($this->parse('DeleteClause')); $AST->setDeleteClause($this->parse('DeleteClause'));
if ($this->_isNextToken(Doctrine_ORM_Query_Token::T_WHERE)) { if ($this->_isNextToken(Doctrine_ORM_Query_Token::T_WHERE)) {
$this->_AST->setWhereClause($this->parse('WhereClause')); $AST->setWhereClause($this->parse('WhereClause'));
} }
// Return AST node // Return AST node
return $this->_AST; return $AST;
} }
} }
...@@ -48,7 +48,8 @@ class Doctrine_ORM_Query_Parser_FieldAliasIdentificationVariable extends Doctrin ...@@ -48,7 +48,8 @@ class Doctrine_ORM_Query_Parser_FieldAliasIdentificationVariable extends Doctrin
if ($parserResult->hasFieldAlias($this->_fieldAlias)) { if ($parserResult->hasFieldAlias($this->_fieldAlias)) {
// We should throw semantical error if there's already a field for this alias // We should throw semantical error if there's already a field for this alias
$message = "Cannot re-declare field alias '" . $this->_fieldAlias . "'."; $message = "Cannot re-declare field alias '" . $this->_fieldAlias
. "' near '" . $this->_parser->getQueryPiece($this->_parser->token) . "'.";
$this->_parser->semanticalError($message); $this->_parser->semanticalError($message);
} }
......
<?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>.
*/
/**
* JoinAssociationPathExpression ::= JoinCollectionValuedPathExpression | JoinSingleValuedAssociationPathExpression
*
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
* @author Janne Vanhala <jpvanhal@cc.hut.fi>
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @link http://www.phpdoctrine.org
* @since 2.0
* @version $Revision$
*/
class Doctrine_ORM_Query_Parser_JoinAssociationPathExpression extends Doctrine_ORM_Query_ParserRule
{
public function syntax()
{
// JoinAssociationPathExpression ::= JoinCollectionValuedPathExpression | JoinSingleValuedAssociationPathExpression
return $this->parse($this->_isSingleValuedPathExpression()
? 'JoinSingleValuedAssociationPathExpression'
: 'JoinCollectionValuedPathExpression'
);
}
private function _isSingleValuedPathExpression()
{
$parserResult = $this->_parser->getParserResult();
// Trying to recoginize this grammar:
// IdentificationVariable "." (CollectionValuedAssociationField | SingleValuedAssociationField)
$token = $this->_parser->lookahead;
$this->_parser->getScanner()->resetPeek();
if ($parserResult->hasQueryComponent($token['value'])) {
$queryComponent = $parserResult->getQueryComponent($token['value']);
$token = $this->_parser->getScanner()->peek();
// If we have a dot ".", then next char must be the "*"
if ($token['type'] === Doctrine_ORM_Query_Token::T_DOT) {
$token = $this->_parser->getScanner()->peek();
if ( ! ($queryComponent['metadata']->hasAssociation($token['value']) &&
$queryComponent['metadata']->getAssociation($token['value'])->isOneToTone())) {
return true;
}
}
}
return false;
}
}
...@@ -59,17 +59,8 @@ class Doctrine_ORM_Query_Parser_JoinCollectionValuedPathExpression extends Doctr ...@@ -59,17 +59,8 @@ class Doctrine_ORM_Query_Parser_JoinCollectionValuedPathExpression extends Doctr
$this->_parser->semanticalError($message); $this->_parser->semanticalError($message);
} }
if ( ! $queryComponent['metadata']->hasAssociation($fieldName)) { if ( ! ($queryComponent['metadata']->hasAssociation($fieldName) &&
$componentName = $queryComponent['metadata']->getClassName(); $queryComponent['metadata']->getAssociation($fieldName)->isOneToTone())) {
$message = "Field '" . $fieldName . "' is not an association in component '" . $componentName . "'.";
$this->_parser->semanticalError($message);
}
$mapping = $queryComponent['metadata']->getAssociation($fieldName);
if ($mapping instanceof Doctrine_ORM_Mapping_OneToOneMapping) {
$componentName = $queryComponent['metadata']->getClassName(); $componentName = $queryComponent['metadata']->getClassName();
$message = "Field '" . $fieldName . "' does not map to a collection valued association in component '" $message = "Field '" . $fieldName . "' does not map to a collection valued association in component '"
......
<?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>.
*/
/**
* JoinSingleValuedAssociationPathExpression ::= IdentificationVariable "." SingleValuedAssociationField
*
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
* @author Janne Vanhala <jpvanhal@cc.hut.fi>
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @link http://www.phpdoctrine.org
* @since 2.0
* @version $Revision$
*/
class Doctrine_ORM_Query_Parser_JoinSingleValuedAssociationPathExpression extends Doctrine_ORM_Query_ParserRule
{
protected $_AST = null;
public function syntax()
{
// JoinSingleValuedAssociationPathExpression ::= IdentificationVariable "." SingleValuedAssociationField
$this->_AST = $this->AST('JoinSingleValuedAssociationPathExpression');
$this->_AST->setIdentificationVariable($this->parse('IdentificationVariable'));
$this->_parser->match(Doctrine_ORM_Query_Token::T_DOT);
$this->_AST->setSingleValuedAssociationField($this->parse('SingleValuedAssociationField'));
}
public function semantical()
{
$parserResult = $this->_parser->getParserResult();
$queryComponent = $parserResult->getQueryComponent($this->_AST->setIdentificationVariable());
$fieldName = $this->_AST->setSingleValuedAssociationField();
if ( ! $queryComponent['metadata']->hasField($fieldName)) {
$componentName = $queryComponent['metadata']->getClassName();
$message = "Field '" . $fieldName . "' does not exist in component '" . $componentName . "'.";
$this->_parser->semanticalError($message);
}
if ( ! ($queryComponent['metadata']->hasAssociation($fieldName) &&
! $queryComponent['metadata']->getAssociation($fieldName)->isOneToTone())) {
$componentName = $queryComponent['metadata']->getClassName();
$message = "Field '" . $fieldName . "' does not map to a single valued association in component '"
. $componentName . "'.";
$this->_parser->semanticalError($message);
}
return $this->_AST;
}
}
\ No newline at end of file
...@@ -53,8 +53,8 @@ class Doctrine_ORM_Query_Parser_SelectClause extends Doctrine_ORM_Query_ParserRu ...@@ -53,8 +53,8 @@ class Doctrine_ORM_Query_Parser_SelectClause extends Doctrine_ORM_Query_ParserRu
// Process SelectExpressions (1..N) // Process SelectExpressions (1..N)
$this->_selectExpressions[] = $this->parse('SelectExpression'); $this->_selectExpressions[] = $this->parse('SelectExpression');
while ($this->_isNextToken(',')) { while ($this->_isNextToken(Doctrine_ORM_Query_Token::T_COMMA)) {
$this->_parser->match(','); $this->_parser->match(Doctrine_ORM_Query_Token::T_COMMA);
$this->_selectExpressions[] = $this->parse('SelectExpression'); $this->_selectExpressions[] = $this->parse('SelectExpression');
} }
......
...@@ -20,9 +20,8 @@ ...@@ -20,9 +20,8 @@
*/ */
/** /**
* SelectExpression ::= IdentificationVariable ["." "*"] | * SelectExpression ::= IdentificationVariable ["." "*"] | StateFieldPathExpression |
* (StateFieldPathExpression | AggregateExpression | "(" Subselect ")" ) * (AggregateExpression | "(" Subselect ")") [["AS"] FieldAliasIdentificationVariable]
* [["AS"] FieldIdentificationVariable]
* *
* @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>
...@@ -43,7 +42,8 @@ class Doctrine_ORM_Query_Parser_SelectExpression extends Doctrine_ORM_Query_Pars ...@@ -43,7 +42,8 @@ class Doctrine_ORM_Query_Parser_SelectExpression extends Doctrine_ORM_Query_Pars
public function syntax() public function syntax()
{ {
// SelectExpression ::= IdentificationVariable ["." "*"] | StateFieldPathExpression | // SelectExpression ::= IdentificationVariable ["." "*"] | StateFieldPathExpression |
// ( ( AggregateExpression | "(" Subselect ")" ) ["AS"] FieldIdentificationVariable ) // (AggregateExpression | "(" Subselect ")") [["AS"] FieldAliasIdentificationVariable]
$this->_AST = $this->AST('SelectExpression');
// First we recognize for an IdentificationVariable (Component alias) // First we recognize for an IdentificationVariable (Component alias)
if ($this->_isIdentificationVariable()) { if ($this->_isIdentificationVariable()) {
...@@ -54,16 +54,16 @@ class Doctrine_ORM_Query_Parser_SelectExpression extends Doctrine_ORM_Query_Pars ...@@ -54,16 +54,16 @@ class Doctrine_ORM_Query_Parser_SelectExpression extends Doctrine_ORM_Query_Pars
$this->_parser->match('.'); $this->_parser->match('.');
$this->_parser->match('*'); $this->_parser->match('*');
} }
} else if ($this->_isFunction() || $this->_isSubselect()) { } else if (($isFunction = $this->_isFunction()) !== false || $this->_isSubselect()) {
$this->_expression = $this->parse( $this->_expression = $this->parse($isFunction ? 'AggregateExpression' : 'Subselect');
$this->_isFunction() ? 'AggregateExpression' : 'Subselect'
);
if ($this->_isNextToken(Doctrine_ORM_Query_Token::T_AS)) { if ($this->_isNextToken(Doctrine_ORM_Query_Token::T_AS)) {
$this->_parser->match(Doctrine_ORM_Query_Token::T_AS); $this->_parser->match(Doctrine_ORM_Query_Token::T_AS);
}
$this->_fieldIdentificationVariable = $this->parse('FieldIdentificationVariable'); $this->_fieldIdentificationVariable = $this->parse('FieldAliasIdentificationVariable');
} elseif ($this->_isNextToken(Doctrine_ORM_Query_Token::T_IDENTIFIER)) {
$this->_fieldIdentificationVariable = $this->parse('FieldAliasIdentificationVariable');
}
} else { } else {
$this->_expression = $this->parse('StateFieldPathExpression'); $this->_expression = $this->parse('StateFieldPathExpression');
} }
...@@ -72,17 +72,14 @@ class Doctrine_ORM_Query_Parser_SelectExpression extends Doctrine_ORM_Query_Pars ...@@ -72,17 +72,14 @@ class Doctrine_ORM_Query_Parser_SelectExpression extends Doctrine_ORM_Query_Pars
public function semantical() public function semantical()
{ {
$expression = $this->_expression->semantical(); $this->_AST->setExpression($this->_expression->semantical());
if ($this->_fieldIdentificationVariable !== null) { if ($this->_fieldIdentificationVariable !== null) {
$expr = $expression; $this->_AST->setFieldIdentificationVariable($this->_fieldIdentificationVariable->semantical());
$expression = $this->AST('SelectExpression');
$expression->setExpression($expr);
$expression->setFieldIdentificationVariable($this->_fieldIdentificationVariable->semantical());
} }
return $expression; // Return AST node
return $this->_AST;
} }
...@@ -97,7 +94,7 @@ class Doctrine_ORM_Query_Parser_SelectExpression extends Doctrine_ORM_Query_Pars ...@@ -97,7 +94,7 @@ class Doctrine_ORM_Query_Parser_SelectExpression extends Doctrine_ORM_Query_Pars
$token = $this->_parser->getScanner()->peek(); $token = $this->_parser->getScanner()->peek();
// If we have a dot ".", then next char must be the "*" // If we have a dot ".", then next char must be the "*"
if ($token['value'] === '.') { if ($token['type'] === Doctrine_ORM_Query_Token::T_DOT) {
$token = $this->_parser->getScanner()->peek(); $token = $this->_parser->getScanner()->peek();
return $token['value'] === '*'; return $token['value'] === '*';
......
...@@ -29,23 +29,20 @@ ...@@ -29,23 +29,20 @@
* @since 2.0 * @since 2.0
* @version $Revision$ * @version $Revision$
*/ */
class Doctrine_ORM_Query_Parser_UpdateStatement extends Doctrine_ORM_Query_Parser class Doctrine_ORM_Query_Parser_UpdateStatement extends Doctrine_ORM_Query_ParserRule
{ {
protected $_AST = null;
public function syntax() public function syntax()
{ {
// UpdateStatement ::= UpdateClause [WhereClause] // UpdateStatement ::= UpdateClause [WhereClause]
$this->_AST = $this->AST('UpdateStatement'); $AST = $this->AST('UpdateStatement');
$this->_AST->setUpdateClause($this->parse('UpdateClause')); $AST->setUpdateClause($this->parse('UpdateClause'));
if ($this->_isNextToken(Doctrine_ORM_Query_Token::T_WHERE)) { if ($this->_isNextToken(Doctrine_ORM_Query_Token::T_WHERE)) {
$this->_AST->setWhereClause($this->parse('WhereClause')); $AST->setWhereClause($this->parse('WhereClause'));
} }
// Return AST node // Return AST node
return $this->_AST; return $AST;
} }
} }
...@@ -46,45 +46,46 @@ final class Doctrine_ORM_Query_Token ...@@ -46,45 +46,46 @@ final class Doctrine_ORM_Query_Token
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_COMMA = 109;
const T_DELETE = 110; const T_COUNT = 110;
const T_DESC = 111; const T_DELETE = 111;
const T_DISTINCT = 112; const T_DESC = 112;
const T_DOT = 113; const T_DISTINCT = 113;
const T_ESCAPE = 114; const T_DOT = 114;
const T_EXISTS = 115; const T_ESCAPE = 115;
const T_FROM = 116; const T_EXISTS = 116;
const T_GROUP = 117; const T_FROM = 117;
const T_HAVING = 118; const T_GROUP = 118;
const T_IN = 119; const T_HAVING = 119;
const T_INDEX = 120; const T_IN = 120;
const T_INNER = 121; const T_INDEX = 121;
const T_IS = 122; const T_INNER = 122;
const T_JOIN = 123; const T_IS = 123;
const T_LEFT = 124; const T_JOIN = 124;
const T_LIKE = 125; const T_LEFT = 125;
const T_LIMIT = 126; const T_LIKE = 126;
const T_MAX = 127; const T_LIMIT = 127;
const T_MIN = 128; const T_MAX = 128;
const T_MOD = 129; const T_MIN = 129;
const T_NOT = 130; const T_MOD = 130;
const T_NULL = 131; const T_NOT = 131;
const T_OFFSET = 132; const T_NULL = 132;
const T_ON = 133; const T_OFFSET = 133;
const T_OR = 134; const T_ON = 134;
const T_ORDER = 135; const T_OR = 135;
const T_OUTER = 136; const T_ORDER = 136;
const T_SELECT = 137; const T_OUTER = 137;
const T_SET = 138; const T_SELECT = 138;
const T_SIZE = 139; const T_SET = 139;
const T_SOME = 140; const T_SIZE = 140;
const T_SUM = 141; const T_SOME = 141;
const T_UPDATE = 142; const T_SUM = 142;
const T_WHERE = 143; const T_UPDATE = 143;
const T_WITH = 144; const T_WHERE = 144;
const T_WITH = 145;
const T_TRUE = 145; const T_TRUE = 146;
const T_FALSE = 146; const T_FALSE = 147;
protected $_keywordsTable = array(); protected $_keywordsTable = array();
...@@ -100,6 +101,7 @@ final class Doctrine_ORM_Query_Token ...@@ -100,6 +101,7 @@ final class Doctrine_ORM_Query_Token
$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_COMMA, ",");
$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");
......
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