Changeset 4800 for trunk/lib/Doctrine
- Timestamp:
- 08/24/08 20:27:24 (5 months ago)
- Location:
- trunk/lib/Doctrine
- Files:
-
- 12 modified
-
Association.php (modified) (4 diffs)
-
Association/ManyToMany.php (modified) (5 diffs)
-
Association/OneToMany.php (modified) (3 diffs)
-
Association/OneToOne.php (modified) (4 diffs)
-
Entity.php (modified) (2 diffs)
-
Hydrator/RecordDriver.php (modified) (3 diffs)
-
MappingException.php (modified) (2 diffs)
-
Query/SqlExecutor/Abstract.php (modified) (5 diffs)
-
Query/SqlExecutor/MultiTableDelete.php (modified) (2 diffs)
-
Query/SqlExecutor/MultiTableUpdate.php (modified) (3 diffs)
-
Query/SqlExecutor/SingleSelect.php (modified) (1 diff)
-
Query/SqlExecutor/SingleTableDeleteUpdate.php (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/lib/Doctrine/Association.php
r4789 r4800 90 90 * association). 91 91 * 92 * @var unknown_type92 * @var string 93 93 */ 94 94 protected $_targetEntityName; … … 105 105 /** 106 106 * Identifies the field on the owning side that has the mapping for the 107 * association. 107 * association. This is only set on the inverse side of an association. 108 108 * 109 109 * @var string 110 110 */ 111 111 protected $_mappedByFieldName; 112 113 /** 114 * The name of the join table, if any. 115 * 116 * @var string 117 */ 118 protected $_joinTable; 119 120 //protected $_mapping = array(); 112 121 113 122 /** … … 119 128 public function __construct(array $mapping) 120 129 { 130 /*$this->_mapping = array( 131 'fieldName' => null, 132 'sourceEntity' => null, 133 'targetEntity' => null, 134 'mappedBy' => null, 135 'joinColumns' => null, 136 'joinTable' => null, 137 'accessor' => null, 138 'mutator' => null, 139 'optional' => true, 140 'cascade' => array() 141 ); 142 $this->_mapping = array_merge($this->_mapping, $mapping);*/ 121 143 $this->_validateAndCompleteMapping($mapping); 122 123 $this->_sourceEntityName = $mapping['sourceEntity']; 124 $this->_targetEntityName = $mapping['targetEntity']; 144 } 145 146 /** 147 * Validates & completes the mapping. Mapping defaults are applied here. 148 * 149 * @param array $mapping 150 */ 151 protected function _validateAndCompleteMapping(array $mapping) 152 { 153 // Mandatory attributes for both sides 154 if ( ! isset($mapping['fieldName'])) { 155 throw Doctrine_MappingException::missingFieldName(); 156 } 125 157 $this->_sourceFieldName = $mapping['fieldName']; 126 158 127 if ( ! $this->_isOwningSide) {128 $this->_mappedByFieldName = $mapping['mappedBy'];129 }130 }131 132 /**133 * Validates & completes the mapping. Mapping defaults are applied here.134 *135 * @param array $mapping136 * @return array The validated & completed mapping.137 */138 protected function _validateAndCompleteMapping(array $mapping)139 {140 if (isset($mapping['mappedBy'])) {141 // Inverse side, mapping can be found on the owning side.142 $this->_isOwningSide = false;143 } else {144 // Owning side145 }146 147 // Mandatory attributes148 if ( ! isset($mapping['fieldName'])) {149 throw Doctrine_MappingException::missingFieldName();150 }151 159 if ( ! isset($mapping['sourceEntity'])) { 152 160 throw Doctrine_MappingException::missingSourceEntity($mapping['fieldName']); 153 161 } 162 $this->_sourceEntityName = $mapping['sourceEntity']; 163 154 164 if ( ! isset($mapping['targetEntity'])) { 155 165 throw Doctrine_MappingException::missingTargetEntity($mapping['fieldName']); 156 166 } 167 $this->_targetEntityName = $mapping['targetEntity']; 157 168 158 // Optional attributes 159 $this->_customAccessor = isset($mapping['accessor']) ? $mapping['accessor'] : null; 160 $this->_customMutator = isset($mapping['mutator']) ? $mapping['mutator'] : null; 161 $this->_isOptional = isset($mapping['isOptional']) ? (bool)$mapping['isOptional'] : true; 162 $this->_cascades = isset($mapping['cascade']) ? (array)$mapping['cascade'] : array(); 163 164 return $mapping; 165 } 166 167 protected function _validateAndCompleteInverseSideMapping() 168 { 169 // Mandatory and optional attributes for either side 170 if ( ! isset($mapping['mappedBy'])) { 171 // Optional 172 if (isset($mapping['joinTable'])) { 173 $this->_joinTable = $mapping['joinTable']; 174 } 175 } else { 176 $this->_isOwningSide = false; 177 $this->_mappedByFieldName = $mapping['mappedBy']; 178 } 169 179 170 } 171 172 protected function _validateAndCompleteOwningSideMapping() 173 { 174 180 // Optional attributes for both sides 181 if (isset($mapping['accessor'])) { 182 $this->_customAccessor = $mapping['accessor']; 183 } 184 if (isset($mapping['mutator'])) { 185 $this->_customMutator = $mapping['mutator']; 186 } 187 $this->_isOptional = isset($mapping['optional']) ? 188 (bool)$mapping['optional'] : true; 189 $this->_cascades = isset($mapping['cascade']) ? 190 (array)$mapping['cascade'] : array(); 175 191 } 176 192 … … 295 311 { 296 312 return $this->_targetEntityName; 313 } 314 315 /** 316 * Gets the name of the join table. 317 * 318 * @return string 319 */ 320 public function getJoinTable() 321 { 322 return $this->_joinTable; 297 323 } 298 324 -
trunk/lib/Doctrine/Association/ManyToMany.php
r4718 r4800 11 11 */ 12 12 class Doctrine_Association_ManyToMany extends Doctrine_Association 13 { 14 /** 15 * Whether the mapping uses an association class. 16 * 17 * @var boolean 18 */ 19 private $_usesAssociationClass; 20 13 { 21 14 /** 22 15 * The name of the association class (if an association class is used). … … 24 17 * @var string 25 18 */ 26 private $_associationClassName; 27 28 /** 29 * The name of the intermediate table. 30 * 31 * @var string 32 */ 33 private $_relationTableName; 19 private $_associationClass; 34 20 35 21 /** The field in the source table that corresponds to the key in the relation table */ … … 45 31 protected $_targetRelationKeyColumns; 46 32 33 /** 34 * Constructor. 35 * Creates a new ManyToManyMapping. 36 * 37 * @param array $mapping The mapping info. 38 */ 39 public function __construct(array $mapping) 40 { 41 parent::__construct($mapping); 42 } 43 44 /** 45 * Validates and completes the mapping. 46 * 47 * @param array $mapping 48 * @override 49 */ 50 protected function _validateAndCompleteMapping(array $mapping) 51 { 52 parent::_validateAndCompleteMapping($mapping); 53 54 if ($this->isOwningSide()) { 55 // many-many owning MUST have a join table 56 if ( ! isset($mapping['joinTable'])) { 57 throw Doctrine_MappingException::joinTableRequired($mapping['fieldName']); 58 } 59 60 // optional attributes for many-many owning side 61 $this->_associationClass = isset($mapping['associationClass']) ? 62 $mapping['associationClass'] : null; 63 } 64 } 47 65 48 66 /** … … 54 72 public function usesAssociationClass() 55 73 { 56 57 } 58 59 /** 60 * Gets the name of the intermediate table. 61 * 62 * @return string 63 */ 64 public function getRelationTableName() 65 { 66 return $this->_relationTableName; 74 return $this->_associationClass !== null; 67 75 } 68 76 … … 74 82 public function getAssociationClassName() 75 83 { 76 return $this->_associationClass Name;84 return $this->_associationClass; 77 85 } 78 86 } -
trunk/lib/Doctrine/Association/OneToMany.php
r4792 r4800 64 64 { 65 65 parent::__construct($mapping); 66 // one side in one-many can currently never be owning side, we may support that later67 $this->_isOwningSide = false;68 66 } 69 67 … … 77 75 protected function _validateAndCompleteMapping(array $mapping) 78 76 { 79 $mapping = parent::_validateAndCompleteMapping($mapping); 77 parent::_validateAndCompleteMapping($mapping); 78 80 79 // one-side MUST be inverse (must have mappedBy) 81 80 if ( ! isset($mapping['mappedBy'])) { … … 83 82 } 84 83 85 return $mapping; 84 $this->_deleteOrphans = isset($mapping['deleteOrphans']) ? 85 (bool)$mapping['deleteOrphans'] : false; 86 86 } 87 87 -
trunk/lib/Doctrine/Association/OneToOne.php
r4776 r4800 48 48 protected $_targetToSourceKeyColumns = array(); 49 49 50 /** Whether to delete orphaned elements (when nulled out, i.e. $foo->other = null) */ 50 /** 51 * Whether to delete orphaned elements (when nulled out, i.e. $foo->other = null) 52 * 53 * @var boolean 54 */ 51 55 protected $_deleteOrphans = false; 52 56 … … 60 64 { 61 65 parent::__construct($mapping); 62 if ($this->isOwningSide()) {63 $this->_sourceToTargetKeyColumns = $mapping['joinColumns'];64 $this->_targetToSourceKeyColumns = array_flip($this->_sourceToTargetKeyColumns);65 }66 66 } 67 67 … … 73 73 * @override 74 74 */ 75 protected function _validate Mapping(array $mapping)75 protected function _validateAndCompleteMapping(array $mapping) 76 76 { 77 $mapping = parent::_validateMapping($mapping);77 parent::_validateAndCompleteMapping($mapping); 78 78 79 79 if ($this->isOwningSide()) { 80 80 if ( ! isset($mapping['joinColumns'])) { 81 throw Doctrine_MappingException:: missingJoinColumns();81 throw Doctrine_MappingException::invalidMapping($this->_sourceFieldName); 82 82 } 83 $this->_sourceToTargetKeyColumns = $mapping['joinColumns']; 84 $this->_targetToSourceKeyColumns = array_flip($this->_sourceToTargetKeyColumns); 83 85 } 86 87 $this->_deleteOrphans = isset($mapping['deleteOrphans']) ? 88 (bool)$mapping['deleteOrphans'] : false; 84 89 85 90 return $mapping; … … 146 151 $otherEntity = Doctrine_Null::$INSTANCE; 147 152 } 148 $entity->_ rawSetReference($this->_sourceFieldName, $otherEntity);153 $entity->_internalSetReference($this->_sourceFieldName, $otherEntity); 149 154 } 150 155 -
trunk/lib/Doctrine/Entity.php
r4789 r4800 526 526 * @param string $fieldName 527 527 * @param mixed $value 528 */ 529 final public function _internalSetReference($name, $value) 528 * @param boolean $completeBidirectional Whether to complete bidirectional associations 529 * (creating the back-reference). Should only 530 * be used by hydration. 531 */ 532 final public function _internalSetReference($name, $value, $completeBidirectional = false) 530 533 { 531 534 if ($value === Doctrine_Null::$INSTANCE) { … … 547 550 548 551 $this->_references[$name] = $value; 552 553 if ($completeBidirectional && $rel->isOneToOne()) { 554 //TODO: check if $rel is bidirectional, if yes create the back-reference 555 if ($rel->isOwningSide()) { 556 //TODO: how to check if its bidirectional? should be as efficient as possible 557 /*$targetClass = $this->_em->getClassMetadata($rel->getTargetEntityName()); 558 if (($invAssoc = $targetClass->getInverseAssociation($name)) !== null) { 559 $value->_internalSetReference($invAssoc->getSourceFieldName(), $this); 560 }*/ 561 } else { 562 // for sure bi-directional, as there is no inverse side in unidirectional 563 $value->_internalSetReference($rel->getMappedByFieldName(), $this); 564 } 565 } 549 566 } 550 567 -
trunk/lib/Doctrine/Hydrator/RecordDriver.php
r4776 r4800 75 75 $coll = $this->getElementCollection($relatedClass->getClassName()); 76 76 $coll->setReference($entity, $relation); 77 $entity->_internalSetReference($name, $coll );77 $entity->_internalSetReference($name, $coll, true); 78 78 $this->_initializedRelations[$entity->getOid()][$name] = true; 79 79 } … … 109 109 public function setRelatedElement(Doctrine_Entity $entity1, $property, $entity2) 110 110 { 111 $entity1->_internalSetReference($property, $entity2 );111 $entity1->_internalSetReference($property, $entity2, true); 112 112 } 113 113 … … 152 152 } 153 153 154 155 154 } -
trunk/lib/Doctrine/MappingException.php
r4792 r4800 1 1 <?php 2 /* 3 * $Id$ 4 * 5 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 6 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 7 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 8 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 9 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 10 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 11 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 12 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 13 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 14 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 15 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 16 * 17 * This software consists of voluntary contributions made by many individuals 18 * and is licensed under the LGPL. For more information, see 19 * <http://www.phpdoctrine.org>. 20 */ 21 22 #namespace Doctrine::ORM::Exceptions; 2 23 3 24 /** … … 53 74 return new self("OneToMany mapping on field '$fieldName' requires the 'mappedBy' attribute."); 54 75 } 76 77 public static function joinTableRequired($fieldName) 78 { 79 return new self("The mapping of field '$fieldName' requires an the 'joinTable' attribute."); 80 } 81 82 /** 83 * Generic exception for invalid mappings. 84 * 85 * @param string $fieldName 86 */ 87 public static function invalidMapping($fieldName) 88 { 89 return new self("The mapping of field '$fieldName' is invalid."); 90 } 55 91 } 56 92 -
trunk/lib/Doctrine/Query/SqlExecutor/Abstract.php
r4422 r4800 23 23 * Doctrine_Query_QueryResult 24 24 * 25 * @package Doctrine26 * @subpackage Query27 25 * @author Roman Borschel <roman@code-factory.org> 28 26 * @license http://www.opensource.org/licenses/lgpl-license.php LGPL … … 34 32 { 35 33 // [TODO] Remove me later! 36 public $AST;34 //public $AST; 37 35 38 36 protected $_sqlStatements; … … 41 39 { 42 40 // [TODO] Remove me later! 43 $this->AST = $AST;41 //$this->AST = $AST; 44 42 } 45 46 43 47 44 /** … … 55 52 } 56 53 57 58 54 /** 59 55 * Executes all sql statements. … … 63 59 */ 64 60 abstract public function execute(Doctrine_Connection $conn, array $params); 65 66 61 67 62 /** -
trunk/lib/Doctrine/Query/SqlExecutor/MultiTableDelete.php
r4422 r4800 24 24 * Class Table Inheritance (JOINED). 25 25 * 26 * @package Doctrine27 * @subpackage Query28 26 * @author Roman Borschel <roman@code-factory.org> 29 27 * @license http://www.opensource.org/licenses/lgpl-license.php LGPL … … 33 31 * @todo For a good implementation that uses temporary tables see the Hibernate sources: 34 32 * (org.hibernate.hql.ast.exec.MultiTableDeleteExecutor). 33 * @todo Rename to MultiTableDeleteExecutor 35 34 */ 36 35 class Doctrine_Query_SqlExecutor_MultiTableDelete extends Doctrine_Query_SqlExecutor_Abstract 37 36 { 37 /** 38 * Enter description here... 39 * 40 * @param Doctrine_Query_Production $AST 41 */ 42 public function __construct(Doctrine_Query_Production $AST) 43 { 44 // TODO: Inspect the AST, create the necessary SQL queries and store them 45 // in $this->_sqlStatements 46 } 38 47 39 48 /** 49 * Executes all sql statements. 50 * 51 * @param Doctrine_Connection $conn The database connection that is used to execute the queries. 52 * @param array $params The parameters. 53 * @override 54 */ 55 public function execute(Doctrine_Connection $conn, array $params) 56 { 57 //... 58 } 40 59 } -
trunk/lib/Doctrine/Query/SqlExecutor/MultiTableUpdate.php
r4422 r4800 24 24 * Class Table Inheritance (JOINED). 25 25 * 26 * @package Doctrine27 * @subpackage Query28 26 * @author Roman Borschel <roman@code-factory.org> 29 27 * @license http://www.opensource.org/licenses/lgpl-license.php LGPL … … 33 31 * @todo For a good implementation that uses temporary tables see the Hibernate sources: 34 32 * (org.hibernate.hql.ast.exec.MultiTableUpdateExecutor). 33 * @todo Rename to MultiTableUpdateExecutor 35 34 */ 36 35 class Doctrine_Query_SqlExecutor_MultiTableUpdate extends Doctrine_Query_SqlExecutor_Abstract … … 42 41 } 43 42 43 /** 44 * Executes all sql statements. 45 * 46 * @param Doctrine_Connection $conn The database connection that is used to execute the queries. 47 * @param array $params The parameters. 48 * @override 49 */ 50 public function execute(Doctrine_Connection $conn, array $params) 51 { 52 //... 53 } 44 54 } -
trunk/lib/Doctrine/Query/SqlExecutor/SingleSelect.php
r4422 r4800 23 23 * Executor that executes the SQL statement for simple DQL SELECT statements. 24 24 * 25 * @package Doctrine26 * @subpackage Abstract27 25 * @license http://www.opensource.org/licenses/lgpl-license.php LGPL 28 26 * @author Roman Borschel <roman@code-factory.org> -
trunk/lib/Doctrine/Query/SqlExecutor/SingleTableDeleteUpdate.php
r4723 r4800 24 24 * that are mapped to a single table. 25 25 * 26 * @package Doctrine27 * @subpackage SingleTableDeleteUpdate28 26 * @license http://www.opensource.org/licenses/lgpl-license.php LGPL 29 27 * @author Roman Borschel <roman@code-factory.org> … … 31 29 * @link www.phpdoctrine.org 32 30 * @since 2.0 31 * @todo This is exactly the same as SingleSelectExecutor. Unify in SingleStatementExecutor. 33 32 */ 34 33 class Doctrine_Query_SqlExecutor_SingleTableDeleteUpdate extends Doctrine_Query_SqlExecutor_Abstract