diff --git a/lib/Doctrine/Entity.php b/lib/Doctrine/Entity.php index 5e87b132d..e5c3d7d15 100644 --- a/lib/Doctrine/Entity.php +++ b/lib/Doctrine/Entity.php @@ -23,7 +23,7 @@ /** * Base class for all Entities (objects with persistent state in a RDBMS that are - * managed by Doctrine). Kind of a Layer Suptertype. + * managed by Doctrine). Kind of a Layer Supertype. * * NOTE: Methods that are intended for internal use only but must be public * are marked INTERNAL: and begin with an underscore "_" to indicate that they @@ -126,14 +126,14 @@ abstract class Doctrine_Entity implements ArrayAccess, Serializable /** * The values that make up the ID/primary key of the entity. * - * @var array + * @var array */ private $_id = array(); /** * The entity data. * - * @var array + * @var array */ private $_data = array(); @@ -173,7 +173,7 @@ abstract class Doctrine_Entity implements ArrayAccess, Serializable * @var array */ private $_references = array(); - + /** * The EntityManager that is responsible for the persistent state of the entity. * @@ -185,10 +185,10 @@ abstract class Doctrine_Entity implements ArrayAccess, Serializable * The object identifier of the object. Each object has a unique identifier * during script execution. * - * @var integer + * @var integer */ private $_oid; - + /** * Flag that indicates whether the entity is dirty. * (which means it has local changes) @@ -214,11 +214,11 @@ abstract class Doctrine_Entity implements ArrayAccess, Serializable } else { $this->_state = self::STATE_NEW; } - + // @todo read from attribute the first time and move this initialization elsewhere. self::$_useAutoAccessorOverride = true; } - + /** * Returns the object identifier. * @@ -295,7 +295,7 @@ abstract class Doctrine_Entity implements ArrayAccess, Serializable } } } - + $str = serialize($vars); //$this->postSerialize($event); @@ -330,7 +330,7 @@ abstract class Doctrine_Entity implements ArrayAccess, Serializable foreach($array as $k => $v) { $this->$k = $v; } - + $this->_class = $this->_em->getClassMetadata($this->_entityName); foreach ($this->_data as $k => $v) { @@ -350,7 +350,7 @@ abstract class Doctrine_Entity implements ArrayAccess, Serializable } $this->_extractIdentifier(!$this->isNew()); - + //$this->postUnserialize($event); } @@ -375,7 +375,7 @@ abstract class Doctrine_Entity implements ArrayAccess, Serializable /** * Gets the current field values. * - * @return array The fields and their values. + * @return array The fields and their values. */ final public function getData() { @@ -390,7 +390,7 @@ abstract class Doctrine_Entity implements ArrayAccess, Serializable * @throws Doctrine::ORM::Exceptions::EntityException If trying to get an unknown field. */ final protected function _get($fieldName) - { + { $nullObj = Doctrine_Null::$INSTANCE; if (isset($this->_data[$fieldName])) { return $this->_data[$fieldName] !== $nullObj ? @@ -415,7 +415,7 @@ abstract class Doctrine_Entity implements ArrayAccess, Serializable } } } - + /** * Sets the value of a field (regular field or reference). * @@ -455,7 +455,7 @@ abstract class Doctrine_Entity implements ArrayAccess, Serializable throw Doctrine_Entity_Exception::invalidField($fieldName); } } - + private function _registerDirty() { if ($this->_state == self::STATE_MANAGED && @@ -463,7 +463,7 @@ abstract class Doctrine_Entity implements ArrayAccess, Serializable $this->_em->getUnitOfWork()->registerDirty($this); } } - + /** * INTERNAL: * Gets the value of a field. @@ -482,7 +482,7 @@ abstract class Doctrine_Entity implements ArrayAccess, Serializable } return $this->_data[$fieldName]; } - + /** * INTERNAL: * Sets the value of a field. @@ -498,7 +498,7 @@ abstract class Doctrine_Entity implements ArrayAccess, Serializable { $this->_data[$fieldName] = $value; } - + /** * INTERNAL: * Gets a reference to another Entity. @@ -515,7 +515,7 @@ abstract class Doctrine_Entity implements ArrayAccess, Serializable } return $this->_references[$fieldName]; } - + /** * INTERNAL: * Sets a reference to another entity or a collection of entities. @@ -532,7 +532,7 @@ abstract class Doctrine_Entity implements ArrayAccess, Serializable $this->_references[$name] = $value; return; } - + $rel = $this->_class->getRelation($name); // one-to-many or one-to-one relation @@ -575,7 +575,7 @@ abstract class Doctrine_Entity implements ArrayAccess, Serializable $this->_references[$name] = $value; } - + /** * INTERNAL: * Sets a reference to another entity or a collection of entities. @@ -592,7 +592,7 @@ abstract class Doctrine_Entity implements ArrayAccess, Serializable $this->_references[$name] = $value; return; } - + $rel = $this->_class->getAssociationMapping($name); // one-to-many or one-to-one relation @@ -641,7 +641,7 @@ abstract class Doctrine_Entity implements ArrayAccess, Serializable } return $this->_get($fieldName); } - + /** * Gets the custom mutator method for a field, if it exists. * @@ -660,17 +660,17 @@ abstract class Doctrine_Entity implements ArrayAccess, Serializable self::$_mutatorCache[$this->_entityName][$fieldName] = false; } } - + if ($setter = $this->_class->getCustomMutator($fieldName)) { self::$_mutatorCache[$this->_entityName][$fieldName] = $setter; } else if ( ! isset(self::$_mutatorCache[$this->_entityName][$fieldName])) { self::$_mutatorCache[$this->_entityName][$fieldName] = false; } } - + return self::$_mutatorCache[$this->_entityName][$fieldName]; } - + /** * Gets the custom accessor method of a field, if it exists. * @@ -695,10 +695,10 @@ abstract class Doctrine_Entity implements ArrayAccess, Serializable self::$_accessorCache[$this->_entityName][$fieldName] = false; } } - + return self::$_accessorCache[$this->_entityName][$fieldName]; } - + /** * Gets the entity class name. * @@ -773,7 +773,7 @@ abstract class Doctrine_Entity implements ArrayAccess, Serializable } } } - + /** * INTERNAL: * Gets the changeset of the entities persistent state. @@ -784,12 +784,12 @@ abstract class Doctrine_Entity implements ArrayAccess, Serializable { return $this->_dataChangeSet; } - + final public function _getReferenceChangeSet() { return $this->_referenceChangeSet; } - + /** * Checks whether the entity already has a persistent state. * @@ -893,7 +893,7 @@ abstract class Doctrine_Entity implements ArrayAccess, Serializable { $this->_references[$alias] = $coll; } - + /** * Gets the ClassMetadata object that describes the entity class. * @@ -903,7 +903,7 @@ abstract class Doctrine_Entity implements ArrayAccess, Serializable { return $this->_class; } - + /** * Gets the EntityManager that is responsible for the persistence of * the entity. @@ -914,7 +914,7 @@ abstract class Doctrine_Entity implements ArrayAccess, Serializable { return $this->_em; } - + /** * Gets the EntityRepository of the Entity. * @@ -924,7 +924,7 @@ abstract class Doctrine_Entity implements ArrayAccess, Serializable { return $this->_em->getRepository($this->_entityName); } - + /** * @todo Why toString() and __toString() ? */ @@ -941,7 +941,7 @@ abstract class Doctrine_Entity implements ArrayAccess, Serializable { return (string)$this->_oid; } - + /** * Helps freeing the memory occupied by the entity. * Cuts all references the entity has to other entities and removes the entity @@ -969,7 +969,7 @@ abstract class Doctrine_Entity implements ArrayAccess, Serializable $this->_references = array(); } } - + /** * Check if an offsetExists. * @@ -1022,7 +1022,7 @@ abstract class Doctrine_Entity implements ArrayAccess, Serializable { return $this->remove($offset); } - + /** * __set * diff --git a/lib/Doctrine/Query/AbstractResult.php b/lib/Doctrine/Query/AbstractResult.php index 03d510c9e..d537777a5 100755 --- a/lib/Doctrine/Query/AbstractResult.php +++ b/lib/Doctrine/Query/AbstractResult.php @@ -123,7 +123,7 @@ abstract class Doctrine_Query_AbstractResult */ public function getQueryComponent($componentAlias) { - if ( ! isset($this->_queryComponents[$componentAlias])) { + if ( ! array_key_exists($componentAlias, $this->_queryComponents)) { throw new Doctrine_Query_Exception('Unknown query component ' . $componentAlias); } diff --git a/lib/Doctrine/Query/Parser.php b/lib/Doctrine/Query/Parser.php index f53ab3e71..1266f1aef 100644 --- a/lib/Doctrine/Query/Parser.php +++ b/lib/Doctrine/Query/Parser.php @@ -173,7 +173,9 @@ class Doctrine_Query_Parser /** - * @todo [TODO] Document these! + * Moves the parser scanner to next token + * + * @return void */ public function next() { diff --git a/lib/Doctrine/Query/Production/BetweenExpression.php b/lib/Doctrine/Query/Production/BetweenExpression.php index c94d74f4b..75024d1f2 100644 --- a/lib/Doctrine/Query/Production/BetweenExpression.php +++ b/lib/Doctrine/Query/Production/BetweenExpression.php @@ -65,31 +65,21 @@ class Doctrine_Query_Production_BetweenExpression extends Doctrine_Query_Product return (($this->_not) ? 'NOT ' : '') . 'BETWEEN ' . $this->_fromExpression->buildSql() . ' AND ' . $this->_toExpression->buildSql(); } - - /** - * Visitor support. - * - * @param object $visitor - */ - public function accept($visitor) - { - $this->_fromExpression->accept($visitor); - $this->_toExpression->accept($visitor); - $visitor->visitBetweenExpression($this); - } - + + /* Getters */ - public function isNot() { return $this->_not; } - + + public function getFromExpression() { return $this->_fromExpression; } - + + public function getToExpression() { return $this->_toExpression; diff --git a/lib/Doctrine/Query/Production/ComparisonExpression.php b/lib/Doctrine/Query/Production/ComparisonExpression.php index cf43da9ec..f26705771 100644 --- a/lib/Doctrine/Query/Production/ComparisonExpression.php +++ b/lib/Doctrine/Query/Production/ComparisonExpression.php @@ -24,6 +24,7 @@ * * @package Doctrine * @subpackage Query + * @author Guilherme Blanco * @author Janne Vanhala * @license http://www.opensource.org/licenses/lgpl-license.php LGPL * @link http://www.phpdoctrine.org @@ -71,30 +72,21 @@ class Doctrine_Query_Production_ComparisonExpression extends Doctrine_Query_Prod '(' . $this->_expression->buildSql() . ')' : $this->_expression->buildSql() ); } - - /** - * Visitor support. - * - * @param object $visitor - */ - public function accept($visitor) - { - $this->_expression->accept($visitor); - $visitor->visitComparisonExpression($this); - } - + + /* Getters */ - public function getOperator() { return $this->_operator; } - + + public function getExpression() { return $this->_expression; } - + + public function isSubselect() { return $this->_isSubselect; diff --git a/lib/Doctrine/Query/Production/ComparisonOperator.php b/lib/Doctrine/Query/Production/ComparisonOperator.php index 06b79e476..3728a2ac8 100644 --- a/lib/Doctrine/Query/Production/ComparisonOperator.php +++ b/lib/Doctrine/Query/Production/ComparisonOperator.php @@ -24,6 +24,7 @@ * * @package Doctrine * @subpackage Query + * @author Guilherme Blanco * @author Janne Vanhala * @license http://www.opensource.org/licenses/lgpl-license.php LGPL * @link http://www.phpdoctrine.org @@ -78,14 +79,4 @@ class Doctrine_Query_Production_ComparisonOperator extends Doctrine_Query_Produc break; } } - - /** - * Visitor support. - * - * @param object $visitor - */ - public function accept($visitor) - { - $visitor->visitComparisonOperator($this); - } } diff --git a/lib/Doctrine/Query/Production/ConditionalExpression.php b/lib/Doctrine/Query/Production/ConditionalExpression.php index 6bafbb7f1..8537315e4 100644 --- a/lib/Doctrine/Query/Production/ConditionalExpression.php +++ b/lib/Doctrine/Query/Production/ConditionalExpression.php @@ -69,22 +69,9 @@ class Doctrine_Query_Production_ConditionalExpression extends Doctrine_Query_Pro { return $value->buildSql(); } - - /** - * Visitor support. - * - * @param object $visitor - */ - public function accept($visitor) - { - foreach ($this->_conditionalTerms as $term) { - $term->accept($visitor); - } - $visitor->visitConditionalExpression($this); - } - + + /* Getters */ - public function getConditionalTerms() { return $this->_conditionalTerms; diff --git a/lib/Doctrine/Query/Production/ConditionalFactor.php b/lib/Doctrine/Query/Production/ConditionalFactor.php index 370926049..19c277f26 100644 --- a/lib/Doctrine/Query/Production/ConditionalFactor.php +++ b/lib/Doctrine/Query/Production/ConditionalFactor.php @@ -60,20 +60,9 @@ class Doctrine_Query_Production_ConditionalFactor extends Doctrine_Query_Product // Do not need to check $notFactor. It'll be always present if we have this instance. return 'NOT ' . $this->_conditionalPrimary->buildSql(); } - - /** - * Visitor support - * - * @param object $visitor - */ - public function accept($visitor) - { - $this->_conditionalPrimary->accept($visitor); - $visitor->visitConditionalFactor($this); - } - + + /* Getters */ - public function getConditionalPrimary() { return $this->_conditionalPrimary; diff --git a/lib/Doctrine/Query/Production/ConditionalPrimary.php b/lib/Doctrine/Query/Production/ConditionalPrimary.php index 0edb88246..74aee8b8b 100644 --- a/lib/Doctrine/Query/Production/ConditionalPrimary.php +++ b/lib/Doctrine/Query/Production/ConditionalPrimary.php @@ -98,10 +98,11 @@ class Doctrine_Query_Production_ConditionalPrimary extends Doctrine_Query_Produc return false; } - - public function accept($visitor) + + + /* Getters */ + public function getConditionalExpression() { - $this->_conditionalExpression->accept($visitor); - $visitor->visitConditionalPrimary($this); + return $this->_conditionalExpression; } } diff --git a/lib/Doctrine/Query/Production/ConditionalTerm.php b/lib/Doctrine/Query/Production/ConditionalTerm.php index 5dafb3517..fb0b9bfa0 100644 --- a/lib/Doctrine/Query/Production/ConditionalTerm.php +++ b/lib/Doctrine/Query/Production/ConditionalTerm.php @@ -69,22 +69,9 @@ class Doctrine_Query_Production_ConditionalTerm extends Doctrine_Query_Productio { return $value->buildSql(); } - - /** - * Visitor support - * - * @param object $visitor - */ - public function accept($visitor) - { - foreach ($this->_conditionalFactors as $factor) { - $factor->accept($visitor); - } - $visitor->visitConditionalTerm($this); - } - + + /* Getters */ - public function getConditionalFactors() { return $this->_conditionalFactors; diff --git a/lib/Doctrine/Query/Production/ExistsExpression.php b/lib/Doctrine/Query/Production/ExistsExpression.php index 31f13ddfb..c83032d52 100644 --- a/lib/Doctrine/Query/Production/ExistsExpression.php +++ b/lib/Doctrine/Query/Production/ExistsExpression.php @@ -51,20 +51,9 @@ class Doctrine_Query_Production_ExistsExpression extends Doctrine_Query_Producti { return 'EXISTS (' . $this->_subselect->buildSql() . ')'; } - - /** - * Visitor support - * - * @param object $visitor - */ - public function accept($visitor) - { - $this->_subselect->accept($visitor); - $visitor->visitExistsExpression($this); - } - + + /* Getters */ - public function getSubselect() { return $this->_subselect; diff --git a/lib/Doctrine/Query/Production/Expression.php b/lib/Doctrine/Query/Production/Expression.php index 48843775a..14e0183fe 100644 --- a/lib/Doctrine/Query/Production/Expression.php +++ b/lib/Doctrine/Query/Production/Expression.php @@ -86,22 +86,9 @@ class Doctrine_Query_Production_Expression extends Doctrine_Query_Production { return (is_string($value) ? $value : $value->buildSql()); } - - /** - * Visitor support - * - * @param object $visitor - */ - public function accept($visitor) - { - foreach ($this->_terms as $term) { - $term->accept($visitor); - } - $visitor->visitExpression($this); - } - + + /* Getters */ - public function getTerms() { return $this->_terms; diff --git a/lib/Doctrine/Query/Production/FieldIdentificationVariable.php b/lib/Doctrine/Query/Production/FieldIdentificationVariable.php index 2919ac51d..60cd86d46 100755 --- a/lib/Doctrine/Query/Production/FieldIdentificationVariable.php +++ b/lib/Doctrine/Query/Production/FieldIdentificationVariable.php @@ -24,6 +24,7 @@ * * @package Doctrine * @subpackage Query + * @author Guilherme Blanco * @author Janne Vanhala * @license http://www.opensource.org/licenses/lgpl-license.php LGPL * @link http://www.phpdoctrine.org @@ -74,24 +75,15 @@ class Doctrine_Query_Production_FieldIdentificationVariable extends Doctrine_Que $this->_columnAlias = $parserResult->getTableAliasFromComponentAlias($componentAlias) . Doctrine_Query_Production::SQLALIAS_SEPARATOR . $idx; } - - /** - * Visitor support - * - * @param object $visitor - */ - public function accept($visitor) - { - $visitor->visitFieldIdentificationVariable($this); - } - + + /* Getters */ - public function getFieldAlias() { return $this->_fieldAlias; } - + + public function getColumnAlias() { return $this->_columnAlias; diff --git a/lib/Doctrine/Query/Production/FromClause.php b/lib/Doctrine/Query/Production/FromClause.php index f2a70d030..604ac4beb 100644 --- a/lib/Doctrine/Query/Production/FromClause.php +++ b/lib/Doctrine/Query/Production/FromClause.php @@ -71,22 +71,9 @@ class Doctrine_Query_Production_FromClause extends Doctrine_Query_Production { return $value->buildSql(); } - - /** - * Visitor support - * - * @param object $visitor - */ - public function accept($visitor) - { - foreach ($this->_identificationVariableDeclaration as $decl) { - $decl->accept($visitor); - } - $visitor->visitFromClause($this); - } - + + /* Getters */ - public function getIdentificationVariableDeclarations() { return $this->_identificationVariableDeclaration; diff --git a/lib/Doctrine/Query/Production/IdentificationVariable.php b/lib/Doctrine/Query/Production/IdentificationVariable.php index bf67b5c5b..3fd786d17 100644 --- a/lib/Doctrine/Query/Production/IdentificationVariable.php +++ b/lib/Doctrine/Query/Production/IdentificationVariable.php @@ -62,21 +62,4 @@ class Doctrine_Query_Production_IdentificationVariable extends Doctrine_Query_Pr return $this->_componentAlias; } - - /** - * Visitor support - * - * @param object $visitor - */ - public function accept($visitor) - { - $visitor->visitIdentificationVariable($this); - } - - /* Getters */ - - public function getComponentAlias() - { - return $this->_componentAlias; - } } diff --git a/lib/Doctrine/Query/Production/IdentificationVariableDeclaration.php b/lib/Doctrine/Query/Production/IdentificationVariableDeclaration.php index cb54c7dde..f11dae0c1 100644 --- a/lib/Doctrine/Query/Production/IdentificationVariableDeclaration.php +++ b/lib/Doctrine/Query/Production/IdentificationVariableDeclaration.php @@ -20,7 +20,7 @@ */ /** - * IdentificationVariableDeclaration = RangeVariableDeclaration [IndexBy] {Join [IndexBy]} + * IdentificationVariableDeclaration = RangeVariableDeclaration [IndexBy] {JoinVariableDeclaration} * * @package Doctrine * @subpackage Query @@ -37,7 +37,7 @@ class Doctrine_Query_Production_IdentificationVariableDeclaration extends Doctri protected $_indexBy; - protected $_relations = array(); + protected $_joinVariableDeclarations = array(); public function syntax($paramHolder) @@ -45,7 +45,7 @@ class Doctrine_Query_Production_IdentificationVariableDeclaration extends Doctri $this->_rangeVariableDeclaration = $this->AST('RangeVariableDeclaration', $paramHolder); if ($this->_isNextToken(Doctrine_Query_Token::T_INDEX)) { - $paramHolder->set('componentAlias', $this->_rangeVariableDeclaration); + $paramHolder->set('componentAlias', $this->_rangeVariableDeclaration->getIdentificationVariable()); $this->_indexBy = $this->AST('IndexBy', $paramHolder); $paramHolder->remove('componentAlias'); } @@ -55,75 +55,38 @@ class Doctrine_Query_Production_IdentificationVariableDeclaration extends Doctri $this->_isNextToken(Doctrine_Query_Token::T_INNER) || $this->_isNextToken(Doctrine_Query_Token::T_JOIN) ) { - $i = count($this->_relations); - - $this->_relations[$i]['join'] = $this->AST('Join', $paramHolder); - - if ($this->_isNextToken(Doctrine_Query_Token::T_INDEX)) { - $paramHolder->set('componentAlias', $this->_relations[$i]['join']->getRangeVariableDeclaration()); - $this->_relations[$i]['indexBy'] = $this->AST('IndexBy', $paramHolder); - $paramHolder->remove('componentAlias'); - } + $this->_joinVariableDeclarations[] = $this->AST('JoinVariableDeclaration', $paramHolder); } } public function buildSql() { - // We need to bring the queryComponent and get things from there. - $parserResult = $this->_parser->getParserResult(); - $queryComponent = $parserResult->getQueryComponent($this->_rangeVariableDeclaration); + $str = $this->_rangeVariableDeclaration->buildSql(); - // Retrieving connection - $conn = $this->_em->getConnection(); - - $str = $conn->quoteIdentifier($queryComponent['metadata']->getTableName()) . ' ' - . $conn->quoteIdentifier($parserResult->getTableAliasFromComponentAlias($this->_rangeVariableDeclaration)); - - for ($i = 0, $l = count($this->_relations); $i < $l; $i++) { - $str .= $this->_relations[$i]['join']->buildSql() . ' ' - . ((isset($this->_relations[$i]['indexby'])) ? $this->_relations[$i]['indexby']->buildSql() . ' ' : ''); + for ($i = 0, $l = count($this->_joinVariableDeclarations); $i < $l; $i++) { + $str .= ' ' . $this->_joinVariableDeclarations[$i]->buildSql(); } return $str; } - - /** - * Visitor support - * - * @param object $visitor - */ - public function accept($visitor) - { - $this->_rangeVariableDeclaration->accept($visitor); - if ($this->_indexBy) { - $this->_indexBy->accept($visitor); - } - foreach ($this->_relations as $relation) { - if ($relation['join']) { - $relation['join']->accept($visitor); - } - if ($relation['indexby']) { - $relation['indexby']->accept($visitor); - } - } - $visitor->visitIdentificationVariable($this); - } - + + /* Getters */ - public function getRangeVariableDeclaration() { return $this->_rangeVariableDeclaration; } - + + public function getIndexBy() { return $this->_indexBy; } - - public function getRelations() + + + public function getJoinVariableDeclarations() { - return $this->_relations; + return $this->_joinVariableDeclarations; } } diff --git a/lib/Doctrine/Query/Production/InExpression.php b/lib/Doctrine/Query/Production/InExpression.php index 4ead9cede..dd89222c2 100644 --- a/lib/Doctrine/Query/Production/InExpression.php +++ b/lib/Doctrine/Query/Production/InExpression.php @@ -87,36 +87,21 @@ class Doctrine_Query_Production_InExpression extends Doctrine_Query_Production { return $value->buildSql(); } - - /** - * Visitor support - * - * @param object $visitor - */ - public function accept($visitor) - { - if ($this->_subselect !== null) { - $this->_subselect->accept($visitor); - } else { - foreach ($this->_atoms as $atom) { - $atom->accept($visitor); - } - } - $visitor->visitInExpression($this); - } - + + /* Getters */ - public function isNot() { return $this->_not; } - + + public function getSubselect() { return $this->_subselect; } - + + public function getAtoms() { return $this->_atoms; diff --git a/lib/Doctrine/Query/Production/IndexBy.php b/lib/Doctrine/Query/Production/IndexBy.php index 794446109..fc02a7c91 100644 --- a/lib/Doctrine/Query/Production/IndexBy.php +++ b/lib/Doctrine/Query/Production/IndexBy.php @@ -24,6 +24,7 @@ * * @package Doctrine * @subpackage Query + * @author Guilherme Blanco * @author Janne Vanhala * @license http://www.opensource.org/licenses/lgpl-license.php LGPL * @link http://www.phpdoctrine.org @@ -95,7 +96,6 @@ class Doctrine_Query_Production_IndexBy extends Doctrine_Query_Production ); } - $queryComponent['map'] = $this->_fieldName; $parserResult->setQueryComponent($this->_componentAlias, $queryComponent); } @@ -105,24 +105,15 @@ class Doctrine_Query_Production_IndexBy extends Doctrine_Query_Production { return ''; } - - /** - * Visitor support - * - * @param object $visitor - */ - public function accept($visitor) - { - $visitor->visitIndexBy($this); - } - + + /* Getters */ - public function getComponentAlias() { return $this->_componentAlias; } - + + public function getFieldName() { return $this->_fieldName; diff --git a/lib/Doctrine/Query/Production/Join.php b/lib/Doctrine/Query/Production/Join.php index 2280cb4fb..5c9930fda 100644 --- a/lib/Doctrine/Query/Production/Join.php +++ b/lib/Doctrine/Query/Production/Join.php @@ -24,6 +24,7 @@ * * @package Doctrine * @subpackage Query + * @author Guilherme Blanco * @author Janne Vanhala * @license http://www.opensource.org/licenses/lgpl-license.php LGPL * @link http://www.phpdoctrine.org @@ -74,36 +75,68 @@ class Doctrine_Query_Production_Join extends Doctrine_Query_Production public function buildSql() { - return ''; + $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 relationship conditions. Retrieving AssociationMapping + $queryComponent = $this->_rangeVariableDeclaration->getQueryComponent(); + $relationColumns = $queryComponent['relation']->getSourceToTargetKeyColumns(); + $relationConditionExpression = ''; + + // We have an array('localColumn' => 'foreignColumn', ...) here + foreach ($relationColumns 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; + } + + return $sql . ' ON ' . $relationConditionExpression . ' AND (' . $conditionExpression . ')'; } - - /** - * Visitor support - * - * @param object $visitor - */ - public function accept($visitor) - { - $visitor->visitJoin($this); - } - + + /* 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; diff --git a/lib/Doctrine/Query/Production/JoinVariableDeclaration.php b/lib/Doctrine/Query/Production/JoinVariableDeclaration.php new file mode 100755 index 000000000..9c28a3823 --- /dev/null +++ b/lib/Doctrine/Query/Production/JoinVariableDeclaration.php @@ -0,0 +1,70 @@ +. + */ + +/** + * JoinVariableDeclaration = Join [IndexBy] + * + * @package Doctrine + * @subpackage Query + * @author Guilherme Blanco + * @author Janne Vanhala + * @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 diff --git a/lib/Doctrine/Query/Production/LikeExpression.php b/lib/Doctrine/Query/Production/LikeExpression.php index 73d94c427..f14b767e4 100644 --- a/lib/Doctrine/Query/Production/LikeExpression.php +++ b/lib/Doctrine/Query/Production/LikeExpression.php @@ -69,30 +69,21 @@ class Doctrine_Query_Production_LikeExpression extends Doctrine_Query_Production return (($this->_not) ? 'NOT ' : '') . 'LIKE ' . $this->_expression->buildSql() . (($this->_escapeString !== null) ? ' ESCAPE ' . $this->_escapeString : ''); } - - /** - * Visitor support - * - * @param object $visitor - */ - public function accept($visitor) - { - $this->_expression->accept($visitor); - $visitor->visitLikeExpression($this); - } - + + /* Getters */ - public function isNot() { return $this->_not; } - + + public function getExpression() { return $this->_expression; } - + + public function getEscapeString() { return $this->_escapeString; diff --git a/lib/Doctrine/Query/Production/NullComparisonExpression.php b/lib/Doctrine/Query/Production/NullComparisonExpression.php index 83cfa1361..9064f3d98 100755 --- a/lib/Doctrine/Query/Production/NullComparisonExpression.php +++ b/lib/Doctrine/Query/Production/NullComparisonExpression.php @@ -55,19 +55,9 @@ class Doctrine_Query_Production_NullComparisonExpression extends Doctrine_Query_ { return 'IS ' . (($this->_not) ? 'NOT ' : '') . 'NULL'; } - - /** - * Visitor support - * - * @param object $visitor - */ - public function accept($visitor) - { - $visitor->visitNullComparisonExpression($this); - } - + + /* Getters */ - public function isNot() { return $this->_not; diff --git a/lib/Doctrine/Query/Production/PathExpressionEndingWithAsterisk.php b/lib/Doctrine/Query/Production/PathExpressionEndingWithAsterisk.php index 48b208530..d58369090 100644 --- a/lib/Doctrine/Query/Production/PathExpressionEndingWithAsterisk.php +++ b/lib/Doctrine/Query/Production/PathExpressionEndingWithAsterisk.php @@ -153,24 +153,15 @@ class Doctrine_Query_Production_PathExpressionEndingWithAsterisk extends Doctrin return $str; } - - /** - * Visitor support - * - * @param object $visitor - */ - public function accept($visitor) - { - $visitor->visitPathExpressionEndingWithAsterisk($this); - } - + + /* Getters */ - public function getIdentifiers() { return $this->_identifiers; } - + + public function getQueryComponent() { return $this->_queryComponent; diff --git a/lib/Doctrine/Query/Production/QuantifiedExpression.php b/lib/Doctrine/Query/Production/QuantifiedExpression.php index 1bb81c191..6d55b3f63 100644 --- a/lib/Doctrine/Query/Production/QuantifiedExpression.php +++ b/lib/Doctrine/Query/Production/QuantifiedExpression.php @@ -69,25 +69,15 @@ class Doctrine_Query_Production_QuantifiedExpression extends Doctrine_Query_Prod { return $this->_type . ' (' . $this->_subselect->buildSql() . ')'; } - - /** - * Visitor support - * - * @param object $visitor - */ - public function accept($visitor) - { - $this->_subselect->accept($visitor); - $visitor->visitQuantifiedExpression($this); - } - + + /* Getters */ - public function getType() { return $this->_type; } - + + public function getSubselect() { return $this->_subselect; diff --git a/lib/Doctrine/Query/Production/RangeVariableDeclaration.php b/lib/Doctrine/Query/Production/RangeVariableDeclaration.php index 5ca043d81..f0ecf2799 100644 --- a/lib/Doctrine/Query/Production/RangeVariableDeclaration.php +++ b/lib/Doctrine/Query/Production/RangeVariableDeclaration.php @@ -35,6 +35,8 @@ class Doctrine_Query_Production_RangeVariableDeclaration extends Doctrine_Query_ { protected $_identifiers = array(); + protected $_queryComponent; + protected $_identificationVariable; @@ -99,14 +101,19 @@ class Doctrine_Query_Production_RangeVariableDeclaration extends Doctrine_Query_ $this->_semanticalWithSingleIdentifier(); } } - - return $this->_identificationVariable; } public function buildSql() { - return ''; + // 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)); } @@ -123,7 +130,7 @@ class Doctrine_Query_Production_RangeVariableDeclaration extends Doctrine_Query_ $classMetadata = $this->_em->getClassMetadata($componentName); // Building queryComponent - $queryComponent = array( + $this->_queryComponent = array( 'metadata' => $classMetadata, 'parent' => null, 'relation' => null, @@ -144,7 +151,7 @@ class Doctrine_Query_Production_RangeVariableDeclaration extends Doctrine_Query_ //echo "Identification Variable: " .$this->_identificationVariable . "\n"; $tableAlias = $parserResult->generateTableAlias($classMetadata->getClassName()); - $parserResult->setQueryComponent($this->_identificationVariable, $queryComponent); + $parserResult->setQueryComponent($this->_identificationVariable, $this->_queryComponent); $parserResult->setTableAlias($tableAlias, $this->_identificationVariable); } @@ -158,8 +165,8 @@ class Doctrine_Query_Production_RangeVariableDeclaration extends Doctrine_Query_ // Retrieve the base component try { - $queryComponent = $parserResult->getQueryComponent($this->_identifiers[0]); - $classMetadata = $queryComponent['metadata']; + $this->_queryComponent = $parserResult->getQueryComponent($this->_identifiers[0]); + $classMetadata = $this->_queryComponent['metadata']; $className = $classMetadata->getClassName(); $parent = $path = $this->_identifiers[0]; } catch (Doctrine_Exception $e) { @@ -175,8 +182,8 @@ class Doctrine_Query_Production_RangeVariableDeclaration extends Doctrine_Query_ if ($parserResult->hasQueryComponent($path)) { // We already have the query component on hands, get it - $queryComponent = $parserResult->getQueryComponent($path); - $classMetadata = $queryComponent['metadata']; + $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) { @@ -204,7 +211,7 @@ class Doctrine_Query_Production_RangeVariableDeclaration extends Doctrine_Query_ $relation = $classMetadata->getAssociationMapping($relationName); $targetClassMetadata = $this->_em->getClassMetadata($relation->getTargetEntityName()); - $queryComponent = array( + $this->_queryComponent = array( 'metadata' => $targetClassMetadata, 'parent' => $parent, 'relation' => $relation, @@ -228,29 +235,24 @@ class Doctrine_Query_Production_RangeVariableDeclaration extends Doctrine_Query_ $tableAlias = $parserResult->generateTableAlias($targetClassMetadata->getClassName()); - //echo "Table alias: " . $tableAlias . "\n"; - - $parserResult->setQueryComponent($this->_identificationVariable, $queryComponent); + $parserResult->setQueryComponent($this->_identificationVariable, $this->_queryComponent); $parserResult->setTableAlias($tableAlias, $this->_identificationVariable); } - - /** - * Visitor support - * - * @param object $visitor - */ - public function accept($visitor) - { - $visitor->visitRangeVariableDeclaration($this); - } - + + /* Getters */ - public function getIdentifiers() { return $this->_identifiers; } - + + + public function getQueryComponent() + { + return $this->_queryComponent; + } + + public function getIdentificationVariable() { return $this->_identificationVariable; diff --git a/lib/Doctrine/Query/Production/SelectClause.php b/lib/Doctrine/Query/Production/SelectClause.php index 0d3fd6a7e..ec7588f07 100644 --- a/lib/Doctrine/Query/Production/SelectClause.php +++ b/lib/Doctrine/Query/Production/SelectClause.php @@ -85,27 +85,15 @@ class Doctrine_Query_Production_SelectClause extends Doctrine_Query_Production { return $value->buildSql(); } - - /** - * Visitor support - * - * @param object $visitor - */ - public function accept($visitor) - { - foreach ($this->_selectExpressions as $expression) { - $expression->accept($visitor); - } - $visitor->visitSelectClause($this); - } - + + /* Getters */ - public function isDistinct() { return $this->_isDistinct; } - + + public function getSelectExpressions() { return $this->_selectExpressions; diff --git a/lib/Doctrine/Query/Production/SelectExpression.php b/lib/Doctrine/Query/Production/SelectExpression.php index e20d86596..ff1882921 100644 --- a/lib/Doctrine/Query/Production/SelectExpression.php +++ b/lib/Doctrine/Query/Production/SelectExpression.php @@ -190,4 +190,23 @@ class Doctrine_Query_Production_SelectExpression extends Doctrine_Query_Producti { return ! is_string($value); } + + + /* Getters */ + public function getLeftExpression() + { + return $this->_leftExpression; + } + + + public function isSubselect() + { + return $this->_isSubselect; + } + + + public function getFieldIdentificationVariable() + { + return $this->_fieldIdentificationVariable; + } } diff --git a/lib/Doctrine/Query/Production/SelectStatement.php b/lib/Doctrine/Query/Production/SelectStatement.php index 63d13cd8c..661422f2c 100644 --- a/lib/Doctrine/Query/Production/SelectStatement.php +++ b/lib/Doctrine/Query/Production/SelectStatement.php @@ -93,58 +93,39 @@ class Doctrine_Query_Production_SelectStatement extends Doctrine_Query_Productio . (($this->_havingClause !== null) ? ' ' . $this->_havingClause->buildSql() : '') . (($this->_orderByClause !== null) ? ' ' . $this->_orderByClause->buildSql() : ''); } - - /** - * Visitor support - * - * @param object $visitor - */ - public function accept($visitor) - { - $this->_selectClause->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->visitSelectStatement($this); - } - + + /* 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; diff --git a/lib/Doctrine/Query/Production/SimpleConditionalExpression.php b/lib/Doctrine/Query/Production/SimpleConditionalExpression.php index ce3f58076..f93a3380e 100644 --- a/lib/Doctrine/Query/Production/SimpleConditionalExpression.php +++ b/lib/Doctrine/Query/Production/SimpleConditionalExpression.php @@ -106,26 +106,15 @@ class Doctrine_Query_Production_SimpleConditionalExpression extends Doctrine_Que return $token['type']; } - - /** - * Visitor support - * - * @param object $visitor - */ - public function accept($visitor) - { - $this->_leftExpression->accept($visitor); - $this->_rightExpression->accept($visitor); - $visitor->visitSimpleConditionalExpression($this); - } - + + /* Getters */ - public function getLeftExpression() { return $this->_leftExpression; } - + + public function getRightExpression() { return $this->_rightExpression; diff --git a/lib/Doctrine/Query/Production/WhereClause.php b/lib/Doctrine/Query/Production/WhereClause.php index ac14267d2..8f4edf122 100644 --- a/lib/Doctrine/Query/Production/WhereClause.php +++ b/lib/Doctrine/Query/Production/WhereClause.php @@ -49,18 +49,9 @@ class Doctrine_Query_Production_WhereClause extends Doctrine_Query_Production { return 'WHERE ' . $this->_conditionalExpression->buildSql(); } - - /** - * Visitor support. - */ - public function accept($visitor) - { - $this->_conditionalExpression->accept($visitor); - $visitor->visitWhereClause($this); - } - + + /* Getters */ - public function getConditionalExpression() { return $this->_conditionalExpression; diff --git a/lib/Doctrine/Query/SqlBuilder.php b/lib/Doctrine/Query/SqlBuilder.php index 59e82830d..b8f2c75e3 100755 --- a/lib/Doctrine/Query/SqlBuilder.php +++ b/lib/Doctrine/Query/SqlBuilder.php @@ -80,7 +80,7 @@ abstract class Doctrine_Query_SqlBuilder // Here we follow the SQL-99 specifications available at: // http://savage.net.au/SQL/sql-99.bnf - + // End of Common SQL generations diff --git a/query-language.txt b/query-language.txt index ac40a3d12..4762e9de8 100644 --- a/query-language.txt +++ b/query-language.txt @@ -37,7 +37,8 @@ OrderByItem = Expression ["ASC" | "DESC"] GroupByItem = PathExpression UpdateItem = PathExpression "=" (Expression | "NULL") -IdentificationVariableDeclaration = RangeVariableDeclaration [IndexBy] {Join [IndexBy]} +IdentificationVariableDeclaration = RangeVariableDeclaration [IndexBy] {JoinVariableDeclaration} +JoinVariableDeclaration = Join [IndexBy] RangeVariableDeclaration = identifier {"." identifier} [["AS"] IdentificationVariable] VariableDeclaration = identifier [["AS"] IdentificationVariable] IdentificationVariable = identifier diff --git a/tests/Orm/Query/SelectSqlGenerationTest.php b/tests/Orm/Query/SelectSqlGenerationTest.php index 92c0570f4..49f582ff6 100755 --- a/tests/Orm/Query/SelectSqlGenerationTest.php +++ b/tests/Orm/Query/SelectSqlGenerationTest.php @@ -167,4 +167,13 @@ class Orm_Query_SelectSqlGenerationTest extends Doctrine_OrmTestCase ); } + + public function testPlainJoinWithoutClause() + { + $this->assertSqlGeneration( + 'SELECT u.id, a.id FROM CmsUser u LEFT JOIN u.articles a', + 'SELECT cu.id AS cu__id, ca.id AS ca__id FROM cms_user cu LEFT JOIN cms_article ca ON ca.user_id = cu.id WHERE 1 = 1' + ); + } + } \ No newline at end of file