Changeset 4451 for trunk/lib/Doctrine
- Timestamp:
- 05/27/08 04:44:08 (8 months ago)
- Location:
- trunk/lib/Doctrine/Query
- Files:
-
- 1 added
- 9 modified
-
AbstractResult.php (modified) (1 diff)
-
Parser.php (modified) (1 diff)
-
ParserResult.php (modified) (2 diffs)
-
Production/FieldIdentificationVariable.php (added)
-
Production/IdentificationVariable.php (modified) (1 diff)
-
Production/PathExpression.php (modified) (4 diffs)
-
Production/PathExpressionEndingWithAsterisk.php (modified) (5 diffs)
-
Production/RangeVariableDeclaration.php (modified) (3 diffs)
-
Production/SelectExpression.php (modified) (7 diffs)
-
Production/VariableDeclaration.php (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/lib/Doctrine/Query/AbstractResult.php
r4422 r4451 133 133 134 134 /** 135 * Get the component alias for a given query component 136 * 137 * @param array $queryComponent The query component 138 * @param string Component alias 139 */ 140 public function getComponentAlias($queryComponent) 141 { 142 return array_search($queryComponent, $this->_queryComponents);; 143 } 144 145 146 /** 135 147 * Whether or not this object has a declaration for given component alias. 136 148 * -
trunk/lib/Doctrine/Query/Parser.php
r4422 r4451 115 115 { 116 116 $this->_scanner = new Doctrine_Query_Scanner($dql); 117 $this->_parserResult = new Doctrine_Query_ParserResult();118 117 $this->_sqlBuilder = Doctrine_Query_SqlBuilder::fromConnection($connection); 119 118 $this->_keywordTable = new Doctrine_Query_Token(); 119 120 $this->_parserResult = new Doctrine_Query_ParserResult( 121 '', 122 array( // queryComponent 123 'dctrn' => array( 124 'metadata' => null, 125 'parent' => null, 126 'relation' => null, 127 'map' => null, 128 'scalar' => null, 129 ), 130 ), 131 array( // tableAliasMap 132 'dctrn' => 'dctrn', 133 ) 134 ); 120 135 121 136 $this->free(true); -
trunk/lib/Doctrine/Query/ParserResult.php
r4422 r4451 44 44 protected $_tableAliasSeeds = array(); 45 45 46 /** 47 * Simple array of keys representing the fields used in query. 48 * 49 * @var array $_queryFields 50 */ 51 protected $_queryFields = array(); 52 46 53 47 54 /** … … 60 67 { 61 68 return $this->_data; 69 } 70 71 72 /** 73 * Defines the mapping fields. 74 * 75 * @param array $queryFields Query fields. 76 */ 77 public function setQueryComponents(array $queryFields) 78 { 79 $this->_queryFields = $queryFields; 80 } 81 82 83 /** 84 * Sets the declaration for given field alias. 85 * 86 * @param string $fieldAlias The field alias to set the declaration to. 87 * @param string $queryField Alias declaration. 88 */ 89 public function setQueryField($fieldAlias, array $queryField) 90 { 91 $this->_queryFields[$fieldAlias] = $queryField; 92 } 93 94 95 /** 96 * Gets the mapping fields. 97 * 98 * @return array Query fields. 99 */ 100 public function getQueryFields() 101 { 102 return $this->_queryComponents; 103 } 104 105 106 /** 107 * Get the declaration for given field alias. 108 * 109 * @param string $fieldAlias The field alias the retrieve the declaration from. 110 * @return array Alias declaration. 111 */ 112 public function getQueryField($fieldAlias) 113 { 114 if ( ! isset($this->_queryFields[$fieldAlias])) { 115 throw new Doctrine_Query_Exception('Unknown query field ' . $fieldAlias); 116 } 117 118 return $this->_queryFields[$fieldAlias]; 119 } 120 121 122 /** 123 * Whether or not this object has a declaration for given field alias. 124 * 125 * @param string $fieldAlias Field alias the retrieve the declaration from. 126 * @return boolean True if this object has given alias, otherwise false. 127 */ 128 public function hasQueryField($fieldAlias) 129 { 130 return isset($this->_queryFields[$fieldAlias]); 62 131 } 63 132 -
trunk/lib/Doctrine/Query/Production/IdentificationVariable.php
r4422 r4451 25 25 * @package Doctrine 26 26 * @subpackage Query 27 * @author Guilherme Blanco <guilhermeblanco@hotmail.com> 27 28 * @author Janne Vanhala <jpvanhal@cc.hut.fi> 28 29 * @license http://www.opensource.org/licenses/lgpl-license.php LGPL -
trunk/lib/Doctrine/Query/Production/PathExpression.php
r4431 r4451 38 38 protected $_fieldName; 39 39 40 pr ivate$_queryComponent;40 protected $_queryComponent; 41 41 42 42 … … 68 68 69 69 // Check if we have more than one queryComponent defined 70 if (count($queryComponents) != 1) {70 if (count($queryComponents) != 2) { 71 71 $this->_parser->semanticalError("Undefined component alias for field '{$this->_fieldName}'", $this->_parser->token); 72 72 } … … 74 74 // Retrieve ClassMetadata 75 75 $k = array_keys($queryComponents); 76 $componentAlias = $k[ 0];76 $componentAlias = $k[1]; 77 77 78 78 $this->_queryComponent = $queryComponents[$componentAlias]; … … 142 142 // Retrieve ClassMetadata 143 143 $k = array_keys($queryComponents); 144 $componentAlias = $k[ 0];144 $componentAlias = $k[1]; 145 145 } 146 146 -
trunk/lib/Doctrine/Query/Production/PathExpressionEndingWithAsterisk.php
r4422 r4451 35 35 protected $_identifiers = array(); 36 36 37 protected $_queryComponent; 38 37 39 38 40 public function syntax($paramHolder) … … 56 58 if (($l = count($this->_identifiers)) > 0) { 57 59 // We are dealing with component{.component}.* 58 $classMetadata = null; 60 $path = $this->_identifiers[0]; 61 $this->_queryComponent = $parserResult->getQueryComponent($path); 59 62 60 for ($i = 0; $i < $l; $i++) { 63 // We should have a semantical error if the queryComponent does not exists yet 64 if ($this->_queryComponent === null) { 65 $this->_parser->semanticalError("Undefined component alias for '{$path}'", $this->_parser->token); 66 } 67 68 // Initializing ClassMetadata 69 $classMetadata = $this->_queryComponent['metadata']; 70 71 // Looping through relations 72 for ($i = 1; $i < $l; $i++) { 61 73 $relationName = $this->_identifiers[$i]; 74 $path .= '.' . $relationName; 62 75 63 // We are still checking for relations 64 if ( $classMetadata !== null && ! $classMetadata->hasRelation($relationName)) { 76 if ( ! $classMetadata->hasRelation($relationName)) { 65 77 $className = $classMetadata->getClassName(); 66 78 67 $this->_parser->semanticalError("Relation '{$relationName}' does not exist in component '{$className}'"); 79 $this->_parser->semanticalError( 80 "Relation '{$relationName}' does not exist in component '{$className}' when trying to get the path '{$path}'", 81 $this->_parser->token 82 ); 83 } 68 84 69 // Assigning new ClassMetadata70 $classMetadata = $classMetadata->getRelation($relationName)->getClassMetadata();71 } elseif ( $classMetadata === null ) {72 $queryComponent = $parserResult->getQueryComponent($relationName);85 // We inspect for queryComponent of relations, since we are using them 86 if ( ! $parserResult->hasQueryComponent($path)) { 87 $this->_parser->semanticalError("Cannot use the path '{$path}' without defining it in FROM.", $this->_parser->token); 88 } 73 89 74 // We should have a semantical error if the queryComponent does not exists yet 75 if ($queryComponent === null) { 76 $this->_parser->semanticalError("Undefined component alias for relation '{$relationName}'"); 77 } 90 // Assigning new queryComponent and classMetadata 91 $this->_queryComponent = $parserResult->getQueryComponent($path); 78 92 79 // Initializing ClassMetadata 80 $classMetadata = $queryComponent['metadata']; 81 } 93 $classMetadata = $this->_queryComponent['metadata']; 82 94 } 83 95 } else { … … 86 98 $queryComponents = $parserResult->getQueryComponents(); 87 99 88 if (count($queryComponents) != 1) {100 if (count($queryComponents) != 2) { 89 101 $this->_parser->semanticalError( 90 102 "Cannot use * as selector expression for multiple components." … … 95 107 // since we have it on hands now. 96 108 $k = array_keys($queryComponents); 97 $this->_identifiers[] = $k[0]; 109 $componentAlias = $k[1]; 110 111 $this->_queryComponent = $queryComponents[$componentAlias]; 98 112 } 99 113 } … … 102 116 public function buildSql() 103 117 { 104 return ''; 118 // Basic handy variables 119 $parserResult = $this->_parser->getParserResult(); 120 121 // Retrieving connection 122 $manager = Doctrine_EntityManager::getManager(); 123 $conn = $manager->getConnection(); 124 125 // Looking for componentAlias to fetch 126 $componentAlias = implode('.', $this->_identifiers); 127 128 if (count($this->_identifiers) == 0) { 129 $queryComponents = $parserResult->getQueryComponents(); 130 131 // Retrieve ClassMetadata 132 $k = array_keys($queryComponents); 133 $componentAlias = $k[1]; 134 } 135 136 // Generating the SQL piece 137 $fields = $this->_queryComponent['metadata']->getMappedColumns(); 138 $tableAlias = $parserResult->getTableAliasFromComponentAlias($componentAlias); 139 $str = ''; 140 141 foreach ($fields as $fieldName => $fieldMap) { 142 $str .= ($str != '') ? ', ' : ''; 143 144 // DB Field name 145 $column = $tableAlias . '.' . $this->_queryComponent['metadata']->getColumnName($fieldName); 146 $column = $conn->quoteIdentifier($column); 147 148 // DB Field alias 149 $columnAlias = $tableAlias . '__' . $this->_queryComponent['metadata']->getColumnName($fieldName); 150 $columnAlias = $conn->quoteIdentifier($columnAlias); 151 152 $str .= $column . ' AS ' . $columnAlias; 153 } 154 155 return $str; 105 156 } 106 157 } -
trunk/lib/Doctrine/Query/Production/RangeVariableDeclaration.php
r4431 r4451 130 130 'relation' => null, 131 131 'map' => null, 132 ' agg'=> null,132 'scalar' => null, 133 133 ); 134 134 } catch (Doctrine_Exception $e) { … … 174 174 for ($i = 1, $l = count($this->_identifiers); $i < $l; $i++) { 175 175 $relationName = $this->_identifiers[$i]; 176 $path = '.' . $relationName;176 $path .= '.' . $relationName; 177 177 178 178 if ($parserResult->hasQueryComponent($path)) { … … 212 212 'relation' => $relation, 213 213 'map' => null, 214 ' agg'=> null,214 'scalar' => null, 215 215 ); 216 216 -
trunk/lib/Doctrine/Query/Production/SelectExpression.php
r4431 r4451 39 39 protected $_isSubselect; 40 40 41 protected $_ identificationVariable;41 protected $_fieldIdentificationVariable; 42 42 43 43 private $__columnAliasInSql; … … 52 52 if ($this->_isPathExpressionEndingWithAsterisk()) { 53 53 $this->_leftExpression = $this->AST('PathExpressionEndingWithAsterisk', $paramHolder); 54 55 $fieldName = implode('.', $this->_leftExpression->getIdentifiers()) . '.*'; 54 56 } elseif(($this->_isSubselect = $this->_isSubselect()) === true) { 55 57 $this->_parser->match('('); 56 58 $this->_leftExpression = $this->AST('Subselect', $paramHolder); 57 59 $this->_parser->match(')'); 60 61 // [TODO] Any way to make it more fancy for user error? 62 $fieldName = '<Subselect>'; 58 63 } else { 59 64 $this->_leftExpression = $this->AST('Expression', $paramHolder); 65 66 // [TODO] Any way to make it more fancy for user error? 67 $fieldName = '<Expression>'; 60 68 } 61 69 … … 65 73 66 74 if ($this->_isNextToken(Doctrine_Query_Token::T_IDENTIFIER)) { 67 $this->_identificationVariable = $this->AST('IdentificationVariable', $paramHolder); 75 $paramHolder->set('fieldName', $fieldName); 76 77 // Will return an identifier, with the semantical check already applied 78 $this->_fieldIdentificationVariable = $this->AST('FieldIdentificationVariable', $paramHolder); 79 80 $paramHolder->remove('fieldName'); 68 81 } 69 82 } … … 72 85 public function semantical($paramHolder) 73 86 { 87 $parserResult = $this->_parser->getParserResult(); 88 74 89 // Here we inspect for duplicate IdentificationVariable, and if the 75 90 // left expression needs the identification variable. If yes, check 76 91 // its existance. 77 if ($this->_leftExpression instanceof Doctrine_Query_Production_PathExpressionEndingWithAsterisk && $this->_ identificationVariable !== null) {92 if ($this->_leftExpression instanceof Doctrine_Query_Production_PathExpressionEndingWithAsterisk && $this->_fieldIdentificationVariable !== null) { 78 93 $this->_parser->semanticalError( 79 94 "Cannot assign an identification variable to a path expression with asterisk (ie. foo.bar.* AS foobaz)." … … 83 98 $this->_leftExpression->semantical($paramHolder); 84 99 85 /*if ($this->_identificationVariable !== null) { 86 if ($this->_leftExpression instanceof Doctrine_Query_Production_PathExpression) { 87 // We bring the queryComponent from the class instance 88 // $queryComponent = $this->_leftExpression->getQueryComponent(); 89 } else { 90 // We bring the default queryComponent 91 // $queryComponent = $parserResult->getQueryComponent(null); 92 } 93 94 $idx = count($queryComponent['scalar']); 95 $this->__columnAliasInSql .= '__' . $idx; 96 97 $queryComponent['scalar'][$idx] = $this->_identificationVariable; 98 99 //$parserResult->setQueryComponent($componentAlias, $queryComponent); 100 }*/ 101 102 // We need to add scalar in queryComponent the item alias if identificationvariable is set. 103 //echo "SelectExpression:\n"; 104 //echo get_class($this->_leftExpression) . "\n"; 105 106 // The check for duplicate IdentificationVariable was already done 100 if($this->_fieldIdentificationVariable !== null) { 101 $this->_fieldIdentificationVariable->semantical($paramHolder); 102 } 107 103 } 108 104 … … 110 106 public function buildSql() 111 107 { 112 return $this->_leftExpression->buildSql() ;// . ' AS ' . (($this->_identificationVariable !== null) ? $this->_identificationVariable : '');108 return $this->_leftExpression->buildSql() . $this->_buildColumnAliasInSql(); 113 109 } 114 110 … … 125 121 return $token['value'] === '*'; 126 122 } 123 124 125 protected function _buildColumnAliasInSql() 126 { 127 // Retrieving parser result 128 $parserResult = $this->_parser->getParserResult(); 129 130 switch (get_class($this->_leftExpression)) { 131 case 'Doctrine_Query_Production_PathExpressionEndingWithAsterisk': 132 return ''; 133 break; 134 135 case 'Doctrine_Query_Production_PathExpression': 136 // We bring the queryComponent from the class instance 137 $queryComponent = $this->_leftExpression->getQueryComponent(); 138 break; 139 140 default: 141 // We bring the default queryComponent 142 $queryComponent = $parserResult->getQueryComponent('dctrn'); 143 break; 144 } 145 146 // Retrieving connection 147 $manager = Doctrine_EntityManager::getManager(); 148 $conn = $manager->getConnection(); 149 150 $componentAlias = $parserResult->getComponentAlias($queryComponent); 151 152 if ($this->_fieldIdentificationVariable !== null) { 153 // We need to add scalar map in queryComponent if iidentificationvariable is set. 154 $idx = count($queryComponent['scalar']); 155 $queryComponent['scalar'][$idx] = $this->_fieldIdentificationVariable; 156 $parserResult->setQueryComponent($componentAlias, $queryComponent); 157 158 $columnAlias = $parserResult->getTableAliasFromComponentAlias($componentAlias) . '__' . $idx; 159 } elseif ($this->_leftExpression instanceof Doctrine_Query_Production_PathExpression) { 160 // We need to build the column alias based on column name 161 $columnAlias = $parserResult->getTableAliasFromComponentAlias($componentAlias) 162 . '__' . $queryComponent['metadata']->getColumnName($this->_leftExpression->getFieldName()); 163 } else { 164 // The right thing should be return the index alone... but we need a better solution. 165 // Possible we can search the index for mapped values and add our item there. 166 167 // [TODO] Find another return value. We cant return 0 here. 168 $columnAlias = 'idx__' . 0; 169 } 170 171 return ' AS ' . $conn->quoteIdentifier($columnAlias); 172 } 127 173 } -
trunk/lib/Doctrine/Query/Production/VariableDeclaration.php
r4431 r4451 97 97 'relation' => null, 98 98 'map' => null, 99 ' agg'=> null,99 'scalar' => null, 100 100 ); 101 101 } catch (Doctrine_Exception $e) {