Commit 22de495e authored by romanb's avatar romanb

[2.0] Cleaned up old Production/Parser classes.

parent d89d9a03
......@@ -24,10 +24,9 @@ namespace Doctrine\Common;
/**
* EventArgs is the base class for classes containing event data.
*
* This class contains no event data and cannot be instantiated.
* It is used by events that do not pass state information to an event handler
* when an event is raised. The single empty EventArgs instance can be obtained
* through {@link getEmptyInstance()}.
* This class contains no event data. It is used by events that do not pass state
* information to an event handler when an event is raised. The single empty EventArgs
* instance can be obtained through {@link getEmptyInstance()}.
*
* @author Konsta Vesterinen <kvesteri@cc.hut.fi>
* @author Roman Borschel
......@@ -39,22 +38,6 @@ namespace Doctrine\Common;
class EventArgs
{
private static $_emptyEventArgsInstance;
private $_defaultPrevented;
protected function __construct()
{
$this->_defaultPrevented = false;
}
public function preventDefault()
{
$this->_defaultPrevented = true;
}
public function getDefaultPrevented()
{
return $this->_defaultPrevented;
}
public static function getEmptyInstance()
{
......
......@@ -54,20 +54,18 @@ class EventManager
public function dispatchEvent($eventName, EventArgs $eventArgs = null)
{
if (isset($this->_listeners[$eventName])) {
$eventArgs = is_null($eventArgs) ? EventArgs::getEmptyInstance() : $eventArgs;
$eventArgs = $eventArgs === null ? EventArgs::getEmptyInstance() : $eventArgs;
foreach ($this->_listeners[$eventName] as $listener) {
$listener->$eventName($eventArgs);
}
return ! $eventArgs->getDefaultPrevented();
}
return true;
}
/**
* Gets the listeners of a specific event or all listeners.
*
* @param string $event The name of the event.
* @return
* @return The event listeners for the specified event, or all event listeners.
*/
public function getListeners($event = null)
{
......@@ -78,7 +76,7 @@ class EventManager
* Checks whether an event has any registered listeners.
*
* @param string $event
* @return boolean
* @return boolean TRUE if the specified event has any listeners, FALSE otherwise.
*/
public function hasListeners($event)
{
......
......@@ -21,6 +21,7 @@
namespace Doctrine\DBAL\Platforms;
use Doctrine\Common\DoctrineException;
use Doctrine\DBAL\Connection;
/**
......
......@@ -599,10 +599,10 @@ class EntityManager
\Doctrine\Common\DoctrineException::updateMe("Invalid parameter '$conn'.");
}
if (is_null($config)) {
if ($config === null) {
$config = new Configuration();
}
if (is_null($eventManager)) {
if ($eventManager === null) {
$eventManager = new EventManager();
}
......
......@@ -80,7 +80,7 @@ class EntityRepository
*/
public function find($id, $hydrationMode = null)
{
if (is_null($id)) {
if ($id === null) {
return false;
}
......
......@@ -2,6 +2,8 @@
namespace Doctrine\ORM\Id;
use Doctrine\ORM\EntityManager;
/**
* Enter description here...
*/
......@@ -9,7 +11,7 @@ abstract class AbstractIdGenerator
{
protected $_em;
public function __construct(\Doctrine\ORM\EntityManager $em)
public function __construct(EntityManager $em)
{
$this->_em = $em;
}
......@@ -26,6 +28,7 @@ abstract class AbstractIdGenerator
* Gets whether this generator is a post-insert generator which means that
* {@link generate()} must be called after the entity has been inserted
* into the database.
*
* By default, this method returns FALSE. Generators that have this requirement
* must override this method and return TRUE.
*
......
......@@ -2,25 +2,48 @@
namespace Doctrine\ORM\Id;
use Doctrine\ORM\EntityManager;
class SequenceGenerator extends AbstractIdGenerator
{
private $_allocationSize;
private $_sequenceName;
private $_nextValue = 0;
private $_maxValue = null;
public function __construct($sequenceName)
public function __construct(EntityManager $em, $sequenceName, $allocationSize = 20)
{
parent::__construct($em);
$this->_sequenceName = $sequenceName;
$this->_allocationSize = $allocationSize;
}
/**
* Enter description here...
* Generates an ID for the given entity.
*
* @param Doctrine_ORM_Entity $entity
* @param object $entity
* @return integer|float The generated value.
* @override
*/
public function generate($entity)
{
$conn = $this->_em->getConnection();
$sql = $conn->getDatabasePlatform()->getSequenceNextValSql($this->_sequenceName);
return $conn->fetchOne($sql);
if ($this->_maxValue === null || $this->_nextValue == $this->_maxValue) {
// Allocate new values
$conn = $this->_em->getConnection();
$sql = $conn->getDatabasePlatform()->getSequenceNextValSql($this->_sequenceName);
$this->_maxValue = $conn->fetchOne($sql);
$this->_nextValue = $this->_maxValue - $this->_allocationSize;
}
return $this->_nextValue++;
}
public function getCurrentMaxValue()
{
return $this->_maxValue;
}
public function getNextValue()
{
return $this->_nextValue;
}
}
\ No newline at end of file
}
......@@ -174,7 +174,7 @@ abstract class AssociationMapping
*/
public function isCascadeDelete()
{
if (is_null($this->_isCascadeDelete)) {
if ($this->_isCascadeDelete === null) {
$this->_isCascadeDelete = in_array('delete', $this->_cascades);
}
return $this->_isCascadeDelete;
......@@ -188,7 +188,7 @@ abstract class AssociationMapping
*/
public function isCascadeSave()
{
if (is_null($this->_isCascadeSave)) {
if ($this->_isCascadeSave === null) {
$this->_isCascadeSave = in_array('save', $this->_cascades);
}
return $this->_isCascadeSave;
......@@ -202,7 +202,7 @@ abstract class AssociationMapping
*/
public function isCascadeRefresh()
{
if (is_null($this->_isCascadeRefresh)) {
if ($this->_isCascadeRefresh === null) {
$this->_isCascadeRefresh = in_array('refresh', $this->_cascades);
}
return $this->_isCascadeRefresh;
......
......@@ -83,4 +83,9 @@ final class DoctrineJoinTable extends \Addendum\Annotation {
public $schema;
public $joinColumns;
public $inverseJoinColumns;
}
\ No newline at end of file
}
final class DoctrineSequenceGenerator extends \Addendum\Annotation {
public $name;
public $allocationSize = 20;
public $initialValue;
}
......@@ -215,14 +215,14 @@ abstract class AbstractEntityPersister
}
foreach ($assocMapping->getSourceToTargetKeyColumns() as $sourceColumn => $targetColumn) {
$otherClass = $this->_em->getClassMetadata($assocMapping->getTargetEntityName());
if (is_null($newVal)) {
if ($newVal === null) {
$result[$sourceColumn] = null;
} else {
$result[$sourceColumn] = $otherClass->getReflectionProperty(
$otherClass->getFieldName($targetColumn))->getValue($newVal);
}
}
} else if (is_null($newVal)) {
} else if ($newVal === null) {
$result[$columnName] = null;
} else {
$result[$columnName] = $type->convertToDatabaseValue($newVal, $this->_conn->getDatabasePlatform());
......
......@@ -40,10 +40,12 @@ class Lexer
* @var array
*/
private $_tokens = array();
/**
* @todo Doc
*/
private $_position = 0;
/**
* @todo Doc
*/
......@@ -69,6 +71,12 @@ class Lexer
$this->_scan($input);
}
/**
* Checks whether a given token matches the current lookahead.
*
* @param <type> $token
* @return <type>
*/
public function isNextToken($token)
{
$la = $this->lookahead;
......
<?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>.
*/
namespace Doctrine\ORM\Query\Parser;
/**
* AbstractSchemaName ::= identifier
*
* @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 AbstractSchemaName extends \Doctrine\ORM\Query\ParserRule
{
protected $_componentName = null;
public function syntax()
{
// AbstractSchemaName ::= identifier
$this->_parser->match(\Doctrine\ORM\Query\Token::T_IDENTIFIER);
$this->_componentName = $this->_parser->token['value'];
}
public function semantical()
{
// Check if we are dealing with a real Doctrine_Entity or not
if ( ! $this->_isDoctrineEntity($this->_componentName)) {
$this->_parser->semanticalError(
"Defined entity '" . $this->_componentName . "' is not a valid entity."
);
}
// Return Component Name identifier
return $this->_componentName;
}
protected function _isDoctrineEntity($componentName)
{
return class_exists($componentName);
}
}
\ No newline at end of file
<?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>.
*/
namespace Doctrine\ORM\Query\Parser;
/**
* AliasIdentificationVariable = identifier
*
* @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 AliasIdentificationVariable extends \Doctrine\ORM\Query\ParserRule
{
protected $_componentAlias = null;
public function syntax()
{
// AliasIdentificationVariable = identifier
$this->_parser->match(\Doctrine\ORM\Query\Token::T_IDENTIFIER);
$this->_componentAlias = $this->_parser->token['value'];
}
public function semantical()
{
$parserResult = $this->_parser->getParserResult();
if ($parserResult->hasQueryComponent($this->_componentAlias)) {
// We should throw semantical error if there's already a component for this alias
$queryComponent = $parserResult->getQueryComponent($this->_componentAlias);
$componentName = $queryComponent['metadata']->getClassName();
$message = "Cannot re-declare component alias '" . $this->_componentAlias . "'. "
. "It was already declared for component '" . $componentName . "'.";
$this->_parser->semanticalError($message);
}
return $this->_componentAlias;
}
}
<?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>.
*/
namespace Doctrine\ORM\Query\Parser;
/**
* CollectionValuedAssociationField ::= FieldIdentificationVariable
*
* @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 CollectionValuedAssociationField extends FieldIdentificationVariable
{
}
\ No newline at end of file
<?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>.
*/
namespace Doctrine\ORM\Query\Parser;
/**
* DeleteStatement ::= DeleteClause [WhereClause]
*
* @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 DeleteStatement extends \Doctrine\ORM\Query\ParserRule
{
public function syntax()
{
// DeleteStatement ::= DeleteClause [WhereClause]
$AST = $this->AST('DeleteStatement');
$AST->setDeleteClause($this->parse('DeleteClause'));
if ($this->_isNextToken(\Doctrine\ORM\Query\Token::T_WHERE)) {
$AST->setWhereClause($this->parse('WhereClause'));
}
// Return AST node
return $AST;
}
}
<?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>.
*/
namespace Doctrine\ORM\Query\Parser;
/**
* EmbeddedClassStateField ::= FieldIdentificationVariable
*
* @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 EmbeddedClassStateField extends FieldIdentificationVariable
{
}
\ No newline at end of file
<?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>.
*/
namespace Doctrine\ORM\Query\Parser;
/**
* FieldAliasIdentificationVariable ::= identifier
*
* @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 FieldAliasIdentificationVariable extends \Doctrine\ORM\Query\Parser
{
protected $_fieldAlias = null;
public function syntax()
{
// AliasIdentificationVariable = identifier
$this->_parser->match(\Doctrine\ORM\Query\Token::T_IDENTIFIER);
$this->_fieldAlias = $this->_parser->token['value'];
}
public function semantical()
{
$parserResult = $this->_parser->getParserResult();
if ($parserResult->hasFieldAlias($this->_fieldAlias)) {
// We should throw semantical error if there's already a field for this alias
$message = "Cannot re-declare field alias '" . $this->_fieldAlias
. "' near '" . $this->_parser->getQueryPiece($this->_parser->token) . "'.";
$this->_parser->semanticalError($message);
}
return $this->_fieldAlias;
}
}
\ No newline at end of file
<?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>.
*/
namespace Doctrine\ORM\Query\Parser;
/**
* FieldIdentificationVariable ::= identifier
*
* @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 FieldIdentificationVariable extends \Doctrine\ORM\Query\ParserRule
{
public function syntax()
{
$this->_parser->match(\Doctrine\ORM\Query\Token::T_IDENTIFIER);
return $this->_parser->token['value'];
}
}
<?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>.
*/
namespace Doctrine\ORM\Query\Parser;
/**
* FromClause ::= "FROM" IdentificationVariableDeclaration {"," IdentificationVariableDeclaration}
*
* @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 FromClause extends \Doctrine\ORM\Query\ParserRule
{
protected $_AST = null;
public function syntax()
{
// FromClause ::= "FROM" IdentificationVariableDeclaration {"," IdentificationVariableDeclaration}
$this->_AST = $this->AST('FromClause');
$this->_parser->match(\Doctrine\ORM\Query\Token::T_FROM);
$this->_AST->addIdentificationVariableDeclaration(
$this->parse('IdentificationVariableDeclaration')
);
while ($this->_isNextToken(',')) {
$this->_parser->match(',');
$this->_AST->addIdentificationVariableDeclaration(
$this->parse('IdentificationVariableDeclaration')
);
}
// Return AST node
return $this->_AST;
}
}
\ No newline at end of file
<?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>.
*/
namespace Doctrine\ORM\Query\Parser;
/**
* IdentificationVariable ::= identifier
*
* @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 IdentificationVariable extends \Doctrine\ORM\Query\ParserRule
{
protected $_componentAlias = null;
public function syntax()
{
// IdentificationVariable ::= identifier
$this->_parser->match(Doctrine_ORM_Query_Token::T_IDENTIFIER);
$this->_componentAlias = $this->_parser->token['value'];
}
public function semantical()
{
$parserResult = $this->_parser->getParserResult();
if ( ! $parserResult->hasQueryComponent($this->_componentAlias)) {
// We should throw semantical error if we cannot find the component alias
$message = "No entity related to declared alias '" . $this->_componentAlias
. "' near '" . $this->_parser->getQueryPiece($this->_parser->token) . "'.";
$this->_parser->semanticalError($message);
}
// Return Component Alias identifier
return $this->_componentAlias;
}
}
\ No newline at end of file
<?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>.
*/
namespace Doctrine\ORM\Query\Parser;
/**
* IdentificationVariableDeclaration ::= RangeVariableDeclaration [IndexBy] {JoinVariableDeclaration}*
*
* @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 IdentificationVariableDeclaration extends \Doctrine\ORM\Query\ParserRule
{
protected $_AST = null;
public function syntax()
{
// IdentificationVariableDeclaration ::= RangeVariableDeclaration [IndexBy] {JoinVariableDeclaration}*
$this->_AST = $this->AST('IdentificationVariableDeclaration');
$this->_AST->setRangeVariableDeclaration($this->parse('RangeVariableDeclaration'));
if ($this->_isNextToken(\Doctrine\ORM\Query\Token::T_INDEX)) {
$this->_AST->setIndexBy($this->parse('IndexBy'));
}
while (
$this->_isNextToken(\Doctrine\ORM\Query\Token::T_LEFT) ||
$this->_isNextToken(\Doctrine\ORM\Query\Token::T_INNER) ||
$this->_isNextToken(\Doctrine\ORM\Query\Token::T_JOIN)
) {
$this->_AST->addJoinVariableDeclaration($this->parse('JoinVariableDeclaration'));
}
}
public function semantical()
{
// If we have an INDEX BY RangeVariableDeclaration
if ($this->_AST->getIndexby() !== null) {
// Grab Range component alias
$rangeComponentAlias = $this->_AST->getRangeVariableDeclaration()->getAliasIdentificationVariable();
// Grab IndexBy component alias
$indexComponentAlias = $this->_AST->getIndexBy()->getSimpleStateFieldPathExpression()
->getIdentificationVariable();
// Check if we have same component being used in index
if ($rangeComponentAlias !== $indexComponentAlias) {
$message = "Invalid aliasing. Cannot index by '" . $indexComponentAlias
. "' inside '" . $rangeComponentAlias . "' scope.";
$this->_parser->semanticalError($message);
}
}
// Return AST node
return $this->_AST;
}
}
\ No newline at end of file
<?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>.
*/
namespace Doctrine\ORM\Query\Parser;
/**
* IndexBy ::= "INDEX" "BY" SimpleStateFieldPathExpression
*
* @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 IndexBy extends \Doctrine\ORM\Query\ParserRule
{
protected $_AST = null;
public function syntax()
{
// IndexBy ::= "INDEX" "BY" SimpleStateFieldPathExpression
$this->_AST = $this->AST('IndexBy');
$this->_parser->match(\Doctrine\ORM\Query\Token::T_INDEX);
$this->_parser->match(\Doctrine\ORM\Query\Token::T_BY);
$this->_AST->setSimpleStateFieldPathExpression($this->parse('SimpleStateFieldPathExpression'));
}
public function semantical()
{
// Retrieving required information
$parserResult = $this->_parser->getParserResult();
// Grab INDEX BY information
$componentAlias = $this->_AST->getSimpleStateFieldPathExpression()->getIdentificationVariable();
$componentFieldName = $this->_AST->getSimpleStateFieldPathExpression()->getSimpleStateField();
// Trying to retrieve related query component
try {
$queryComponent = $parserResult->getQueryComponent($componentAlias);
$classMetadata = $queryComponent['metadata'];
} catch (Doctrine_Exception $e) {
$this->_parser->semanticalError($e->getMessage());
return;
}
// The INDEX BY 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;
}
}
\ No newline at end of file
<?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>.
*/
namespace Doctrine\ORM\Query\Parser;
/**
* Join ::= ["LEFT" ["OUTER"] | "INNER"] "JOIN" JoinAssociationPathExpression
* ["AS"] AliasIdentificationVariable [("ON" | "WITH") ConditionalExpression]
*
* @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 Join extends \Doctrine\ORM\Query\ParserRule
{
protected $_AST = null;
public function syntax()
{
// Join ::= ["LEFT" ["OUTER"] | "INNER"] "JOIN" JoinAssociationPathExpression
// ["AS"] AliasIdentificationVariable [("ON" | "WITH") ConditionalExpression]
$this->_AST = $this->AST('Join');
// Check Join type
if ($this->_isNextToken(\Doctrine\ORM\Query\Token::T_LEFT)) {
$this->_parser->match(\Doctrine\ORM\Query\Token::T_LEFT);
// Possible LEFT OUTER join
if ($this->_isNextToken(\Doctrine\ORM\Query\Token::T_OUTER)) {
$this->_parser->match(\Doctrine\ORM\Query\Token::T_OUTER);
$this->_AST->setJoinType(Doctrine_ORM_Query_AST_Join::JOIN_TYPE_LEFTOUTER);
} else {
$this->_AST->setJoinType(Doctrine_ORM_Query_AST_Join::JOIN_TYPE_LEFT);
}
} else if ($this->_isNextToken(\Doctrine\ORM\Query\Token::T_INNER)) {
// Default Join type. Not need to setJoinType.
$this->_parser->match(\Doctrine\ORM\Query\Token::T_INNER);
}
$this->_parser->match(\Doctrine\ORM\Query\Token::T_JOIN);
$this->_AST->setJoinAssociationPathExpression($this->parse('JoinAssociationPathExpression'));
if ($this->_isNextToken(\Doctrine\ORM\Query\Token::T_AS)) {
$this->_parser->match(\Doctrine\ORM\Query\Token::T_AS);
}
$this->_AST->setAliasIdentificationVariable($this->parse('AliasIdentificationVariable'));
// Check Join where type
if (
$this->_isNextToken(\Doctrine\ORM\Query\Token::T_ON) ||
$this->_isNextToken(\Doctrine\ORM\Query\Token::T_WITH)
) {
// Apply matches and adjusts
if ($this->_isNextToken(\Doctrine\ORM\Query\Token::T_ON)) {
$this->_parser->match(\Doctrine\ORM\Query\Token::T_ON);
$this->_AST->setWhereType(Doctrine_ORM_Query_AST_Join::JOIN_WHERE_ON);
} else {
// Default Join where type. Not need to setWhereType.
$this->_parser->match(\Doctrine\ORM\Query\Token::T_WITH);
}
$this->_AST->setConditionalExpression($this->parse('ConditionalExpression'));
}
// Return AST node
return $this->_AST;
}
}
\ No newline at end of file
<?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>.
*/
namespace Doctrine\ORM\Query\Parser;
/**
* 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 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;
}
}
\ No newline at end of file
<?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>.
*/
namespace Doctrine\ORM\Query\Parser;
/**
* JoinCollectionValuedPathExpression ::= IdentificationVariable "." CollectionValuedAssociationField
*
* @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 JoinCollectionValuedPathExpression extends \Doctrine\ORM\Query\ParserRule
{
protected $_AST = null;
public function syntax()
{
// JoinCollectionValuedPathExpression ::= IdentificationVariable "." CollectionValuedAssociationField
$this->_AST = $this->AST('JoinCollectionValuedPathExpression');
$this->_AST->setIdentificationVariable($this->parse('IdentificationVariable'));
$this->_parser->match(\Doctrine\ORM\Query\Token::T_DOT);
$this->_AST->setCollectionValuedAssociationField($this->parse('CollectionValuedAssociationField'));
}
public function semantical()
{
$parserResult = $this->_parser->getParserResult();
$queryComponent = $parserResult->getQueryComponent($this->_AST->setIdentificationVariable());
$fieldName = $this->_AST->setCollectionValuedAssociationField();
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 collection valued association in component '"
. $componentName . "'.";
$this->_parser->semanticalError($message);
}
return $this->_AST;
}
}
\ No newline at end of file
<?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>.
*/
namespace Doctrine\ORM\Query\Parser;
/**
* 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 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
<?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>.
*/
namespace Doctrine\ORM\Query\Parser;
/**
* JoinVariableDeclaration ::= Join [IndexBy]
*
* @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 JoinVariableDeclaration extends \Doctrine\ORM\Query\ParserRule
{
protected $_AST = null;
public function syntax()
{
// JoinVariableDeclaration ::= Join [IndexBy]
$this->_AST = $this->AST('JoinVariableDeclaration');
$this->_AST->setJoin($this->parse('Join'));
if ($this->_isNextToken(\Doctrine\ORM\Query\Token::T_INDEX)) {
$this->_AST->setIndexBy($this->parse('IndexBy'));
}
}
public function semantical()
{
// If we have an INDEX BY JoinVariableDeclaration
if ($this->_AST->getIndexby() !== null) {
// Grab Join component alias
$joinComponentAlias = $this->_AST->getJoin()
->getAliasIdentificationVariable()->getComponentAlias();
// Grab IndexBy component alias
$indexComponentAlias = $this->_AST->getIndexBy()
->getSimpleStateFieldPathExpression()->getIdentificationVariable()->getComponentAlias();
// Check if we have same component being used in index
if ($joinComponentAlias !== $indexComponentAlias) {
$message = "Invalid aliasing. Cannot index by '" . $indexComponentAlias
. "' inside '" . $joinComponentAlias . "' scope.";
$this->_parser->semanticalError($message);
}
}
// Return AST node
return $this->_AST;
}
}
\ No newline at end of file
<?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>.
*/
namespace Doctrine\ORM\Query\Parser;
/**
* 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 QueryLanguage extends \Doctrine\ORM\Query\ParserRule
{
public function syntax()
{
// QueryLanguage ::= SelectStatement | UpdateStatement | DeleteStatement
switch ($this->_parser->lookahead['type']) {
case \Doctrine\ORM\Query\Token::T_SELECT:
return $this->parse('SelectStatement');
break;
case \Doctrine\ORM\Query\Token::T_UPDATE:
return $this->parse('UpdateStatement');
break;
case \Doctrine\ORM\Query\Token::T_DELETE:
return $this->parse('DeleteStatement');
break;
default:
$this->_parser->syntaxError('SELECT, UPDATE or DELETE');
break;
}
}
}
<?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>.
*/
namespace Doctrine\ORM\Query\Parser;
/**
* RangeVariableDeclaration ::= AbstractSchemaName ["AS"] AliasIdentificationVariable
*
* @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 RangeVariableDeclaration extends \Doctrine\ORM\Query\ParserRule
{
protected $_AST = null;
public function syntax()
{
// RangeVariableDeclaration ::= AbstractSchemaName ["AS"] AliasIdentificationVariable
$this->_AST = $this->AST('RangeVariableDeclaration');
$this->_AST->setAbstractSchemaName($this->parse('AbstractSchemaName'));
if ($this->_isNextToken(\Doctrine\ORM\Query\Token::T_AS)) {
$this->_parser->match(\Doctrine\ORM\Query\Token::T_AS);
}
$this->_AST->setAliasIdentificationVariable($this->parse('AliasIdentificationVariable'));
}
public function semantical()
{
$parserResult = $this->_parser->getParserResult();
$componentName = $this->_AST->getAbstractSchemaName();
$componentAlias = $this->_AST->getAliasIdentificationVariable();
// 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;
}
}
\ No newline at end of file
<?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}
*
* @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_SelectClause extends Doctrine_ORM_Query_ParserRule
{
protected $_AST = null;
protected $_selectExpressions = array();
public function syntax()
{
// SelectClause ::= "SELECT" ["DISTINCT"] SelectExpression {"," SelectExpression}
$this->_AST = $this->AST('SelectClause');
$this->_parser->match(\Doctrine\ORM\Query\Token::T_SELECT);
// Inspecting if we are in a DISTINCT query
if ($this->_isNextToken(\Doctrine\ORM\Query\Token::T_DISTINCT)) {
$this->_parser->match(\Doctrine\ORM\Query\Token::T_DISTINCT);
$this->_AST->setIsDistinct(true);
}
// Process SelectExpressions (1..N)
$this->_selectExpressions[] = $this->parse('SelectExpression');
while ($this->_isNextToken(\Doctrine\ORM\Query\Token::T_COMMA)) {
$this->_parser->match(\Doctrine\ORM\Query\Token::T_COMMA);
$this->_selectExpressions[] = $this->parse('SelectExpression');
}
}
public function semantical()
{
// We need to validate each SelectExpression
for ($i = 0, $l = count($this->_selectExpressions); $i < $l; $i++) {
$this->_AST->addSelectExpression($this->_selectExpressions[$i]->semantical());
}
// Return AST node
return $this->_AST;
}
}
\ No newline at end of file
<?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>.
*/
namespace Doctrine\ORM\Query\Parser;
/**
* SelectExpression ::= IdentificationVariable ["." "*"] | StateFieldPathExpression |
* (AggregateExpression | "(" Subselect ")") [["AS"] FieldAliasIdentificationVariable]
*
* @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 SelectExpression extends \Doctrine\ORM\Query\ParserRule
{
protected $_AST = null;
protected $_expression = null;
protected $_fieldIdentificationVariable = null;
public function syntax()
{
// SelectExpression ::= IdentificationVariable ["." "*"] | StateFieldPathExpression |
// (AggregateExpression | "(" Subselect ")") [["AS"] FieldAliasIdentificationVariable]
$this->_AST = $this->AST('SelectExpression');
// First we recognize for an IdentificationVariable (Component alias)
if ($this->_isIdentificationVariable()) {
$this->_expression = $this->parse('IdentificationVariable');
// Inspecting if we are in a ["." "*"]
if ($this->_isNextToken('.')) {
$this->_parser->match('.');
$this->_parser->match('*');
}
} else if (($isFunction = $this->_isFunction()) !== false || $this->_isSubselect()) {
$this->_expression = $this->parse($isFunction ? 'AggregateExpression' : 'Subselect');
if ($this->_isNextToken(\Doctrine\ORM\Query\Token::T_AS)) {
$this->_parser->match(\Doctrine\ORM\Query\Token::T_AS);
$this->_fieldIdentificationVariable = $this->parse('FieldAliasIdentificationVariable');
} elseif ($this->_isNextToken(\Doctrine\ORM\Query\Token::T_IDENTIFIER)) {
$this->_fieldIdentificationVariable = $this->parse('FieldAliasIdentificationVariable');
}
} else {
$this->_expression = $this->parse('StateFieldPathExpression');
}
}
public function semantical()
{
$this->_AST->setExpression($this->_expression->semantical());
if ($this->_fieldIdentificationVariable !== null) {
$this->_AST->setFieldIdentificationVariable($this->_fieldIdentificationVariable->semantical());
}
// Return AST node
return $this->_AST;
}
protected function _isIdentificationVariable()
{
// Trying to recoginize this grammar: IdentificationVariable ["." "*"]
$token = $this->_parser->lookahead;
$this->_parser->getScanner()->resetPeek();
// We have an identifier here
if ($token['type'] === \Doctrine\ORM\Query\Token::T_IDENTIFIER) {
return true;
}
return false;
}
}
\ No newline at end of file
<?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>.
*/
namespace Doctrine\ORM\Query\Parser;
/**
* SelectStatement ::= SelectClause FromClause [WhereClause] [GroupByClause] [HavingClause] [OrderByClause]
*
* @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 SelectStatement extends \Doctrine\ORM\Query\ParserRule
{
protected $_AST = null;
protected $_selectClause = null;
public function syntax()
{
// 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).
//$this->_dataHolder->set('semanticalCheck', false);
$this->_selectClause = $this->parse('SelectClause');
//$this->_dataHolder->remove('semanticalCheck');
$this->_AST->setFromClause($this->parse('FromClause'));
if ($this->_isNextToken(\Doctrine\ORM\Query\Token::T_WHERE)) {
$this->_AST->setWhereClause($this->parse('WhereClause'));
}
if ($this->_isNextToken(\Doctrine\ORM\Query\Token::T_GROUP)) {
$this->_AST->setGroupByClause($this->parse('GroupByClause'));
}
if ($this->_isNextToken(\Doctrine\ORM\Query\Token::T_HAVING)) {
$this->_AST->setHavingClause($this->parse('HavingClause'));
}
if ($this->_isNextToken(\Doctrine\ORM\Query\Token::T_ORDER)) {
$this->_AST->setOrderByClause($this->parse('OrderByClause'));
}
}
public function semantical()
{
// 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());
// Return AST node
return $this->_AST;
}
}
\ No newline at end of file
<?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>.
*/
namespace Doctrine\ORM\Query\Parser;
/**
* SimpleStateField ::= FieldIdentificationVariable
*
* @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 SimpleStateField extends \Doctrine\ORM\Query\Parser\FieldIdentificationVariable
{
}
\ No newline at end of file
<?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>.
*/
namespace Doctrine\ORM\Query\Parser;
/**
* SimpleStateFieldPathExpression ::= IdentificationVariable "." SimpleStateField
*
* @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 SimpleStateFieldPathExpression extends \Doctrine\ORM\Query\ParserRule
{
protected $_AST = null;
public function syntax()
{
// SimpleStateFieldPathExpression ::= IdentificationVariable "." SimpleStateField
$this->_AST = $this->AST('SimpleStateFieldPathExpression');
$this->_AST->setIdentificationVariable($this->parse('IdentificationVariable'));
$this->_parser->match('.');
$this->_AST->setSimpleStateField($this->parse('SimpleStateField'));
}
public function semantical()
{
$parserResult = $this->_parser->getParserResult();
$componentAlias = $this->_AST->getIdentificationVariable();
$componentFieldName = $this->_AST->getSimpleStateField();
// 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\ORM\Mapping\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;
}
}
\ No newline at end of file
<?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>.
*/
namespace Doctrine\ORM\Query\Parser;
/**
* SingleValuedAssociationField ::= FieldIdentificationVariable
*
* @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 SingleValuedAssociationField extends \Doctrine\ORM\Query\Parser\FieldIdentificationVariable
{
}
\ No newline at end of file
<?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>.
*/
namespace Doctrine\ORM\Query\Parser;
/**
* StateField ::= {EmbeddedClassStateField "."}* SimpleStateField
*
* @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.doctrine-doctrine.org
* @since 2.0
* @version $Revision$
*/
class StateField extends \Doctrine\ORM\Query\ParserRule
{
protected $_AST = null;
public function syntax()
{
// StateField ::= {EmbeddedClassStateField "."}* SimpleStateField
$this->_AST = $this->AST('StateField');
while ($this->_parser->lookahead['type'] == \Doctrine\ORM\Query\Token::T_IDENTIFIER &&
$this->_isNextToken(\Doctrine\ORM\Query\Token::T_DOT)) {
$this->_AST->addEmbeddedClassStateField($this->parse('EmbeddedClassStateField'));
$this->_parser->match(\Doctrine\ORM\Query\Token::T_DOT);
}
$this->_AST->setSimpleStateField($this->parse('SimpleStateField'));
}
}
\ No newline at end of file
<?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>.
*/
namespace Doctrine\ORM\Query\Parser;
/**
* UpdateStatement ::= UpdateClause [WhereClause]
*
* @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 UpdateStatement extends \Doctrine\ORM\Query\ParserRule
{
public function syntax()
{
// UpdateStatement ::= UpdateClause [WhereClause]
$AST = $this->AST('UpdateStatement');
$AST->setUpdateClause($this->parse('UpdateClause'));
if ($this->_isNextToken(\Doctrine\ORM\Query\Token::T_WHERE)) {
$AST->setWhereClause($this->parse('WhereClause'));
}
// Return AST node
return $AST;
}
}
\ No newline at end of file
<?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>.
*/
namespace Doctrine\ORM\Query\Production;
use \Doctrine\ORM\Query\Token;
/**
* AggregateExpression = ("AVG" | "MAX" | "MIN" | "SUM" | "COUNT") "(" ["DISTINCT"] Expression ")"
*
* @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 AggregateExpression extends Doctrine_Query_Production
{
protected $_functionName;
protected $_isDistinct;
protected $_expression;
public function syntax($paramHolder)
{
// AggregateExpression = ("AVG" | "MAX" | "MIN" | "SUM" | "COUNT") "(" ["DISTINCT"] Expression ")"
$this->_isDistinct = false;
$token = $this->_parser->lookahead;
switch ($token['type']) {
case Token::T_AVG:
case Token::T_MAX:
case Token::T_MIN:
case Token::T_SUM:
case Token::T_COUNT:
$this->_parser->match($token['type']);
$this->_functionName = strtoupper($token['value']);
break;
default:
$this->_parser->logError('AVG, MAX, MIN, SUM or COUNT');
break;
}
$this->_parser->match('(');
if ($this->_isNextToken(Token::T_DISTINCT)) {
$this->_parser->match(Token::T_DISTINCT);
$this->_isDistinct = true;
}
$this->_expression = $this->AST('Expression', $paramHolder);
$this->_parser->match(')');
}
public function semantical($paramHolder)
{
$this->_expression->semantical($paramHolder);
}
public function buildSql()
{
return $this->_functionName
. '(' . (($this->_isDistinct) ? 'DISTINCT ' : '')
. $this->_expression->buildSql()
. ')';
}
/**
* Visitor support.
*
* @param object $visitor
*/
public function accept($visitor)
{
$this->_expression->accept($visitor);
$visitor->visitAggregateExpression($this);
}
/* Getters */
public function getExpression()
{
return $this->_expression;
}
public function getFunctionName()
{
return $this->_functionName;
}
public function isDistinct()
{
return $this->_isDistinct;
}
}
\ No newline at end of file
<?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>.
*/
/**
* Atom = string | integer | float | input_parameter
*
* @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_Production_Atom extends Doctrine_Query_Production
{
protected $_type;
protected $_value;
public function syntax($paramHolder)
{
// Atom = string | integer | float | input_parameter
switch ($this->_parser->lookahead['type']) {
case Doctrine_Query_Token::T_STRING:
$this->_parser->match(Doctrine_Query_Token::T_STRING);
$this->_type = 'string';
break;
case Doctrine_Query_Token::T_INTEGER:
$this->_parser->match(Doctrine_Query_Token::T_INTEGER);
$this->_type = 'integer';
break;
case Doctrine_Query_Token::T_FLOAT:
$this->_parser->match(Doctrine_Query_Token::T_FLOAT);
$this->_type = 'float';
break;
case Doctrine_Query_Token::T_INPUT_PARAMETER:
$this->_parser->match(Doctrine_Query_Token::T_INPUT_PARAMETER);
$this->_type = 'param';
break;
default:
$this->_parser->syntaxError('string, number or parameter (? or :)');
break;
}
$this->_value = $this->_parser->token['value'];
}
public function buildSql()
{
$conn = $this->_em->getConnection();
switch ($this->_type) {
case 'param':
return $this->_value;
case 'string':
//FIXME: Remove the quotes from _value! Should the scanner do that or where?
// 'mystring' => mystring. Otherwise 'mystring' is the content (with quotes)!
// Eg: select ... from ... where f.foo = 'bar'
// => $conn->quote('bar',...), CURRENTLY: $conn->quote("'bar'",...)
// This fix looks a bit ugly or ... ? Should this happen earlier? Syntax?
// Scanner?
if (strpos($this->_value, "'") === 0) {
$this->_value = substr($this->_value, 1, strlen($this->_value) - 2);
}
return $conn->quote($this->_value, $this->_type);
default:
return $conn->quote($this->_value, $this->_type);
}
}
/**
* Visitor support.
*
* @param object $visitor
*/
public function accept($visitor)
{
$visitor->visitAtom($this);
}
/* Getters */
public function getType()
{
return $this->_type;
}
public function getValue()
{
return $this->_value;
}
}
<?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>.
*/
/**
* BetweenExpression = ["NOT"] "BETWEEN" Expression "AND" Expression
*
* @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_Production_BetweenExpression extends Doctrine_Query_Production
{
protected $_not;
protected $_fromExpression;
protected $_toExpression;
public function syntax($paramHolder)
{
// BetweenExpression = ["NOT"] "BETWEEN" Expression "AND" Expression
$this->_not = false;
if ($this->_isNextToken(Doctrine_Query_Token::T_NOT)) {
$this->_parser->match(Doctrine_Query_Token::T_NOT);
$this->_not = true;
}
$this->_parser->match(Doctrine_Query_Token::T_BETWEEN);
$this->_fromExpression = $this->AST('Expression', $paramHolder);
$this->_parser->match(Doctrine_Query_Token::T_AND);
$this->_toExpression = $this->AST('Expression', $paramHolder);
}
public function buildSql()
{
return (($this->_not) ? 'NOT ' : '') . 'BETWEEN '
. $this->_fromExpression->buildSql() . ' AND ' . $this->_toExpression->buildSql();
}
/* Getters */
public function isNot()
{
return $this->_not;
}
public function getFromExpression()
{
return $this->_fromExpression;
}
public function getToExpression()
{
return $this->_toExpression;
}
}
<?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>.
*/
/**
* ComparisonExpression = ComparisonOperator ( QuantifiedExpression | Expression | "(" Subselect ")" )
*
* @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_Production_ComparisonExpression extends Doctrine_Query_Production
{
protected $_operator;
protected $_expression;
protected $_isSubselect;
public function syntax($paramHolder)
{
// ComparisonExpression = ComparisonOperator ( QuantifiedExpression | Expression | "(" Subselect ")" )
$this->_operator = $this->AST('ComparisonOperator', $paramHolder);
if (($this->_isSubselect = $this->_isSubselect()) === true) {
$this->_parser->match('(');
$this->_expression = $this->AST('Subselect', $paramHolder);
$this->_parser->match(')');
$this->_isSubselect = true;
} else {
switch ($this->_parser->lookahead['type']) {
case Doctrine_Query_Token::T_ALL:
case Doctrine_Query_Token::T_ANY:
case Doctrine_Query_Token::T_SOME:
$this->_expression = $this->AST('QuantifiedExpression', $paramHolder);
break;
default:
$this->_expression = $this->AST('Expression', $paramHolder);
break;
}
}
}
public function buildSql()
{
return $this->_operator . ' ' . (($this->_isSubselect) ?
'(' . $this->_expression->buildSql() . ')' : $this->_expression->buildSql()
);
}
/* Getters */
public function getOperator()
{
return $this->_operator;
}
public function getExpression()
{
return $this->_expression;
}
public function isSubselect()
{
return $this->_isSubselect;
}
}
<?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>.
*/
/**
* ComparisonOperator = "=" | "<" | "<=" | "<>" | ">" | ">=" | "!="
*
* @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_Production_ComparisonOperator extends Doctrine_Query_Production
{
public function syntax($paramHolder)
{
switch ($this->_parser->lookahead['value']) {
case '=':
$this->_parser->match('=');
return '=';
break;
case '<':
$this->_parser->match('<');
$operator = '<';
if ($this->_isNextToken('=')) {
$this->_parser->match('=');
$operator .= '=';
} elseif ($this->_isNextToken('>')) {
$this->_parser->match('>');
$operator .= '>';
}
return $operator;
break;
case '>':
$this->_parser->match('>');
$operator = '>';
if ($this->_isNextToken('=')) {
$this->_parser->match('=');
$operator .= '=';
}
return $operator;
break;
case '!':
$this->_parser->match('!');
$this->_parser->match('=');
return '<>';
break;
default:
$this->_parser->syntaxError('=, <, <=, <>, >, >=, !=');
break;
}
}
}
<?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>.
*/
/**
* ConditionalExpression = ConditionalTerm {"OR" ConditionalTerm}
*
* @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_Production_ConditionalExpression extends Doctrine_Query_Production
{
protected $_conditionalTerms = array();
public function syntax($paramHolder)
{
// ConditionalExpression = ConditionalTerm {"OR" ConditionalTerm}
$this->_conditionalTerms[] = $this->AST('ConditionalTerm', $paramHolder);
while ($this->_isNextToken(Doctrine_Query_Token::T_OR)) {
$this->_parser->match(Doctrine_Query_Token::T_OR);
$this->_conditionalTerms[] = $this->AST('ConditionalTerm', $paramHolder);
}
// Optimize depth instances in AST
if (count($this->_conditionalTerms) == 1) {
return $this->_conditionalTerms[0];
}
}
public function buildSql()
{
return implode(' OR ', $this->_mapConditionalTerms());
}
protected function _mapConditionalTerms()
{
return array_map(array(&$this, '_mapConditionalTerm'), $this->_conditionalTerms);
}
protected function _mapConditionalTerm($value)
{
return $value->buildSql();
}
/* Getters */
public function getConditionalTerms()
{
return $this->_conditionalTerms;
}
}
<?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>.
*/
/**
* ConditionalFactor = ["NOT"] ConditionalPrimary
*
* @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_Production_ConditionalFactor extends Doctrine_Query_Production
{
protected $_conditionalPrimary;
public function syntax($paramHolder)
{
// ConditionalFactor = ["NOT"] ConditionalPrimary
$notFactor = false;
if ($this->_isNextToken(Doctrine_Query_Token::T_NOT)) {
$this->_parser->match(Doctrine_Query_Token::T_NOT);
$notFactor = true;
}
$this->_conditionalPrimary = $this->AST('ConditionalPrimary', $paramHolder);
// Optimize depth instances in AST
if ( ! $notFactor) {
return $this->_conditionalPrimary;
}
}
public function buildSql()
{
// Do not need to check $notFactor. It'll be always present if we have this instance.
return 'NOT ' . $this->_conditionalPrimary->buildSql();
}
/* Getters */
public function getConditionalPrimary()
{
return $this->_conditionalPrimary;
}
}
<?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>.
*/
/**
* ConditionalPrimary = SimpleConditionalExpression | "(" ConditionalExpression ")"
*
* @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_Production_ConditionalPrimary extends Doctrine_Query_Production
{
protected $_conditionalExpression;
public function syntax($paramHolder)
{
// ConditionalPrimary = SimpleConditionalExpression | "(" ConditionalExpression ")"
if ( ! $this->_isConditionalExpression()) {
return $this->AST('SimpleConditionalExpression', $paramHolder);
}
$this->_parser->match('(');
$this->_conditionalExpression = $this->AST('ConditionalExpression', $paramHolder);
$this->_parser->match(')');
}
public function buildSql()
{
return '(' . $this->_conditionalExpression->buildSql() . ')';
}
protected 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 '>':
case '!':
return true;
}
break;
}
}
}
return false;
}
/* Getters */
public function getConditionalExpression()
{
return $this->_conditionalExpression;
}
}
<?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>.
*/
/**
* ConditionalTerm = ConditionalFactor {"AND" ConditionalFactor}
*
* @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_Production_ConditionalTerm extends Doctrine_Query_Production
{
protected $_conditionalFactors = array();
public function syntax($paramHolder)
{
// ConditionalTerm = ConditionalFactor {"AND" ConditionalFactor}
$this->_conditionalFactors[] = $this->AST('ConditionalFactor', $paramHolder);
while ($this->_isNextToken(Doctrine_Query_Token::T_AND)) {
$this->_parser->match(Doctrine_Query_Token::T_AND);
$this->_conditionalFactors[] = $this->AST('ConditionalFactor', $paramHolder);
}
// Optimize depth instances in AST
if (count($this->_conditionalFactors) == 1) {
return $this->_conditionalFactors[0];
}
}
public function buildSql()
{
return implode(' AND ', $this->_mapConditionalFactors());
}
protected function _mapConditionalFactors()
{
return array_map(array(&$this, '_mapConditionalFactor'), $this->_conditionalFactors);
}
protected function _mapConditionalFactor($value)
{
return $value->buildSql();
}
/* Getters */
public function getConditionalFactors()
{
return $this->_conditionalFactors;
}
}
<?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>.
*/
/**
* DeleteClause = "DELETE" ["FROM"] VariableDeclaration
*
* @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_Production_DeleteClause extends Doctrine_Query_Production
{
protected $_variableDeclaration;
public function syntax($paramHolder)
{
// DeleteClause = "DELETE" ["FROM"] VariableDeclaration
$this->_parser->match(Doctrine_Query_Token::T_DELETE);
if ($this->_isNextToken(Doctrine_Query_Token::T_FROM)) {
$this->_parser->match(Doctrine_Query_Token::T_FROM);
}
$this->_variableDeclaration = $this->AST('VariableDeclaration', $paramHolder);
}
public function buildSql()
{
return 'DELETE FROM ' . $this->_variableDeclaration->buildSql();
}
/**
* Visitor support
*
* @param object $visitor
*/
public function accept($visitor)
{
$this->_variableDeclaration->accept($visitor);
$visitor->visitDeleteClause($this);
}
/* Getters */
public function getVariableDeclaration()
{
return $this->_variableDeclaration;
}
}
<?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_Production_DeleteStatement extends Doctrine_Query_Production
{
protected $_deleteClause;
protected $_whereClause;
public function syntax($paramHolder)
{
// DeleteStatement = DeleteClause [WhereClause]
$this->_deleteClause = $this->AST('DeleteClause', $paramHolder);
if ($this->_isNextToken(Doctrine_Query_Token::T_WHERE)) {
$this->_whereClause = $this->AST('WhereClause', $paramHolder);
}
}
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');
}
/**
* Visitor support
*
* @param object $visitor
*/
public function accept($visitor)
{
$this->_deleteClause->accept($visitor);
if ($this->_whereClause) {
$this->_whereClause->accept($visitor);
}
$visitor->visitDeleteStatement($this);
}
/* Getters */
public function getDeleteClause()
{
return $this->_deleteClause;
}
public function getWhereClause()
{
return $this->_whereClause;
}
}
<?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>.
*/
/**
* ExistsExpression = "EXISTS" "(" Subselect ")"
*
* @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_Production_ExistsExpression extends Doctrine_Query_Production
{
protected $_subselect;
public function syntax($paramHolder)
{
// ExistsExpression = "EXISTS" "(" Subselect ")"
$this->_parser->match(Doctrine_Query_Token::T_EXISTS);
$this->_parser->match('(');
$this->_subselect = $this->AST('Subselect', $paramHolder);
$this->_parser->match(')');
}
public function buildSql()
{
return 'EXISTS (' . $this->_subselect->buildSql() . ')';
}
/* Getters */
public function getSubselect()
{
return $this->_subselect;
}
}
<?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>.
*/
/**
* Expression = Term {("+" | "-") Term}
*
* @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_Production_Expression extends Doctrine_Query_Production
{
protected $_terms = array();
public function syntax($paramHolder)
{
// Expression = Term {("+" | "-") Term}
$this->_terms[] = $this->AST('Term', $paramHolder);
while ($this->_isNextToken('+') || $this->_isNextToken('-')) {
if ($this->_isNextToken('+')) {
$this->_parser->match('+');
$this->_terms[] = '+';
} else{
$this->_parser->match('-');
$this->_terms[] = '-';
}
$this->_terms[] = $this->AST('Term', $paramHolder);
}
// Optimize depth instances in AST
if (count($this->_terms) == 1) {
return $this->_terms[0];
}
}
public function semantical($paramHolder)
{
for ($i = 0, $l = count($this->_terms); $i < $l; $i++) {
if ($this->_terms[$i] != '+' && $this->_terms[$i] != '-') {
$this->_terms[$i]->semantical($paramHolder);
}
}
}
public function buildSql()
{
return implode(' ', $this->_mapTerms());
}
protected function _mapTerms()
{
return array_map(array(&$this, '_mapTerm'), $this->_terms);
}
protected function _mapTerm($value)
{
return (is_string($value) ? $value : $value->buildSql());
}
/* Getters */
public function getTerms()
{
return $this->_terms;
}
}
<?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>.
*/
namespace Doctrine\Query\Production;
/**
* Factor = [("+" | "-")] Primary
*
* @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 Factor extends \Doctrine\Query\Production
{
protected $_type;
protected $_primary;
public function syntax($paramHolder)
{
// Factor = [("+" | "-")] Primary
if ($this->_isNextToken('+')) {
$this->_parser->match('+');
$this->_type = '+';
} elseif ($this->_isNextToken('-')) {
$this->_parser->match('-');
$this->_type = '-';
}
$this->_primary = $this->AST('Primary', $paramHolder);
// Optimize depth instances in AST
if ($this->_type === null) {
return $this->_primary;
}
}
public function semantical($paramHolder)
{
$this->_primary->semantical($paramHolder);
}
public function buildSql()
{
return $this->_type . ' ' . $this->_primary->buildSql();
}
/**
* Visitor support
*
* @param object $visitor
*/
public function accept($visitor)
{
$this->_primary->accept($visitor);
$visitor->visitFactor($this);
}
/* Getters */
public function getType()
{
return $this->_type;
}
public function getPrimary()
{
return $this->_primary;
}
}
\ No newline at end of file
<?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_Production_FieldIdentificationVariable extends Doctrine_Query_Production
{
protected $_fieldAlias;
protected $_columnAlias;
public function syntax($paramHolder)
{
// FieldIdentificationVariable = identifier
$this->_parser->match(Doctrine_Query_Token::T_IDENTIFIER);
$this->_fieldAlias = $this->_parser->token['value'];
}
public function semantical($paramHolder)
{
$parserResult = $this->_parser->getParserResult();
if ($parserResult->hasQueryField($this->_fieldAlias)) {
// We should throw semantical error if there's already a component for this alias
$fieldName = $parserResult->getQueryField($this->_fieldAlias);
$message = "Cannot re-declare field alias '{$this->_fieldAlias}'"
. "for '".$paramHolder->get('fieldName')."'.";
$this->_parser->semanticalError($message);
}
// Now we map it in queryComponent
$componentAlias = Doctrine_Query_Production::DEFAULT_QUERYCOMPONENT;
$queryComponent = $parserResult->getQueryComponent($componentAlias);
$idx = count($queryComponent['scalar']);
$queryComponent['scalar'][$idx] = $this->_fieldAlias;
$parserResult->setQueryComponent($componentAlias, $queryComponent);
// And also in field aliases
$parserResult->setQueryField($queryComponent['scalar'][$idx], $idx);
// Build the column alias
$this->_columnAlias = $parserResult->getTableAliasFromComponentAlias($componentAlias)
. Doctrine_Query_Production::SQLALIAS_SEPARATOR . $idx;
}
/* Getters */
public function getFieldAlias()
{
return $this->_fieldAlias;
}
public function getColumnAlias()
{
return $this->_columnAlias;
}
}
<?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 2.0
* @version $Revision$
*/
class Doctrine_Query_Production_FromClause extends Doctrine_Query_Production
{
protected $_identificationVariableDeclaration = array();
public function syntax($paramHolder)
{
// FromClause = "FROM" IdentificationVariableDeclaration {"," IdentificationVariableDeclaration}
$this->_parser->match(Doctrine_Query_Token::T_FROM);
$this->_identificationVariableDeclaration[] = $this->AST('IdentificationVariableDeclaration', $paramHolder);
while ($this->_isNextToken(',')) {
$this->_parser->match(',');
$this->_identificationVariableDeclaration[] = $this->AST('IdentificationVariableDeclaration', $paramHolder);
}
}
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->_identificationVariableDeclaration);
}
protected function _mapIdentificationVariableDeclaration($value)
{
return $value->buildSql();
}
/* Getters */
public function getIdentificationVariableDeclarations()
{
return $this->_identificationVariableDeclaration;
}
}
<?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>.
*/
/**
* Function = identifier "(" [Expression {"," Expression}] ")"
*
* @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_Production_Function extends Doctrine_Query_Production
{
protected $_functionName;
protected $_arguments = array();
public function syntax($paramHolder)
{
// Function = identifier "(" [Expression {"," Expression}] ")"
$this->_parser->match(Doctrine_Query_Token::T_IDENTIFIER);
$this->_functionName = $this->_parser->token['value'];
$this->_parser->match('(');
if ( ! $this->_isNextToken(')')) {
$this->_arguments[] = $this->AST('Expression', $paramHolder);
while ($this->_isNextToken(',')) {
$this->_parser->match(',');
$this->_arguments[] = $this->AST('Expression', $paramHolder);
}
}
$this->_parser->match(')');
}
public function buildSql()
{
return $this->_functionName . '(' . implode(', ', $this->_mapArguments()) . ')';
}
protected function _mapArguments()
{
return array_map(array(&$this, '_mapArgument'), $this->_arguments);
}
protected function _mapArgument($value)
{
return $value->buildSql();
}
/**
* Visitor support
*
* @param object $visitor
*/
public function accept($visitor)
{
foreach ($this->_arguments as $argument) {
$argument->accept($visitor);
}
$visitor->visitFunction($this);
}
/* Getters */
public function getFunctionName()
{
return $this->_functionName;
}
public function getArguments()
{
return $this->_arguments;
}
}
<?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>.
*/
/**
* GroupByClause = "GROUP" "BY" GroupByItem {"," GroupByItem}
*
* @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_Production_GroupByClause extends Doctrine_Query_Production
{
protected $_groupByItems = array();
public function syntax($paramHolder)
{
$this->_parser->match(Doctrine_Query_Token::T_GROUP);
$this->_parser->match(Doctrine_Query_Token::T_BY);
$this->_groupByItems[] = $this->AST('GroupByItem', $paramHolder);
while ($this->_isNextToken(',')) {
$this->_parser->match(',');
$this->_groupByItems[] = $this->AST('GroupByItem', $paramHolder);
}
}
public function buildSql()
{
return 'GROUP BY ' . implode(', ', $this->_mapGroupByItems());
}
protected function _mapGroupByItems()
{
return array_map(array(&$this, '_mapGroupByItem'), $this->_groupByItems);
}
protected function _mapGroupByItem($value)
{
return $value->buildSql();
}
/**
* Visitor support
*
* @param object $visitor
*/
public function accept($visitor)
{
foreach ($this->_groupByItems as $item) {
$item->accept($visitor);
}
$visitor->visitGroupByClause($this);
}
/* Getters */
public function getGroupByItems()
{
return $this->_groupByItems;
}
}
<?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>.
*/
/**
* OrderByItem = PathExpression
*
* @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_Production_GroupByItem extends Doctrine_Query_Production
{
public function syntax($paramHolder)
{
return $this->AST('PathExpression', $paramHolder);
}
/**
* Visitor support
*
* @param object $visitor
*/
public function accept($visitor)
{
$visitor->visitGroupByItem($this);
}
}
<?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>.
*/
/**
* HavingClause = "HAVING" ConditionalExpression
*
* @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_Production_HavingClause extends Doctrine_Query_Production
{
protected $_conditionalExpression;
public function syntax($paramHolder)
{
// HavingClause = "HAVING" ConditionalExpression
$this->_parser->match(Doctrine_Query_Token::T_HAVING);
$this->_conditionalExpression = $this->AST('ConditionalExpression', $paramHolder);
}
public function buildSql()
{
return 'HAVING ' . $this->_conditionalExpression->buildSql();
}
/**
* Visitor support
*
* @param object $visitor
*/
public function accept($visitor)
{
$this->_conditionalExpression->accept($visitor);
$visitor->visitHavingClause($this);
}
/* Getters */
public function getConditionalExpression()
{
return $this->_conditionalExpression;
}
}
<?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_Production_IdentificationVariable extends Doctrine_Query_Production
{
protected $_componentAlias;
public function syntax($paramHolder)
{
// IdentificationVariable = identifier
$this->_parser->match(Doctrine_Query_Token::T_IDENTIFIER);
$this->_componentAlias = $this->_parser->token['value'];
}
public function semantical($paramHolder)
{
$parserResult = $this->_parser->getParserResult();
if ($parserResult->hasQueryComponent($this->_componentAlias)) {
// We should throw semantical error if there's already a component for this alias
$queryComponent = $parserResult->getQueryComponent($this->_componentAlias);
$componentName = $queryComponent['metadata']->getClassName();
$message = "Cannot re-declare component alias '{$this->_componentAlias}'"
. "for '".$paramHolder->get('componentName')."'. It was already declared for "
. "component '{$componentName}'.";
$this->_parser->semanticalError($message);
}
return $this->_componentAlias;
}
}
<?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 2.0
* @version $Revision$
*/
class Doctrine_Query_Production_IdentificationVariableDeclaration extends Doctrine_Query_Production
{
protected $_rangeVariableDeclaration;
protected $_indexBy;
protected $_joinVariableDeclarations = array();
public function syntax($paramHolder)
{
$this->_rangeVariableDeclaration = $this->AST('RangeVariableDeclaration', $paramHolder);
if ($this->_isNextToken(Doctrine_Query_Token::T_INDEX)) {
$paramHolder->set('componentAlias', $this->_rangeVariableDeclaration->getIdentificationVariable());
$this->_indexBy = $this->AST('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->_joinVariableDeclarations[] = $this->AST('JoinVariableDeclaration', $paramHolder);
}
}
public function buildSql()
{
$str = $this->_rangeVariableDeclaration->buildSql();
for ($i = 0, $l = count($this->_joinVariableDeclarations); $i < $l; $i++) {
$str .= ' ' . $this->_joinVariableDeclarations[$i]->buildSql();
}
return $str;
}
/* Getters */
public function getRangeVariableDeclaration()
{
return $this->_rangeVariableDeclaration;
}
public function getIndexBy()
{
return $this->_indexBy;
}
public function getJoinVariableDeclarations()
{
return $this->_joinVariableDeclarations;
}
}
<?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>.
*/
/**
* InExpression = ["NOT"] "IN" "(" (Atom {"," Atom} | Subselect) ")"
*
* @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_Production_InExpression extends Doctrine_Query_Production
{
protected $_not;
protected $_subselect;
protected $_atoms = array();
public function syntax($paramHolder)
{
// InExpression = ["NOT"] "IN" "(" (Atom {"," Atom} | Subselect) ")"
$this->_not = false;
if ($this->_isNextToken(Doctrine_Query_Token::T_NOT)) {
$this->_parser->match(Doctrine_Query_Token::T_NOT);
$this->_not = true;
}
$this->_parser->match(Doctrine_Query_Token::T_IN);
$this->_parser->match('(');
if ($this->_isNextToken(Doctrine_Query_Token::T_SELECT)) {
$this->_subselect = $this->AST('Subselect', $paramHolder);
} else {
$this->_atoms[] = $this->AST('Atom', $paramHolder);
while ($this->_isNextToken(',')) {
$this->_parser->match(',');
$this->_atoms[] = $this->AST('Atom', $paramHolder);
}
}
$this->_parser->match(')');
}
public function buildSql()
{
return (($this->_not) ? 'NOT ' : '') . 'IN ('
. (($this->_subselect !== null) ? $this->_subselect->buildSql() : implode(', ', $this->_mapAtoms()))
. ')';
}
protected function _mapAtoms()
{
return array_map(array(&$this, '_mapAtom'), $this->_atoms);
}
protected function _mapAtom($value)
{
return $value->buildSql();
}
/* Getters */
public function isNot()
{
return $this->_not;
}
public function getSubselect()
{
return $this->_subselect;
}
public function getAtoms()
{
return $this->_atoms;
}
}
<?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" 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_Production_IndexBy extends Doctrine_Query_Production
{
protected $_componentAlias;
protected $_fieldName;
public function syntax($paramHolder)
{
$this->_componentAlias = $paramHolder->get('componentAlias');
$this->_parser->match(Doctrine_Query_Token::T_INDEX);
$this->_parser->match(Doctrine_Query_Token::T_BY);
$this->_parser->match(Doctrine_Query_Token::T_IDENTIFIER);
$this->_fieldName = $this->_parser->token['value'];
}
public function semantical($paramHolder)
{
$parserResult = $this->_parser->getParserResult();
//echo "Component alias: " . $this->_componentAlias . "\n";
//echo "Has query component: " . ($parserResult->hasQueryComponent($this->_componentAlias) ? "TRUE" : "FALSE") . "\n";
//$qc = $parserResult->getQueryComponents();
//$qc = array_keys($qc);
//echo "Query Components: " . var_export($qc, true) . "\n";
try {
$queryComponent = $parserResult->getQueryComponent($this->_componentAlias);
$classMetadata = $queryComponent['metadata'];
} catch (Doctrine_Exception $e) {
$this->_parser->semanticalError($e->getMessage());
return;
}
if ($classMetadata instanceof Doctrine_ClassMetadata && ! $classMetadata->hasField($this->_fieldName)) {
$this->_parser->semanticalError(
"Cannot use key mapping. Field '" . $this->_fieldName . "' " .
"does not exist in component '" . $classMetadata->getClassName() . "'.",
$this->_parser->token
);
}
// The INDEXBY field must be either the (primary && not part of composite pk) || (unique && notnull)
$columnMapping = $classMetadata->getFieldMapping($this->_fieldName);
if ( ! $classMetadata->isIdentifier($this->_fieldName) && ! $classMetadata->isUniqueField($this->_fieldName) && ! $classMetadata->isNotNull($this->_fieldName)) {
$this->_parser->semanticalError(
"Field '" . $this->_fieldName . "' of component '" . $classMetadata->getClassName() .
"' must be unique and notnull to be used as index.",
$this->_parser->token
);
}
if ($classMetadata->isIdentifier($this->_fieldName) && $classMetadata->isIdentifierComposite()) {
$this->_parser->semanticalError(
"Field '" . $this->_fieldName . "' 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'] = $this->_fieldName;
$parserResult->setQueryComponent($this->_componentAlias, $queryComponent);
}
public function buildSql()
{
return '';
}
/* Getters */
public function getComponentAlias()
{
return $this->_componentAlias;
}
public function getFieldName()
{
return $this->_fieldName;
}
}
<?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>.
*/
/**
* Join = ["LEFT" | "INNER"] "JOIN" RangeVariableDeclaration [("ON" | "WITH") ConditionalExpression]
*
* @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_Production_Join extends Doctrine_Query_Production
{
protected $_joinType;
protected $_rangeVariableDeclaration;
protected $_whereType;
protected $_conditionalExpression;
public function syntax($paramHolder)
{
$this->_joinType = 'INNER';
$this->_whereType = 'WITH';
if ($this->_isNextToken(Doctrine_Query_Token::T_LEFT)) {
$this->_parser->match(Doctrine_Query_Token::T_LEFT);
$this->_joinType = 'LEFT';
} else if ($this->_isNextToken(Doctrine_Query_Token::T_INNER)) {
$this->_parser->match(Doctrine_Query_Token::T_INNER);
}
$this->_parser->match(Doctrine_Query_Token::T_JOIN);
$this->_rangeVariableDeclaration = $this->AST('RangeVariableDeclaration', $paramHolder);
if ($this->_isNextToken(Doctrine_Query_Token::T_ON)) {
$this->_parser->match(Doctrine_Query_Token::T_ON);
$this->_whereType = 'ON';
$this->_conditionalExpression = $this->AST('ConditionalExpression', $paramHolder);
} else if ($this->_isNextToken(Doctrine_Query_Token::T_WITH)) {
$this->_parser->match(Doctrine_Query_Token::T_WITH);
$this->_conditionalExpression = $this->AST('ConditionalExpression', $paramHolder);
}
}
public function buildSql()
{
$parserResult = $this->_parser->getParserResult();
// Get the connection for the component
$conn = $this->_em->getConnection();
$sql = $this->_joinType . ' JOIN ' . $this->_rangeVariableDeclaration->buildSql();
$conditionExpression = isset($this->_conditionExpression)
? $this->_conditionExpression->buildSql() : '';
if ($this->_whereType == 'ON') {
return $sql . ' ON ' . $conditionExpression;
}
// We need to build the join conditions. Retrieving AssociationMapping
$queryComponent = $this->_rangeVariableDeclaration->getQueryComponent();
$association = $queryComponent['relation'];
$joinColumns = array();
if ($association->isOneToMany() || $association->isOneToOne()) {
if ($association->isInverseSide()) {
// joinColumns are found on the other (owning) side
$targetClass = $this->_em->getClassMetadata($association->getTargetEntityName());
$joinColumns = $targetClass->getAssociationMapping($association->getMappedByFieldName())
->getTargetToSourceKeyColumns();
} else {
$joinColumns = $association->getSourceToTargetKeyColumns();
}
} else {
//TODO: many-many
}
$relationConditionExpression = '';
// We have an array('localColumn' => 'foreignColumn', ...) here
foreach ($joinColumns as $localColumn => $foreignColumn) {
// leftExpression = rightExpression
// Defining leftExpression
$leftExpression = $conn->quoteIdentifier(
$parserResult->getTableAliasFromComponentAlias($queryComponent['parent']) . '.' . $localColumn
);
// Defining rightExpression
$rightExpression = $conn->quoteIdentifier(
$parserResult->getTableAliasFromComponentAlias(
$this->_rangeVariableDeclaration->getIdentificationVariable()
) . '.' . $foreignColumn
);
// Building the relation
$relationConditionExpression .= (($relationConditionExpression != '') ? ' AND ' : '')
. $leftExpression . ' = ' . $rightExpression;
}
$sql .= ' ON ' . $relationConditionExpression;
$sql .= empty($conditionExpression) ? '' : ' AND (' . $conditionExpression . ')';
return $sql;
}
/* Getters */
public function getJoinType()
{
return $this->_joinType;
}
public function getRangeVariableDeclaration()
{
return $this->_rangeVariableDeclaration;
}
public function getWhereType()
{
return $this->_whereType;
}
public function getConditionalExpression()
{
return $this->_conditionalExpression;
}
}
<?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>.
*/
/**
* JoinVariableDeclaration = Join [IndexBy]
*
* @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_Production_JoinVariableDeclaration extends Doctrine_Query_Production
{
protected $_join;
protected $_indexBy;
public function syntax($paramHolder)
{
$this->_join = $this->AST('Join', $paramHolder);
if ($this->_isNextToken(Doctrine_Query_Token::T_INDEX)) {
$paramHolder->set('componentAlias', $this->_join->getRangeVariableDeclaration()->getIdentificationVariable());
$this->_indexBy = $this->AST('IndexBy', $paramHolder);
$paramHolder->remove('componentAlias');
}
}
public function buildSql()
{
return $this->_join->buildSql() . (isset($this->_indexby) ? $this->_indexby->buildSql() . ' ' : '');
}
/* Getters */
public function getJoin()
{
return $this->_join;
}
public function getIndexBy()
{
return $this->_indexBy;
}
}
\ No newline at end of file
<?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>.
*/
/**
* LikeExpression = ["NOT"] "LIKE" Expression ["ESCAPE" string]
*
* @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_Production_LikeExpression extends Doctrine_Query_Production
{
protected $_not;
protected $_expression;
protected $_escapeString;
public function syntax($paramHolder)
{
// LikeExpression = ["NOT"] "LIKE" Expression ["ESCAPE" string]
$this->_escapeString = null;
$this->_not = false;
if ($this->_isNextToken(Doctrine_Query_Token::T_NOT)) {
$this->_parser->match(Doctrine_Query_Token::T_NOT);
$this->_not = true;
}
$this->_parser->match(Doctrine_Query_Token::T_LIKE);
$this->_expression = $this->AST('Expression', $paramHolder);
if ($this->_isNextToken(Doctrine_Query_Token::T_ESCAPE)) {
$this->_parser->match(Doctrine_Query_Token::T_ESCAPE);
$this->_parser->match(Doctrine_Query_Token::T_STRING);
$this->_escapeString = $this->_parser->token['value'];
}
}
public function buildSql()
{
return (($this->_not) ? 'NOT ' : '') . 'LIKE ' . $this->_expression->buildSql()
. (($this->_escapeString !== null) ? ' ESCAPE ' . $this->_escapeString : '');
}
/* Getters */
public function isNot()
{
return $this->_not;
}
public function getExpression()
{
return $this->_expression;
}
public function getEscapeString()
{
return $this->_escapeString;
}
}
<?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" integer
*
* @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_Production_LimitClause extends Doctrine_Query_Production
{
protected $_limit;
public function execute(array $params = array())
{
$this->_parser->match(Doctrine_Query_Token::T_LIMIT);
$this->_parser->match(Doctrine_Query_Token::T_INTEGER);
$this->_limit = $this->_parser->token['value'];
return $this;
}
/**
* Visitor support
*
* @param object $visitor
*/
public function accept($visitor)
{
$visitor->visitLimitClause($this);
}
/* Getters */
public function getLimit()
{
return $this->_limit;
}
}
<?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>.
*/
/**
* NullComparisonExpression = "IS" ["NOT"] "NULL"
*
* @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_Production_NullComparisonExpression extends Doctrine_Query_Production
{
protected $_not;
public function syntax($paramHolder)
{
$this->_not = false;
$this->_parser->match(Doctrine_Query_Token::T_IS);
if ($this->_isNextToken(Doctrine_Query_Token::T_NOT)) {
$this->_parser->match(Doctrine_Query_Token::T_NOT);
$this->_not = true;
}
$this->_parser->match(Doctrine_Query_Token::T_NULL);
}
public function buildSql()
{
return 'IS ' . (($this->_not) ? 'NOT ' : '') . 'NULL';
}
/* Getters */
public function isNot()
{
return $this->_not;
}
}
<?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" integer
*
* @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_Production_OffsetClause extends Doctrine_Query_Production
{
protected $_offset;
public function execute(array $params = array())
{
$this->_parser->match(Doctrine_Query_Token::T_OFFSET);
$this->_parser->match(Doctrine_Query_Token::T_INTEGER);
$this->_offset = $this->_parser->token['value'];
return $this;
}
public function buildSql()
{
// [TODO] How to deal with different DBMS here?
// The responsability to apply the limit-subquery is from
// SelectStatement, not this object's one.
return ' OFFSET ' . $this->_offset;
}
/**
* Visitor support
*
* @param object $visitor
*/
public function accept($visitor)
{
$visitor->visitOffsetClause($this);
}
/* Getters */
public function getOffset()
{
return $this->_offset;
}
}
<?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>.
*/
/**
* OrderByClause = "ORDER" "BY" OrderByItem {"," OrderByItem}
*
* @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_Production_OrderByClause extends Doctrine_Query_Production
{
protected $_orderByItems = array();
public function syntax($paramHolder)
{
$this->_parser->match(Doctrine_Query_Token::T_ORDER);
$this->_parser->match(Doctrine_Query_Token::T_BY);
$this->_orderByItems[] = $this->AST('OrderByItem', $paramHolder);
while ($this->_isNextToken(',')) {
$this->_parser->match(',');
$this->_orderByItems[] = $this->AST('OrderByItem', $paramHolder);
}
}
public function buildSql()
{
$str = 'ORDER BY ';
for ($i = 0, $l = count($this->_orderByItems); $i < $l; $i++) {
if ($i != 0) {
$str .= ', ';
}
$str .= ( $this->_orderByItems[$i] instanceof Doctrine_Query_Production ) ?
$this->_orderByItems[$i]->buildSql() : $this->_orderByItems[$i];
}
return $str;
}
/**
* Visitor support
*
* @param object $visitor
*/
public function accept($visitor)
{
foreach ($this->_orderByItems as $item) {
$item->accept($visitor);
}
$visitor->visitOrderByClause($this);
}
/* Getters */
public function getOrderByItems()
{
return $this->_orderByItems;
}
}
<?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>.
*/
/**
* OrderByItem = Expression ["ASC" | "DESC"]
*
* @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_Production_OrderByItem extends Doctrine_Query_Production
{
protected $_expression;
protected $_orderType;
public function syntax($paramHolder)
{
$this->_expression = $this->AST('Expression', $paramHolder);
$this->_orderType = 'ASC';
if ($this->_isNextToken(Doctrine_Query_Token::T_ASC)) {
$this->_parser->match(Doctrine_Query_Token::T_ASC);
} elseif ($this->_isNextToken(Doctrine_Query_Token::T_DESC)) {
$this->_parser->match(Doctrine_Query_Token::T_DESC);
$this->_orderType = 'DESC';
}
}
public function buildSql()
{
return $this->_expression->buildSql() . ' ' . $this->_orderType;
}
/**
* Visitor support
*
* @param object $visitor
*/
public function accept($visitor)
{
$this->_expression->accept($visitor);
$visitor->visitOrderByItem($this);
}
/* Getters */
public function getExpression()
{
return $this->_expression;
}
public function getOrderType()
{
return $this->_orderType;
}
}
<?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>.
*/
/**
* PathExpression = identifier { "." 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_Production_PathExpression extends Doctrine_Query_Production
{
protected $_identifiers = array();
protected $_fieldName;
protected $_componentAlias;
public function syntax($paramHolder)
{
$this->_parser->match(Doctrine_Query_Token::T_IDENTIFIER);
$this->_identifiers[] = $this->_parser->token['value'];
while ($this->_isNextToken('.')) {
$this->_parser->match('.');
$this->_parser->match(Doctrine_Query_Token::T_IDENTIFIER);
$this->_identifiers[] = $this->_parser->token['value'];
}
$this->_fieldName = array_pop($this->_identifiers);
}
public function semantical($paramHolder)
{
$parserResult = $this->_parser->getParserResult();
$classMetadata = null;
if (($l = count($this->_identifiers)) == 0) {
// No metadata selection until now. We might need to deal with:
// DELETE FROM Obj alias WHERE field = X
$queryComponents = $parserResult->getQueryComponents();
// Check if we have more than one queryComponent defined
if (count($queryComponents) != 2) {
$this->_parser->semanticalError("Undefined component alias for field '{$this->_fieldName}'", $this->_parser->token);
}
// Retrieve ClassMetadata
$k = array_keys($queryComponents);
$this->_componentAlias = $k[1];
$classMetadata = $queryComponents[$this->_componentAlias]['metadata'];
} else {
$this->_componentAlias = $path = $this->_identifiers[0];
$queryComponent = $parserResult->getQueryComponent($path);
// We should have a semantical error if the queryComponent does not exists yet
if ($queryComponent === null) {
$this->_parser->semanticalError("Undefined component alias for '{$path}'", $this->_parser->token);
}
// Initializing ClassMetadata
$classMetadata = $queryComponent['metadata'];
// Looping through relations
for ($i = 1; $i < $l; $i++) {
$relationName = $this->_identifiers[$i];
$path .= '.' . $relationName;
if ( ! $classMetadata->hasAssociation($relationName)) {
$className = $classMetadata->getClassName();
$this->_parser->semanticalError(
"Relation '{$relationName}' does not exist in component '{$className}' when trying to get the path '{$path}'",
$this->_parser->token
);
}
// We inspect for queryComponent of relations, since we are using them
if ( ! $parserResult->hasQueryComponent($path)) {
$this->_parser->semanticalError("Cannot use the path '{$path}' without defining it in FROM.", $this->_parser->token);
}
// Assigning new componentAlias, queryComponent and classMetadata
$this->_componentAlias = $path;
$queryComponent = $parserResult->getQueryComponent($path);
$classMetadata = $queryComponent['metadata'];
}
}
// Now we inspect for field existance
if ( ! $classMetadata->hasField($this->_fieldName)) {
$className = $classMetadata->getClassName();
$this->_parser->semanticalError("Field '{$this->_fieldName}' does not exist in component '{$className}'", $this->_parser->token);
}
}
public function buildSql()
{
// Basic handy variables
$parserResult = $this->_parser->getParserResult();
// Retrieving connection
$conn = $this->_em->getConnection();
// Looking for queryComponent to fetch
$queryComponent = $parserResult->getQueryComponent($this->_componentAlias);
// Generating the SQL piece
$str = $parserResult->getTableAliasFromComponentAlias($this->_componentAlias) . '.'
. $queryComponent['metadata']->getColumnName($this->_fieldName);
return $conn->quoteIdentifier($str);
}
/**
* Visitor support
*
* @param object $visitor
*/
public function accept($visitor)
{
$visitor->visitPathExpression($this);
}
/* Getters */
public function getIdentifiers()
{
return $this->_identifiers;
}
public function getFieldName()
{
return $this->_fieldName;
}
public function getComponentAlias()
{
return $this->_componentAlias;
}
}
<?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>.
*/
/**
* PathExpressionEndingWithAsterisk = {identifier "."} "*"
*
* @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 2.0
* @version $Revision$
*/
class Doctrine_Query_Production_PathExpressionEndingWithAsterisk extends Doctrine_Query_Production
{
protected $_identifiers = array();
protected $_queryComponent;
public function syntax($paramHolder)
{
// PathExpressionEndingWithAsterisk = {identifier "."} "*"
while ($this->_isNextToken(Doctrine_Query_Token::T_IDENTIFIER)) {
$this->_parser->match(Doctrine_Query_Token::T_IDENTIFIER);
$this->_identifiers[] = $this->_parser->token['value'];
$this->_parser->match('.');
}
$this->_parser->match('*');
}
public function semantical($paramHolder)
{
$parserResult = $this->_parser->getParserResult();
if (($l = count($this->_identifiers)) > 0) {
// We are dealing with component{.component}.*
$path = $this->_identifiers[0];
$this->_queryComponent = $parserResult->getQueryComponent($path);
// We should have a semantical error if the queryComponent does not exists yet
if ($this->_queryComponent === null) {
$this->_parser->semanticalError("Undefined component alias for '{$path}'", $this->_parser->token);
}
// Initializing ClassMetadata
$classMetadata = $this->_queryComponent['metadata'];
// Looping through relations
for ($i = 1; $i < $l; $i++) {
$relationName = $this->_identifiers[$i];
$path .= '.' . $relationName;
if ( ! $classMetadata->hasAssociation($relationName)) {
$className = $classMetadata->getClassName();
$this->_parser->semanticalError(
"Relation '{$relationName}' does not exist in component '{$className}' when trying to get the path '{$path}'",
$this->_parser->token
);
}
// We inspect for queryComponent of relations, since we are using them
if ( ! $parserResult->hasQueryComponent($path)) {
$this->_parser->semanticalError("Cannot use the path '{$path}' without defining it in FROM.", $this->_parser->token);
}
// Assigning new queryComponent and classMetadata
$this->_queryComponent = $parserResult->getQueryComponent($path);
$classMetadata = $this->_queryComponent['metadata'];
}
} else {
// We are dealing with a simple * as our PathExpression.
// We need to check if there's only one query component.
$queryComponents = $parserResult->getQueryComponents();
if (count($queryComponents) != 2) {
$this->_parser->semanticalError(
"Cannot use * as selector expression for multiple components."
);
}
// We simplify our life adding the component alias to our AST,
// since we have it on hands now.
$k = array_keys($queryComponents);
$componentAlias = $k[1];
$this->_queryComponent = $queryComponents[$componentAlias];
}
}
public function buildSql()
{
// Basic handy variables
$parserResult = $this->_parser->getParserResult();
// Retrieving connection
$conn = $this->_em->getConnection();
// Looking for componentAlias to fetch
$componentAlias = implode('.', $this->_identifiers);
if (count($this->_identifiers) == 0) {
$queryComponents = $parserResult->getQueryComponents();
// Retrieve ClassMetadata
$k = array_keys($queryComponents);
$componentAlias = $k[1];
}
// Generating the SQL piece
$fields = $this->_queryComponent['metadata']->getFieldMappings();
$tableAlias = $parserResult->getTableAliasFromComponentAlias($componentAlias);
$str = '';
foreach ($fields as $fieldName => $fieldMap) {
$str .= ($str != '') ? ', ' : '';
// DB Field name
$column = $tableAlias . '.' . $this->_queryComponent['metadata']->getColumnName($fieldName);
$column = $conn->quoteIdentifier($column);
// DB Field alias
$columnAlias = $tableAlias . '__' . $this->_queryComponent['metadata']->getColumnName($fieldName);
$columnAlias = $conn->quoteIdentifier($columnAlias);
$str .= $column . ' AS ' . $columnAlias;
}
return $str;
}
/* Getters */
public function getIdentifiers()
{
return $this->_identifiers;
}
public function getQueryComponent()
{
return $this->_queryComponent;
}
}
<?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>.
*/
/**
* Primary = PathExpression | Atom | "(" Expression ")" | Function | AggregateExpression
*
* @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_Production_Primary extends Doctrine_Query_Production
{
protected $_expression;
public function syntax($paramHolder)
{
// Primary = PathExpression | Atom | "(" Expression ")" | Function | AggregateExpression
switch ($this->_parser->lookahead['type']) {
case Doctrine_Query_Token::T_IDENTIFIER:
if ($this->_isFunction()) {
return $this->AST('Function', $paramHolder);
} else {
return $this->AST('PathExpression', $paramHolder);
}
break;
case Doctrine_Query_Token::T_STRING:
case Doctrine_Query_Token::T_INTEGER:
case Doctrine_Query_Token::T_FLOAT:
case Doctrine_Query_Token::T_INPUT_PARAMETER:
return $this->AST('Atom', $paramHolder);
break;
case Doctrine_Query_Token::T_AVG:
case Doctrine_Query_Token::T_COUNT:
case Doctrine_Query_Token::T_MAX:
case Doctrine_Query_Token::T_MIN:
case Doctrine_Query_Token::T_SUM:
return $this->AST('AggregateExpression', $paramHolder);
break;
case Doctrine_Query_Token::T_NONE:
if ($this->_isNextToken('(')) {
$this->_parser->match('(');
$this->_expression = $this->AST('Expression', $paramHolder);
$this->_parser->match(')');
}
break;
default:
$this->_parser->syntaxError('Could not process primary type');
break;
}
}
public function semantical($paramHolder)
{
$this->_expression->semantical($paramHolder);
}
public function buildSql()
{
return '(' . $this->_expression->buildSql() . ')';
}
/**
* Visitor support
*
* @param object $visitor
*/
public function accept($visitor)
{
$this->_expression->accept($visitor);
$visitor->visitPrimary($this);
}
/* Getters */
public function getExpression()
{
return $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>.
*/
/**
* QuantifiedExpression = ("ALL" | "ANY" | "SOME") "(" Subselect ")"
*
* @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 2.0
* @version $Revision$
*/
class Doctrine_Query_Production_QuantifiedExpression extends Doctrine_Query_Production
{
protected $_type;
protected $_subselect;
public function syntax($paramHolder)
{
switch ($this->_parser->lookahead['type']) {
case Doctrine_Query_Token::T_ALL:
$this->_parser->match(Doctrine_Query_Token::T_ALL);
break;
case Doctrine_Query_Token::T_ANY:
$this->_parser->match(Doctrine_Query_Token::T_ANY);
break;
case Doctrine_Query_Token::T_SOME:
$this->_parser->match(Doctrine_Query_Token::T_SOME);
break;
default:
$this->_parser->logError('ALL, ANY or SOME');
break;
}
$this->_type = strtoupper($this->_parser->lookahead['value']);
$this->_parser->match('(');
$this->_subselect = $this->AST('Subselect', $paramHolder);
$this->_parser->match(')');
}
public function buildSql()
{
return $this->_type . ' (' . $this->_subselect->buildSql() . ')';
}
/* Getters */
public function getType()
{
return $this->_type;
}
public function getSubselect()
{
return $this->_subselect;
}
}
<?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_Production_QueryLanguage extends Doctrine_Query_Production
{
public function syntax($paramHolder)
{
// QueryLanguage = SelectStatement | UpdateStatement | DeleteStatement
switch ($this->_parser->lookahead['type']) {
case Doctrine_Query_Token::T_SELECT:
return $this->AST('SelectStatement', $paramHolder);
break;
case Doctrine_Query_Token::T_UPDATE:
return $this->AST('UpdateStatement', $paramHolder);
break;
case Doctrine_Query_Token::T_DELETE:
return $this->AST('DeleteStatement', $paramHolder);
break;
default:
$this->_parser->syntaxError('SELECT, UPDATE or DELETE');
break;
}
}
}
<?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 = identifier {"." identifier} [["AS"] IdentificationVariable]
*
* @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_Production_RangeVariableDeclaration extends Doctrine_Query_Production
{
protected $_identifiers = array();
protected $_queryComponent;
protected $_identificationVariable;
public function syntax($paramHolder)
{
// RangeVariableDeclaration = identifier {"." identifier} [["AS"] IdentificationVariable]
$this->_parser->match(Doctrine_Query_Token::T_IDENTIFIER);
$this->_identifiers[] = $this->_parser->token['value'];
while ($this->_isNextToken('.')) {
$this->_parser->match('.');
$this->_parser->match(Doctrine_Query_Token::T_IDENTIFIER);
$this->_identifiers[] = $this->_parser->token['value'];
}
if ($this->_isNextToken(Doctrine_Query_Token::T_AS)) {
$this->_parser->match(Doctrine_Query_Token::T_AS);
}
if ($this->_isNextToken(Doctrine_Query_Token::T_IDENTIFIER)) {
$paramHolder->set('componentName', implode('.', $this->_identifiers));
// Will return an identifier, with the semantical check already applied
$this->_identificationVariable = $this->AST('IdentificationVariable', $paramHolder);
$paramHolder->remove('componentName');
}
}
public function semantical($paramHolder)
{
$parserResult = $this->_parser->getParserResult();
$componentName = implode('.', $this->_identifiers);
if ($parserResult->hasQueryComponent($componentName)) {
//echo "Entered in if of hasQueryComponent(".$componentName."): true\n";
// As long as name != alias, try to bring the queryComponent from name (already processed)
$queryComponent = $parserResult->getQueryComponent($componentName);
// Check if we defined _identificationVariable. We throw semantical error if not
if ($this->_identificationVariable === null) {
$componentName = $queryComponent['metadata']->getClassName();
$this->_parser->semanticalError(
"Cannot re-declare component '{$componentName}'. Please assign an alias to it."
);
return;
}
} else {
//echo "Entered in if hasQueryComponent(".$componentName."), alias ".var_export($this->_identificationVariable, true).": false\n";
// No queryComponent was found. We will have to build it for the first time
if (count($this->_identifiers) > 1) {
// We are in a multiple identifier declaration; we are dealing with relations here
$this->_semanticalWithMultipleIdentifier();
} else {
// We are in a single identifier declaration; our identifier is the class name
$this->_semanticalWithSingleIdentifier();
}
}
}
public function buildSql()
{
// We need to bring the queryComponent and get things from there.
$parserResult = $this->_parser->getParserResult();
// Retrieving connection
$conn = $this->_em->getConnection();
return $conn->quoteIdentifier($this->_queryComponent['metadata']->getTableName()) . ' '
. $conn->quoteIdentifier($parserResult->getTableAliasFromComponentAlias($this->_identificationVariable));
}
private function _semanticalWithSingleIdentifier()
{
$parserResult = $this->_parser->getParserResult();
// Get the connection for the component
$conn = $this->_em->getConnection();
$componentName = $this->_identifiers[0];
// Retrieving ClassMetadata and Mapper
try {
$classMetadata = $this->_em->getClassMetadata($componentName);
// Building queryComponent
$this->_queryComponent = array(
'metadata' => $classMetadata,
'parent' => null,
'relation' => null,
'map' => null,
'scalar' => null,
);
} catch (Doctrine_Exception $e) {
//echo "Tried to load class metadata from '".$componentName."': " . $e->getMessage() . "\n";
$this->_parser->semanticalError($e->getMessage());
return;
}
if ($this->_identificationVariable === null) {
$this->_identificationVariable = $componentName;
}
//echo "Identification Variable: " .$this->_identificationVariable . "\n";
$tableAlias = $parserResult->generateTableAlias($classMetadata->getClassName());
$parserResult->setQueryComponent($this->_identificationVariable, $this->_queryComponent);
$parserResult->setTableAlias($tableAlias, $this->_identificationVariable);
}
private function _semanticalWithMultipleIdentifier()
{
$parserResult = $this->_parser->getParserResult();
// Get the connection for the component
$conn = $this->_em->getConnection();
// Retrieve the base component
try {
$this->_queryComponent = $parserResult->getQueryComponent($this->_identifiers[0]);
$classMetadata = $this->_queryComponent['metadata'];
$className = $classMetadata->getClassName();
$parent = $path = $this->_identifiers[0];
} catch (Doctrine_Exception $e) {
$this->_parser->semanticalError($e->getMessage());
return;
}
// We loop into others identifier to build query components
for ($i = 1, $l = count($this->_identifiers); $i < $l; $i++) {
$relationName = $this->_identifiers[$i];
$path .= '.' . $relationName;
if ($parserResult->hasQueryComponent($path)) {
// We already have the query component on hands, get it
$this->_queryComponent = $parserResult->getQueryComponent($path);
$classMetadata = $this->_queryComponent['metadata'];
// If we are in our last check and identification variable is null, we throw semantical error
if ($i == $l - 1 && $this->_identificationVariable === null) {
$componentName = $classMetadata->getClassName();
$this->_parser->semanticalError(
"Cannot re-declare component '{$componentName}' in path '{$path}'. " .
"Please assign an alias to it."
);
return;
}
} else {
// We don't have the query component yet
if ( ! $classMetadata->hasAssociation($relationName)) {
$className = $classMetadata->getClassName();
$this->_parser->semanticalError("Relation '{$relationName}' does not exist in component '{$className}'");
return;
}
// Retrieving ClassMetadata
try {
$relation = $classMetadata->getAssociationMapping($relationName);
$targetClassMetadata = $this->_em->getClassMetadata($relation->getTargetEntityName());
$this->_queryComponent = array(
'metadata' => $targetClassMetadata,
'parent' => $parent,
'relation' => $relation,
'map' => null,
'scalar' => null,
);
$parent = $path;
} catch (Doctrine_Exception $e) {
//echo "Tried to load class metadata from '".$relationName."'\n";
$this->_parser->semanticalError($e->getMessage());
return;
}
}
}
if ($this->_identificationVariable === null) {
$this->_identificationVariable = $path;
}
$tableAlias = $parserResult->generateTableAlias($targetClassMetadata->getClassName());
$parserResult->setQueryComponent($this->_identificationVariable, $this->_queryComponent);
$parserResult->setTableAlias($tableAlias, $this->_identificationVariable);
}
/* Getters */
public function getIdentifiers()
{
return $this->_identifiers;
}
public function getQueryComponent()
{
return $this->_queryComponent;
}
public function getIdentificationVariable()
{
return $this->_identificationVariable;
}
}
<?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_Production_SelectClause extends Doctrine_Query_Production
{
protected $_isDistinct;
protected $_selectExpressions = array();
public function syntax($paramHolder)
{
// SelectClause = "SELECT" ["DISTINCT"] SelectExpression {"," SelectExpression}
$this->_isDistinct = false;
$this->_parser->match(Doctrine_Query_Token::T_SELECT);
if ($this->_isNextToken(Doctrine_Query_Token::T_DISTINCT)) {
$this->_parser->match(Doctrine_Query_Token::T_DISTINCT);
$this->_isDistinct = true;
}
$this->_selectExpressions[] = $this->AST('SelectExpression', $paramHolder);
while ($this->_isNextToken(',')) {
$this->_parser->match(',');
$this->_selectExpressions[] = $this->AST('SelectExpression', $paramHolder);
}
}
public function semantical($paramHolder)
{
// We need to validate each SelectExpression
for ($i = 0, $l = count($this->_selectExpressions); $i < $l; $i++) {
$this->_selectExpressions[$i]->semantical($paramHolder);
}
}
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();
}
/* Getters */
public function isDistinct()
{
return $this->_isDistinct;
}
public function getSelectExpressions()
{
return $this->_selectExpressions;
}
}
<?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 = (PathExpressionEndingWithAsterisk | Expression | "(" Subselect ")")
* [["AS"] IdentificationVariable]
*
* @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_Production_SelectExpression extends Doctrine_Query_Production
{
protected $_leftExpression;
protected $_isSubselect;
protected $_fieldIdentificationVariable;
private $__columnAliasInSql;
public function syntax($paramHolder)
{
// SelectExpression = (PathExpressionEndingWithAsterisk | Expression | "(" Subselect ")")
// [["AS"] IdentificationVariable]
$this->_isSubselect = false;
if ($this->_isPathExpressionEndingWithAsterisk()) {
$this->_leftExpression = $this->AST('PathExpressionEndingWithAsterisk', $paramHolder);
$fieldName = implode('.', $this->_leftExpression->getIdentifiers()) . '.*';
} else if (($this->_isSubselect = $this->_isSubselect()) === true) {
$this->_parser->match('(');
$this->_leftExpression = $this->AST('Subselect', $paramHolder);
$this->_parser->match(')');
// [TODO] Any way to make it more fancy for user error?
$fieldName = '<Subselect>';
} else {
$this->_leftExpression = $this->AST('Expression', $paramHolder);
// [TODO] Any way to make it more fancy for user error?
$fieldName = '<Expression>';
}
if ($this->_isNextToken(Doctrine_Query_Token::T_AS)) {
$this->_parser->match(Doctrine_Query_Token::T_AS);
}
if ($this->_isNextToken(Doctrine_Query_Token::T_IDENTIFIER)) {
$paramHolder->set('fieldName', $fieldName);
// Will return an identifier, with the semantical check already applied
$this->_fieldIdentificationVariable = $this->AST('FieldIdentificationVariable', $paramHolder);
$paramHolder->remove('fieldName');
}
}
public function semantical($paramHolder)
{
$parserResult = $this->_parser->getParserResult();
// We cannot have aliases for foo.*
if ($this->_leftExpression instanceof Doctrine_Query_Production_PathExpressionEndingWithAsterisk
&& $this->_fieldIdentificationVariable !== null) {
$this->_parser->semanticalError(
"Cannot assign an identification variable to a path expression ending with asterisk (ie. foo.bar.* AS foobaz)."
);
}
// Also, we cannot have aliases for path expressions: foo.bar
if ($this->_leftExpression instanceof Doctrine_Query_Production_PathExpressionEndingWithAsterisk
&& $this->_fieldIdentificationVariable !== null) {
$this->_parser->semanticalError(
"Cannot assign an identification variable to a path expression (ie. foo.bar AS foobaz)."
);
}
// Make semantical checks
$this->_leftExpression->semantical($paramHolder);
if($this->_fieldIdentificationVariable !== null) {
$this->_fieldIdentificationVariable->semantical($paramHolder);
}
}
public function buildSql()
{
return $this->_leftExpression->buildSql() . $this->_buildColumnAliasInSql();
}
protected function _isPathExpressionEndingWithAsterisk()
{
$token = $this->_parser->lookahead;
$this->_parser->getScanner()->resetPeek();
while (($token['type'] === Doctrine_Query_Token::T_IDENTIFIER) || ($token['value'] === '.')) {
$token = $this->_parser->getScanner()->peek();
}
return $token['value'] === '*';
}
protected function _buildColumnAliasInSql()
{
// Retrieving parser result
$parserResult = $this->_parser->getParserResult();
// Retrieving connection
$conn = $this->_em->getConnection();
switch (get_class($this->_leftExpression)) {
case 'Doctrine_Query_Production_PathExpressionEndingWithAsterisk':
return '';
break;
case 'Doctrine_Query_Production_PathExpression':
// We bring the queryComponent from the class instance
$componentAlias = $this->_leftExpression->getComponentAlias();
$queryComponent = $parserResult->getQueryComponent($componentAlias);
$fieldName = $this->_leftExpression->getFieldName();
// Build the column alias now
$columnAlias = $parserResult->getTableAliasFromComponentAlias($componentAlias)
. Doctrine_Query_Production::SQLALIAS_SEPARATOR
. $queryComponent['metadata']->getColumnName($fieldName);
break;
default:
// We bring the default queryComponent
$componentAlias = Doctrine_Query_Production::DEFAULT_QUERYCOMPONENT;
$queryComponent = $parserResult->getQueryComponent($componentAlias);
// If we have FieldIdentificationVariable, we have to use the scalar map of it
if ($this->_fieldIdentificationVariable !== null) {
$columnAlias = $this->_fieldIdentificationVariable->getColumnAlias();
} else {
// We have to include the map now, since we don't have the scalar mapped
$queryFields = $parserResult->getQueryFields();
$itemIndex = 'item' . count(array_filter($queryFields, array($this, "_nonIdentifiedVariable")));
$idx = count($queryFields);
$queryComponent['scalar'][$idx] = $itemIndex;
$parserResult->setQueryComponent($componentAlias, $queryComponent);
// And also in field aliases
$parserResult->setQueryField($itemIndex, $idx);
// Build the column alias
$columnAlias = $parserResult->getTableAliasFromComponentAlias($componentAlias)
. Doctrine_Query_Production::SQLALIAS_SEPARATOR . $idx;
}
break;
}
return ' AS ' . $conn->quoteIdentifier($columnAlias);
}
protected function _nonIdentifiedVariable($value)
{
return ! is_string($value);
}
/* Getters */
public function getLeftExpression()
{
return $this->_leftExpression;
}
public function isSubselect()
{
return $this->_isSubselect;
}
public function getFieldIdentificationVariable()
{
return $this->_fieldIdentificationVariable;
}
}
<?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_Production_SelectStatement extends Doctrine_Query_Production
{
protected $_selectClause;
protected $_fromClause;
protected $_whereClause;
protected $_groupByClause;
protected $_havingClause;
protected $_orderByClause;
public function syntax($paramHolder)
{
// SelectStatement = SelectClause FromClause [WhereClause] [GroupByClause] [HavingClause] [OrderByClause]
// 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 clause be processed).
$paramHolder->set('semanticalCheck', false);
$this->_selectClause = $this->AST('SelectClause', $paramHolder);
$paramHolder->remove('semanticalCheck');
$this->_fromClause = $this->AST('FromClause', $paramHolder);
if ($this->_isNextToken(Doctrine_Query_Token::T_WHERE)) {
$this->_whereClause = $this->AST('WhereClause', $paramHolder);
}
if ($this->_isNextToken(Doctrine_Query_Token::T_GROUP)) {
$this->_groupByClause = $this->AST('GroupByClause', $paramHolder);
}
if ($this->_isNextToken(Doctrine_Query_Token::T_HAVING)) {
$this->_havingClause = $this->AST('HavingClause', $paramHolder);
}
if ($this->_isNextToken(Doctrine_Query_Token::T_ORDER)) {
$this->_orderByClause = $this->AST('OrderByClause', $paramHolder);
}
}
public function semantical($paramHolder)
{
// We need to invoke the semantical check of SelectClause here, since
// it was not yet checked.
$this->_selectClause->semantical($paramHolder);
}
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() : '');
}
/* 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;
}
}
<?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>.
*/
/**
* SimpleConditionalExpression =
* ExistsExpression | Expression (ComparisonExpression | BetweenExpression |
* LikeExpression | InExpression | NullComparisonExpression | QuantifiedExpression)
*
* @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_Production_SimpleConditionalExpression extends Doctrine_Query_Production
{
protected $_leftExpression;
protected $_rightExpression;
public function syntax($paramHolder)
{
// SimpleConditionalExpression =
// ExistsExpression | Expression (ComparisonExpression | BetweenExpression |
// LikeExpression | InExpression | NullComparisonExpression | QuantifiedExpression)
if ($this->_getExpressionType() === Doctrine_Query_Token::T_EXISTS) {
return $this->AST('ExistsExpression', $paramHolder);
}
$this->_leftExpression = $this->AST('Expression', $paramHolder);
switch ($this->_getExpressionType()) {
case Doctrine_Query_Token::T_BETWEEN:
$this->_rightExpression = $this->AST('BetweenExpression', $paramHolder);
break;
case Doctrine_Query_Token::T_LIKE:
$this->_rightExpression = $this->AST('LikeExpression', $paramHolder);
break;
case Doctrine_Query_Token::T_IN:
$this->_rightExpression = $this->AST('InExpression', $paramHolder);
break;
case Doctrine_Query_Token::T_IS:
$this->_rightExpression = $this->AST('NullComparisonExpression', $paramHolder);
break;
case Doctrine_Query_Token::T_ALL:
case Doctrine_Query_Token::T_ANY:
case Doctrine_Query_Token::T_SOME:
$this->_rightExpression = $this->AST('QuantifiedExpression', $paramHolder);
break;
case Doctrine_Query_Token::T_NONE:
// [TODO] Check out ticket #935 to understand what will be done with enumParams
$this->_rightExpression = $this->AST('ComparisonExpression', $paramHolder);
break;
default:
$message = "BETWEEN, LIKE, IN, IS, quantified (ALL, ANY or SOME) "
. "or comparison (=, <, <=, <>, >, >=, !=)";
$this->_parser->syntaxError($message);
break;
}
}
public function buildSql()
{
return $this->_leftExpression->buildSql() . ' ' . $this->_rightExpression->buildSql();
}
protected function _getExpressionType() {
if ($this->_isNextToken(Doctrine_Query_Token::T_NOT)) {
$scanner = $this->_parser->getScanner();
$token = $scanner->peek();
$scanner->resetPeek();
} else {
$token = $this->_parser->lookahead;
}
return $token['type'];
}
/* Getters */
public function getLeftExpression()
{
return $this->_leftExpression;
}
public function getRightExpression()
{
return $this->_rightExpression;
}
}
<?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>.
*/
/**
* SimpleSelectClause = "SELECT" ["DISTINCT"] SelectExpression
*
* @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 2.0
* @version $Revision$
*/
class Doctrine_Query_Production_SimpleSelectClause extends Doctrine_Query_Production
{
protected $_isDistinct;
protected $_selectExpression;
public function syntax($paramHolder)
{
// SimpleSelectClause = "SELECT" ["DISTINCT"] SelectExpression
$this->_isDistinct = false;
$this->_parser->match(Doctrine_Query_Token::T_SELECT);
if ($this->_isNextToken(Doctrine_Query_Token::T_DISTINCT)) {
$this->_parser->match(Doctrine_Query_Token::T_DISTINCT);
$this->_isDistinct = true;
}
$this->_selectExpression = $this->AST('SelectExpression', $paramHolder);
}
public function semantical($paramHolder)
{
// We need to validate the SelectExpression
$this->_selectExpression->semantical($paramHolder);
}
public function buildSql()
{
return 'SELECT ' . (($this->_isDistinct) ? 'DISTINCT ' : '')
. $this->_selectExpression->buildSql();
}
/**
* Visitor support
*
* @param object $visitor
*/
public function acccept($visitor)
{
$this->_selectExpression->accept($visitor);
$visitor->visitSimpleSelectClause($this);
}
/* Getters */
public function isDistinct()
{
return $this->_isDistinct;
}
public function getSelectExpression()
{
return $this->_selectExpression;
}
}
<?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>.
*/
/**
* Subselect = SimpleSelectClause FromClause [WhereClause] [GroupByClause]
* [HavingClause] [OrderByClause] [LimitClause] [OffsetClause]
*
* @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_Production_Subselect extends Doctrine_Query_Production
{
protected $_simpleSelectClause;
protected $_fromClause;
protected $_whereClause;
protected $_groupByClause;
protected $_havingClause;
protected $_orderByClause;
protected $_limitClause;
public function syntax($paramHolder)
{
// Subselect = SimpleSelectClause FromClause [WhereClause] [GroupByClause] [HavingClause] [OrderByClause] [LimitClause]
// 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 clause be processed).
$paramHolder->set('semanticalCheck', false);
$this->_simpleSelectClause = $this->AST('SimpleSelectClause', $paramHolder);
$paramHolder->remove('semanticalCheck');
$this->_fromClause = $this->AST('FromClause', $paramHolder);
if ($this->_isNextToken(Doctrine_Query_Token::T_WHERE)) {
$this->_whereClause = $this->AST('WhereClause', $paramHolder);
}
if ($this->_isNextToken(Doctrine_Query_Token::T_GROUP)) {
$this->_groupByClause = $this->AST('GroupByClause', $paramHolder);
}
if ($this->_isNextToken(Doctrine_Query_Token::T_HAVING)) {
$this->_havingClause = $this->AST('HavingClause', $paramHolder);
}
if ($this->_isNextToken(Doctrine_Query_Token::T_ORDER)) {
$this->_orderByClause = $this->AST('OrderByClause', $paramHolder);
}
if ($this->_isNextToken(Doctrine_Query_Token::T_LIMIT)) {
$this->_limitClause = $this->AST('LimitClause', $paramHolder);
}
}
public function semantical($paramHolder)
{
// We need to invoke the semantical check of SelectClause here, since
// it was not yet checked.
$this->_simpleSelectClause->semantical($paramHolder);
}
public function buildSql()
{
return $this->_simpleSelectClause->buildSql() . ' ' . $this->_fromClause->buildSql()
. (($this->_whereClause !== null) ? ' ' . $this->_whereClause->buildSql() : '')
. (($this->_groupByClause !== null) ? ' ' . $this->_groupByClause->buildSql() : '')
. (($this->_havingClause !== null) ? ' ' . $this->_havingClause->buildSql() : '')
. (($this->_orderByClause !== null) ? ' ' . $this->_orderByClause->buildSql() : '');
}
/**
* Visitor support
*
* @param object $visitor
*/
public function accept($visitor)
{
$this->_simpleSelectClause->accept($visitor);
$this->_fromClause->accept($visitor);
if ($this->_whereClause) {
$this->_whereClause->accept($visitor);
}
if ($this->_groupByClause) {
$this->_groupByClause->accept($visitor);
}
if ($this->_havingClause) {
$this->_havingClause->accept($visitor);
}
if ($this->_orderByClause) {
$this->_orderByClause->accept($visitor);
}
$visitor->visitSubselect($this);
}
/* Getters */
public function getSimpleSelectClause()
{
return $this->_simpleSelectClause;
}
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;
}
}
<?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>.
*/
/**
* Term = Factor {("*" | "/") Factor}
*
* @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_Production_Term extends Doctrine_Query_Production
{
protected $_factors = array();
public function syntax($paramHolder)
{
// Term = Factor {("*" | "/") Factor}
$this->_factors[] = $this->AST('Factor', $paramHolder);
while ($this->_isNextToken('*') || $this->_isNextToken('/')) {
if ($this->_isNextToken('*')) {
$this->_parser->match('*');
$this->_factors[] = '*';
} else {
$this->_parser->match('/');
$this->_factors[] = '/';
}
$this->_factors[] = $this->AST('Factor', $paramHolder);
}
// Optimize depth instances in AST
if (count($this->_factors) == 1) {
return $this->_factors[0];
}
}
public function semantical($paramHolder)
{
for ($i = 0, $l = count($this->_factors); $i < $l; $i++) {
if ($this->_factors[$i] != '*' && $this->_factors[$i] != '/') {
$this->_factors[$i]->semantical($paramHolder);
}
}
}
public function buildSql()
{
return implode(' ', $this->_mapFactors());
}
protected function _mapFactors()
{
return array_map(array(&$this, '_mapFactor'), $this->_factors);
}
protected function _mapFactor($value)
{
return (is_string($value) ? $value : $value->buildSql());
}
/**
* Visitor support.
*/
public function accept($visitor)
{
foreach ($this->_factors as $factor) {
$factor->accept($visitor);
}
$visitor->visitTerm($this);
}
/* Getters */
public function getFactors()
{
return $this->_factors;
}
}
<?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>.
*/
/**
* UpdateClause = "UPDATE" VariableDeclaration "SET" UpdateItem {"," UpdateItem}
*
* @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_Production_UpdateClause extends Doctrine_Query_Production
{
protected $_variableDeclaration;
protected $_updateItems = array();
public function syntax($paramHolder)
{
// UpdateClause = "UPDATE" VariableDeclaration "SET" UpdateItem {"," UpdateItem}
$this->_parser->match(Doctrine_Query_Token::T_UPDATE);
$this->_variableDeclaration = $this->AST('VariableDeclaration', $paramHolder);
$this->_parser->match(Doctrine_Query_Token::T_SET);
$this->_updateItems[] = $this->AST('UpdateItem', $paramHolder);
while ($this->_isNextToken(',')) {
$this->_parser->match(',');
$this->_updateItems[] = $this->AST('UpdateItem', $paramHolder);
}
}
public function buildSql()
{
return 'UPDATE ' . $this->_variableDeclaration->buildSql()
. ' SET ' . implode(', ', $this->_mapUpdateItems());
}
protected function _mapUpdateItems()
{
return array_map(array(&$this, '_mapUpdateItem'), $this->_updateItems);
}
protected function _mapUpdateItem($value)
{
return $value->buildSql();
}
/**
* Visitor support.
*/
public function accept($visitor)
{
$this->_variableDeclaration->accept($visitor);
foreach ($this->_updateItems as $item) {
$item->accept($visitor);
}
$visitor->visitUpdateClause($this);
}
/* Getters */
public function getVariableDeclaration()
{
return $this->_variableDeclaration;
}
public function getUpdateItems()
{
return $this->_updateItems;
}
}
<?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 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_Production_UpdateItem extends Doctrine_Query_Production
{
protected $_pathExpression;
protected $_expression;
public function syntax($paramHolder)
{
// UpdateItem = PathExpression "=" (Expression | "NULL")
$this->_pathExpression = $this->AST('PathExpression', $paramHolder);
$this->_parser->match('=');
if ($this->_isNextToken(Doctrine_Query_Token::T_NULL)) {
$this->_parser->match(Doctrine_Query_Token::T_NULL);
$this->_expression = null;
} else {
$this->_expression = $this->AST('Expression', $paramHolder);
}
}
public function buildSql()
{
return $this->_pathExpression->buildSql() . ' = '
. ($this->_expression === null ? 'NULL' : $this->_expression->buildSql());
}
/**
* Visitor support.
*/
public function accept($visitor)
{
$this->_pathExpression->accept($visitor);
if ($this->_expression) {
$this->_expression->accept($visitor);
}
$visitor->visitUpdateItem($this);
}
/* Getters */
public function getPathExpression()
{
return $this->_pathExpression;
}
public function getExpression()
{
return $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>.
*/
/**
* 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_Production_UpdateStatement extends Doctrine_Query_Production
{
protected $_updateClause;
protected $_whereClause;
public function syntax($paramHolder)
{
// UpdateStatement = UpdateClause [WhereClause]
$this->_updateClause = $this->AST('UpdateClause', $paramHolder);
if ($this->_isNextToken(Doctrine_Query_Token::T_WHERE)) {
$this->_whereClause = $this->AST('WhereClause', $paramHolder);
}
}
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');
}
/**
* Visitor support.
*/
public function accept($visitor)
{
$this->_updateClause->accept($visitor);
if ($this->_whereClause) {
$this->_whereClause->accept($visitor);
}
$visitor->visitUpdateStatment($this);
}
/* Getters */
public function getUpdateClause()
{
return $this->_updateClause;
}
public function getWhereClause()
{
return $this->_whereClause;
}
}
<?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>.
*/
/**
* VariableDeclaration = identifier [["AS"] IdentificationVariable]
*
* @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_Production_VariableDeclaration extends Doctrine_Query_Production
{
protected $_componentName;
protected $_componentAlias;
public function syntax($paramHolder)
{
// VariableDeclaration = identifier [["AS"] IdentificationVariable]
if ($this->_parser->match(Doctrine_Query_Token::T_IDENTIFIER)) {
// identifier
$this->_componentName = $this->_parser->token['value'];
}
if ($this->_isNextToken(Doctrine_Query_Token::T_AS)) {
$this->_parser->match(Doctrine_Query_Token::T_AS);
}
if ($this->_isNextToken(Doctrine_Query_Token::T_IDENTIFIER)) {
$paramHolder->set('componentName', $this->_componentName);
// Will return an identifier, with the semantical check already applied
$this->_componentAlias = $this->AST('IdentificationVariable', $paramHolder);
$paramHolder->remove('componentName');
}
}
public function semantical($paramHolder)
{
$parserResult = $this->_parser->getParserResult();
if ($parserResult->hasQueryComponent($this->_componentName)) {
// As long as name != alias, try to bring the queryComponent from name (already processed)
$queryComponent = $parserResult->getQueryComponent($this->_componentName);
// Check if we defined _componentAlias. We throw semantical error if not
if ($this->_componentAlias === null) {
$componentName = $queryComponent['metadata']->getClassName();
$this->_parser->semanticalError(
"Cannot re-declare component '{$this->_componentName}'. Please assign an alias to it."
);
return;
}
} else {
// No queryComponent was found. We will have to build it for the first time
// Get the connection for the component
$conn = $this->_em->getConnection();
// Retrieving ClassMetadata and Mapper
try {
$classMetadata = $this->_em->getMetadata($this->_componentName);
// Building queryComponent
$queryComponent = array(
'metadata' => $classMetadata,
'parent' => null,
'relation' => null,
'map' => null,
'scalar' => null,
);
} catch (Doctrine_Exception $e) {
$this->_parser->semanticalError($e->getMessage());
return;
}
}
// Define ParserResult assertions for later usage
$tableAlias = $this->_parser->getParserResult()->generateTableAlias($this->_componentName);
if ($this->_componentAlias === null) {
$this->_componentAlias = $this->_componentName;
}
$parserResult->setQueryComponent($this->_componentAlias, $queryComponent);
$parserResult->setTableAlias($tableAlias, $this->_componentAlias);
}
public function buildSql()
{
// Basic handy variables
$parserResult = $this->_parser->getParserResult();
$queryComponent = $parserResult->getQueryComponent($this->_componentAlias);
// Retrieving connection
$conn = $this->_em->getConnection();
return $conn->quoteIdentifier($queryComponent['metadata']->getTableName()) . ' '
. $conn->quoteIdentifier($parserResult->getTableAliasFromComponentAlias($this->_componentAlias));
}
/**
* Visitor support.
*/
public function accept($visitor)
{
$visitor->visitVariableDeclaration($this);
}
/* Getters */
public function getComponentName()
{
return $this->_componentName;
}
public function getComponentAlias()
{
return $this->_componentAlias;
}
}
<?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>.
*/
/**
* WhereClause = "WHERE" ConditionalExpression
*
* @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_Production_WhereClause extends Doctrine_Query_Production
{
protected $_conditionalExpression;
public function syntax($paramHolder)
{
// WhereClause = "WHERE" ConditionalExpression
$this->_parser->match(Doctrine_Query_Token::T_WHERE);
$this->_conditionalExpression = $this->AST('ConditionalExpression', $paramHolder);
}
public function buildSql()
{
return 'WHERE ' . $this->_conditionalExpression->buildSql();
}
/* Getters */
public function getConditionalExpression()
{
return $this->_conditionalExpression;
}
}
......@@ -302,7 +302,7 @@ class UnitOfWork
public function computeChangeSets(array $entities = null)
{
$entitySet = array();
if ( ! is_null($entities)) {
if ($entities !== null) {
foreach ($entities as $entity) {
$entitySet[get_class($entity)][] = $entity;
}
......@@ -331,7 +331,7 @@ class UnitOfWork
}
if ($class->isCollectionValuedAssociation($name)
&& ! is_null($actualData[$name])
&& $actualData[$name] !== null
&& ! ($actualData[$name] instanceof PersistentCollection)) {
//TODO: If $actualData[$name] is Collection then unwrap the array
$assoc = $class->getAssociationMapping($name);
......@@ -365,7 +365,7 @@ class UnitOfWork
$orgValue = isset($originalData[$propName]) ? $originalData[$propName] : null;
if (is_object($orgValue) && $orgValue !== $actualValue) {
$changeSet[$propName] = array($orgValue, $actualValue);
} else if ($orgValue != $actualValue || (is_null($orgValue) xor is_null($actualValue))) {
} else if ($orgValue != $actualValue || ($orgValue === null xor $actualValue === null)) {
$changeSet[$propName] = array($orgValue, $actualValue);
}
......@@ -398,7 +398,7 @@ class UnitOfWork
if ($state == self::STATE_MANAGED) {
foreach ($class->getAssociationMappings() as $assoc) {
$val = $actualData[$assoc->getSourceFieldName()];
if ( ! is_null($val)) {
if ($val !== null) {
$this->_computeAssociationChanges($assoc, $val);
}
}
......@@ -493,7 +493,7 @@ class UnitOfWork
foreach ($this->_entityInsertions as $entity) {
if (get_class($entity) == $className) {
$returnVal = $persister->insert($entity);
if ( ! is_null($returnVal)) {
if ($returnVal !== null) {
// Persister returned a post-insert ID
$oid = spl_object_hash($entity);
$idField = $class->getSingleIdentifierFieldName();
......@@ -546,7 +546,7 @@ class UnitOfWork
*/
private function _getCommitOrder(array $entityChangeSet = null)
{
if (is_null($entityChangeSet)) {
if ($entityChangeSet === null) {
$entityChangeSet = array_merge(
$this->_entityInsertions,
$this->_entityUpdates,
......
......@@ -4,6 +4,7 @@ namespace Doctrine\Tests\Mocks;
class ConnectionMock extends \Doctrine\DBAL\Connection
{
private $_fetchOneResult;
private $_platformMock;
private $_lastInsertId = 0;
private $_inserts = array();
......@@ -38,6 +39,14 @@ class ConnectionMock extends \Doctrine\DBAL\Connection
{
return $this->_lastInsertId;
}
/**
* @override
*/
public function fetchOne($sql)
{
return $this->_fetchOneResult;
}
/**
* @override
......@@ -51,6 +60,11 @@ class ConnectionMock extends \Doctrine\DBAL\Connection
}
/* Mock API */
public function setFetchOneResult($fetchOneResult)
{
$this->_fetchOneResult = $fetchOneResult;
}
public function setDatabasePlatform($platform)
{
......
......@@ -4,6 +4,7 @@ namespace Doctrine\Tests\Mocks;
class DatabasePlatformMock extends \Doctrine\DBAL\Platforms\AbstractPlatform
{
private $_sequenceNextValSql = "";
private $_prefersIdentityColumns = false;
/**
......@@ -24,6 +25,12 @@ class DatabasePlatformMock extends \Doctrine\DBAL\Platforms\AbstractPlatform
return $this->_prefersIdentityColumns;
}
/** @override */
public function getSequenceNextValSql($sequenceName)
{
return $this->_sequenceNextValSql;
}
/** @override */
public function getIntegerTypeDeclarationSql(array $field) {}
......@@ -51,4 +58,9 @@ class DatabasePlatformMock extends \Doctrine\DBAL\Platforms\AbstractPlatform
{
$this->_prefersIdentityColumns = (bool)$bool;
}
public function setSequenceNextValSql($sql)
{
$this->_sequenceNextValSql = $sql;
}
}
\ No newline at end of file
......@@ -40,6 +40,7 @@ class AllTests
$suite->addTest(Associations\AllTests::suite());
$suite->addTest(Mapping\AllTests::suite());
$suite->addTest(Functional\AllTests::suite());
$suite->addTest(Id\AllTests::suite());
return $suite;
}
......
......@@ -26,7 +26,7 @@ class EntityPersisterTest extends \Doctrine\Tests\OrmTestCase
$this->_emMock = EntityManagerMock::create($this->_connMock);
$this->_uowMock = new UnitOfWorkMock($this->_emMock);
$this->_emMock->setUnitOfWork($this->_uowMock);
$this->_idGenMock = new SequenceMock($this->_emMock);
$this->_idGenMock = new SequenceMock($this->_emMock, 'seq');
$this->_emMock->setIdGenerator('Doctrine\Tests\Models\Forum\ForumUser', $this->_idGenMock);
}
......
......@@ -12,6 +12,11 @@ class OrmTestCase extends DoctrineTestCase
/**
* Creates an EntityManager for testing purposes.
*
* NOTE: The created EntityManager will have its dependant DBAL parts completely
* mocked out using a DriverMock, ConnectionMock, etc. These mocks can then
* be configured in the tests to simulate the DBAL behavior that is desired
* for a particular test,
*
* @return Doctrine\ORM\EntityManager
*/
......@@ -20,7 +25,7 @@ class OrmTestCase extends DoctrineTestCase
$config = new \Doctrine\ORM\Configuration();
$config->setMetadataCacheImpl(self::getSharedMetadataCacheImpl());
$eventManager = new \Doctrine\Common\EventManager();
if (is_null($conn)) {
if ($conn === null) {
$conn = array(
'driverClass' => 'Doctrine\Tests\Mocks\DriverMock',
'wrapperClass' => 'Doctrine\Tests\Mocks\ConnectionMock',
......@@ -33,7 +38,7 @@ class OrmTestCase extends DoctrineTestCase
private static function getSharedMetadataCacheImpl()
{
if (is_null(self::$_metadataCacheImpl)) {
if (self::$_metadataCacheImpl === null) {
self::$_metadataCacheImpl = new \Doctrine\ORM\Cache\ArrayCache;
}
return self::$_metadataCacheImpl;
......
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