1
0
mirror of synced 2024-12-05 03:06:05 +03:00

Some cleanups, docblocks, and a small needed refactoring of ClassMetadataFactory.

This commit is contained in:
romanb 2009-02-05 17:34:44 +00:00
parent efb733d7df
commit deb095f2c8
25 changed files with 241 additions and 947 deletions

View File

@ -13,4 +13,4 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
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>.
and is licensed under the LGPL. For more information, see <http://www.doctrine-project.org>.

View File

@ -54,12 +54,20 @@ abstract class AbstractPlatform
* Constructor.
*/
public function __construct() {}
/**
* Sets whether to quote identifiers.
*/
public function setQuoteIdentifiers($bool)
{
$this->_quoteIdentifiers = (bool)$bool;
}
/**
* Gets whether to quote identifiers.
*
* @return boolean
*/
public function getQuoteIdentifiers()
{
return $this->_quoteIdentifiers;
@ -1752,7 +1760,7 @@ abstract class AbstractPlatform
* @return string
* @todo Remove the ORM dependency
*/
public function writeLimitClauseInSubquery(Doctrine_ClassMetadata $rootClass,
public function writeLimitClauseInSubquery(\Doctrine\ORM\Mapping\ClassMetadata $rootClass,
$query, $limit = false, $offset = false)
{
return $this->modifyLimitQuery($query, $limit, $offset);
@ -1778,7 +1786,6 @@ abstract class AbstractPlatform
* Default conversion defined here converts to integers.
*
* @param array $item
* @return void
*/
public function convertBooleans($item)
{
@ -1797,9 +1804,9 @@ abstract class AbstractPlatform
}
/**
* Enter description here...
* Gets the SQL statement specific for the platform to set the charset.
*
* @param unknown_type $charset
* @param string $charset
* @return string
*/
public function getSetCharsetSql($charset)
@ -1810,7 +1817,7 @@ abstract class AbstractPlatform
/**
* Enter description here...
*
* @param unknown_type $level
* @param integer $level
*/
protected function _getTransactionIsolationLevelSql($level)
{
@ -1831,7 +1838,7 @@ abstract class AbstractPlatform
/**
* Enter description here...
*
* @param unknown_type $level
* @param integer $level
*/
public function getSetTransactionIsolationSql($level)
{
@ -1842,7 +1849,7 @@ abstract class AbstractPlatform
* Gets the default transaction isolation level of the platform.
*
* @return integer The default isolation level.
* @see Doctrine::DBAL::Connection::TRANSACTION_* constants.
* @see Doctrine\DBAL\Connection\TRANSACTION_* constants.
*/
public function getDefaultTransactionIsolationLevel()
{
@ -1851,42 +1858,85 @@ abstract class AbstractPlatform
/* supports*() metods */
/**
* Whether the platform supports sequences.
*
* @return boolean
*/
public function supportsSequences()
{
return false;
}
/**
* Whether the platform supports identity columns.
* Identity columns are columns that recieve an auto-generated value from the
* database on insert of a row.
*
* @return boolean
*/
public function supportsIdentityColumns()
{
return false;
}
/**
* Whether the platform supports indexes.
*
* @return boolean
*/
public function supportsIndexes()
{
return true;
}
/**
* Whether the platform supports transactions.
*
* @return boolean
*/
public function supportsTransactions()
{
return true;
}
/**
* Whether the platform supports savepoints.
*
* @return boolean
*/
public function supportsSavepoints()
{
return true;
}
/**
* Whether the platform supports primary key constraints.
*
* @return boolean
*/
public function supportsPrimaryConstraints()
{
return true;
}
/**
* Whether the platform supports foreign key constraints.
*
* @return boolean
*/
public function supportsForeignKeyConstraints()
{
return true;
}
/**
* Whether the platform supports getting the affected rows or a recent
* update/delete type query.
*
* @return boolean
*/
public function supportsGettingAffectedRows()
{
return true;

View File

@ -1,9 +1,29 @@
<?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.doctrine-project.org>.
*/
namespace Doctrine\DBAL\Platforms;
/**
* Enter description here...
* The SqlitePlatform class describes the specifics and dialects of the SQLite
* database platform.
*
* @since 2.0
*/
@ -537,7 +557,7 @@ class SqlitePlatform extends AbstractPlatform
* This really limits their usefulness and requires SQLite specific handling, so
* we simply say that SQLite does NOT support foreign keys for now...
*
* @return boolean
* @return boolean FALSE
* @override
*/
public function supportsForeignKeyConstraints()

View File

@ -16,14 +16,14 @@
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information, see
* <http://www.phpdoctrine.org>.
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\DBAL\Schema;
/**
* Base class for schema managers. Schema managers are used to inspect and/or
* modify the database schema.
* modify the database schema/structure.
*
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @author Konsta Vesterinen <kvesteri@cc.hut.fi>

View File

@ -16,7 +16,7 @@
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information, see
* <http://www.phpdoctrine.org>.
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\DBAL\Schema;

View File

@ -1,35 +0,0 @@
<?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;
/**
* Entity marker interface.
*
* @author Roman Borschel <roman@code-factory.org>
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @link www.doctrine-project.org
* @since 2.0
* @version $Revision: 4342 $
* @DEPRECATED
*/
interface Doctrine_ORM_Entity
{}

View File

@ -1,6 +1,6 @@
<?php
/*
* $Id: Export.php 4805 2008-08-25 19:11:58Z subzero2000 $
* $Id$
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
@ -16,7 +16,7 @@
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information, see
* <http://www.phpdoctrine.org>.
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\ORM\Export;
@ -27,8 +27,6 @@ use Doctrine\ORM\EntityManager;
* The ClassExporter can generate database schemas/structures from ClassMetadata
* class descriptors.
*
* @package Doctrine
* @subpackage Export
* @author Konsta Vesterinen <kvesteri@cc.hut.fi>
* @author Lukas Smith <smith@pooteeweet.org> (PEAR MDB2 library)
* @author Roman Borschel <roman@code-factory.org>

View File

@ -34,7 +34,7 @@ class Assigned extends AbstractIdGenerator
/**
* Returns the identifier assigned to the given entity.
*
* @param Doctrine\ORM\Entity $entity
* @param object $entity
* @return mixed
* @override
*/

View File

@ -1,168 +0,0 @@
<?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\Internal\Hydration;
/**
* Defines an array hydration strategy.
*
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @link www.phpdoctrine.org
* @since 1.0
* @version $Revision$
* @author Konsta Vesterinen <kvesteri@cc.hut.fi>
* @author Roman Borschel <roman@code-factory.org>
* @DEPRECATED
*/
class Doctrine_ORM_Internal_Hydration_ArrayDriver
{
/**
*
*/
public function getElementCollection($component)
{
return array();
}
/**
*
*/
public function getElement(array $data, $component)
{
return $data;
}
/**
*
*/
public function registerCollection($coll)
{ /* Nothing to do */ }
/**
*
*/
public function initRelatedCollection(array &$data, $name)
{
if ( ! isset($data[$name])) {
$data[$name] = array();
}
}
public function addRelatedIndexedElement(array &$entity1, $property, array &$entity2, $indexField)
{
$entity1[$property][$entity2[$indexField]] = $entity2;
}
public function addRelatedElement(array &$entity1, $property, array &$entity2)
{
$entity1[$property][] = $entity2;
}
public function setRelatedElement(array &$entity1, $property, &$entity2)
{
$entity1[$property] = $entity2;
}
public function isIndexKeyInUse(array &$entity, $assocField, $indexField)
{
return isset($entity[$assocField][$indexField]);
}
public function isFieldSet(array &$entity, $field)
{
return isset($entity[$field]);
}
public function getFieldValue(array &$entity, $field)
{
return $entity[$field];
}
public function &getReferenceValue(array &$entity, $field)
{
return $entity[$field];
}
public function addElementToIndexedCollection(array &$coll, array &$entity, $keyField)
{
$coll[$entity[$keyField]] = $entity;
}
public function addElementToCollection(array &$coll, array &$entity)
{
$coll[] = $entity;
}
/**
*
*/
public function getNullPointer()
{
return null;
}
/**
*
*/
public function getLastKey(&$data)
{
end($data);
return key($data);
}
/**
* Updates the result pointer for an Entity. The result pointers point to the
* last seen instance of each Entity type. This is used for graph construction.
*
* @param array $resultPointers The result pointers.
* @param array $coll The element.
* @param boolean|integer $index Index of the element in the collection.
* @param string $dqlAlias
* @param boolean $oneToOne Whether it is a single-valued association or not.
*/
public function updateResultPointer(&$resultPointers, &$coll, $index, $dqlAlias, $oneToOne)
{
if ($coll === null) {
unset($resultPointers[$dqlAlias]); // Ticket #1228
return;
}
if ($index !== false) {
$resultPointers[$dqlAlias] =& $coll[$index];
return;
}
if ($coll) {
if ($oneToOne) {
$resultPointers[$dqlAlias] =& $coll;
} else {
end($coll);
$resultPointers[$dqlAlias] =& $coll[key($coll)];
}
}
}
/**
*
*/
public function flush()
{ /* Nothing to do */ }
}

View File

@ -1,257 +0,0 @@
<?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.doctrine-project.org>.
*/
#namespace Doctrine\ORM\Internal\Hydration;
/**
* Defines the object hydration strategy.
*
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @link www.doctrine-project.org
* @since 1.0
* @version $Revision$
* @author Konsta Vesterinen <kvesteri@cc.hut.fi>
* @author Roman Borschel <roman@code-factory.org>
* @internal All the methods in this class are performance-sentitive.
* @DEPRECATED
*/
class Doctrine_ORM_Internal_Hydration_ObjectDriver
{
/** Collections initialized by the driver */
protected $_collections = array();
/** Memory for initialized relations */
private $_initializedRelations = array();
/** Null object */
//private $_nullObject;
/** The EntityManager */
private $_em;
private $_uow;
private $_metadataMap = array();
private $_entityData = array();
public function __construct(Doctrine_ORM_EntityManager $em)
{
//$this->_nullObject = Doctrine_ORM_Internal_Null::$INSTANCE;
$this->_em = $em;
$this->_uow = $this->_em->getUnitOfWork();
}
public function getElementCollection($component)
{
$coll = new Doctrine_ORM_Collection($this->_em, $component);
$this->_collections[] = $coll;
return $coll;
}
public function getLastKey($coll)
{
// check needed because of mixed results.
// is_object instead of is_array because is_array is slow on large arrays.
if (is_object($coll)) {
$coll->last();
return $coll->key();
} else {
end($coll);
return key($coll);
}
}
public function initRelatedCollection($entity, $name)
{
$oid = spl_object_hash($entity);
$classMetadata = $this->_metadataMap[$oid];
if ( ! isset($this->_initializedRelations[$oid][$name])) {
$relation = $classMetadata->getAssociationMapping($name);
$relatedClass = $this->_em->getClassMetadata($relation->getTargetEntityName());
$coll = $this->getElementCollection($relatedClass->getClassName());
$coll->_setOwner($entity, $relation);
$coll->_setHydrationFlag(true);
$classMetadata->getReflectionProperty($name)->setValue($entity, $coll);
$this->_initializedRelations[$oid][$name] = true;
$this->_uow->setOriginalEntityProperty($oid, $name, $coll);
}
}
public function registerCollection(Doctrine_ORM_Collection $coll)
{
$this->_collections[] = $coll;
}
public function getNullPointer()
{
//TODO: Return VirtualProxy if lazy association
return null;
}
public function getElement(array $data, $className)
{
$entity = $this->_em->getUnitOfWork()->createEntity($className, $data);
$oid = spl_object_hash($entity);
$this->_metadataMap[$oid] = $this->_em->getClassMetadata($className);
return $entity;
}
/**
* Adds an element to an indexed collection-valued property.
*
* @param <type> $entity1
* @param <type> $property
* @param <type> $entity2
* @param <type> $indexField
*/
public function addRelatedIndexedElement($entity1, $property, $entity2, $indexField)
{
$classMetadata1 = $this->_metadataMap[spl_object_hash($entity1)];
$classMetadata2 = $this->_metadataMap[spl_object_hash($entity2)];
$indexValue = $classMetadata2->getReflectionProperty($indexField)->getValue($entity2);
$classMetadata1->getReflectionProperty($property)->getValue($entity1)->set($indexValue, $entity2);
}
/**
* Adds an element to a collection-valued property.
*
* @param <type> $entity1
* @param <type> $property
* @param <type> $entity2
*/
public function addRelatedElement($entity1, $property, $entity2)
{
$classMetadata1 = $this->_metadataMap[spl_object_hash($entity1)];
$classMetadata1->getReflectionProperty($property)->getValue($entity1)->add($entity2);
}
/**
* Sets a related element.
*
* @param <type> $entity1
* @param <type> $property
* @param <type> $entity2
*/
public function setRelatedElement($entity1, $property, $entity2)
{
$oid = spl_object_hash($entity1);
$classMetadata1 = $this->_metadataMap[$oid];
$classMetadata1->getReflectionProperty($property)->setValue($entity1, $entity2);
$this->_uow->setOriginalEntityProperty($oid, $property, $entity2);
$relation = $classMetadata1->getAssociationMapping($property);
if ($relation->isOneToOne()) {
$targetClass = $this->_em->getClassMetadata($relation->getTargetEntityName());
if ($relation->isOwningSide()) {
// If there is an inverse mapping on the target class its bidirectional
if ($targetClass->hasInverseAssociationMapping($property)) {
$oid2 = spl_object_hash($entity2);
$sourceProp = $targetClass->getInverseAssociationMapping($fieldName)->getSourceFieldName();
$targetClass->getReflectionProperty($sourceProp)->setValue($entity2, $entity1);
//$this->_entityData[$oid2][$sourceProp] = $entity1;
}
} else {
// for sure bidirectional, as there is no inverse side in unidirectional
$mappedByProp = $relation->getMappedByFieldName();
$targetClass->getReflectionProperty($mappedByProp)->setValue($entity2, $entity1);
//$this->_entityData[spl_object_hash($entity2)][$mappedByProp] = $entity1;
}
}
}
public function isIndexKeyInUse($entity, $assocField, $indexField)
{
return $this->_metadataMap[spl_object_hash($entity)]->getReflectionProperty($assocField)
->getValue($entity)->containsKey($indexField);
}
public function isFieldSet($entity, $field)
{
return $this->_metadataMap[spl_object_hash($entity)]->getReflectionProperty($field)
->getValue($entity) !== null;
}
public function getFieldValue($entity, $field)
{
return $this->_metadataMap[spl_object_hash($entity)]->getReflectionProperty($field)
->getValue($entity);
}
public function getReferenceValue($entity, $field)
{
return $this->_metadataMap[spl_object_hash($entity)]->getReflectionProperty($field)
->getValue($entity);
}
public function addElementToIndexedCollection($coll, $entity, $keyField)
{
$coll->set($entity, $this->getFieldValue($keyField, $entity));
}
public function addElementToCollection($coll, $entity)
{
$coll->add($entity);
}
/**
* Updates the result pointer for an Entity. The result pointers point to the
* last seen instance of each Entity type. This is used for graph construction.
*
* @param array $resultPointers The result pointers.
* @param Collection $coll The element.
* @param boolean|integer $index Index of the element in the collection.
* @param string $dqlAlias
* @param boolean $oneToOne Whether it is a single-valued association or not.
*/
public function updateResultPointer(&$resultPointers, &$coll, $index, $dqlAlias, $oneToOne)
{
if ($coll === null) {
unset($resultPointers[$dqlAlias]); // Ticket #1228
return;
}
if ($index !== false) {
$resultPointers[$dqlAlias] = $coll[$index];
return;
}
if ( ! is_object($coll)) {
end($coll);
$resultPointers[$dqlAlias] =& $coll[key($coll)];
} else if ($coll instanceof Doctrine_ORM_Collection) {
if (count($coll) > 0) {
$resultPointers[$dqlAlias] = $coll->last();
}
} else {
$resultPointers[$dqlAlias] = $coll;
}
}
public function flush()
{
// take snapshots from all initialized collections
foreach ($this->_collections as $coll) {
$coll->_takeSnapshot();
$coll->_setHydrationFlag(false);
$this->_uow->addManagedCollection($coll);
}
// clean up
$this->_collections = array();
$this->_initializedRelations = array();
$this->_metadataMap = array();
$this->_entityData = array();
}
}

View File

@ -1,294 +0,0 @@
<?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\Internal\Hydration;
/**
* The hydrator has the tedious task to process result sets returned by the database
* and turn them into useable structures.
*
* Runtime complexity: The following gives the overall number of iterations
* required to process a result set when using identity hydration
* (HYDRATE_IDENTITY_OBJECT or HYDRATE_IDENTITY_ARRAY).
*
* <code>numRowsInResult * numColumnsInResult + numRowsInResult * numClassesInQuery</code>
*
* This comes down to:
*
* <code>(numRowsInResult * (numColumnsInResult + numClassesInQuery))</code>
*
* For scalar hydration (HYDRATE_SCALAR) it's:
*
* <code>numRowsInResult * numColumnsInResult</code>
*
* Note that this is only a crude definition as it also heavily
* depends on the complexity of all the single operations that are performed in
* each iteration.
*
* As can be seen, the number of columns in the result has the most impact on
* the overall performance (apart from the row count, of course), since numClassesInQuery
* is usually pretty low.
* That's why the performance of the _gatherRowData() methods which are responsible
* for the "numRowsInResult * numColumnsInResult" part is crucial to fast hydration.
*
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @link www.doctrine-project.org
* @since 1.0
* @version $Revision: 3192 $
* @author Konsta Vesterinen <kvesteri@cc.hut.fi>
* @author Roman Borschel <roman@code-factory.org>
* @DEPRECATED
*/
class Doctrine_ORM_Internal_Hydration_StandardHydrator extends Doctrine_ORM_Internal_Hydration_AbstractHydrator
{
/**
* Parses the data returned by statement object.
*
* This is method defines the core of Doctrine's object population algorithm.
*
* @param array $aliasMap Array that maps DQL aliases to their components
* (DQL alias => array(
* 'metadata' => Table object,
* 'parent' => Parent DQL alias (if any),
* 'relation' => Relation object (if any),
* 'map' => Custom index to use as the key in the result (if any),
* 'agg' => List of aggregate value names (sql alias => dql alias)
* )
* )
* @return mixed The created object/array graph.
* @throws Doctrine_Hydrator_Exception If the hydration process failed.
*/
public function hydrateResultSet($parserResult)
{
if ($parserResult->getHydrationMode() === null) {
$hydrationMode = $this->_hydrationMode;
} else {
$hydrationMode = $parserResult->getHydrationMode();
}
$stmt = $parserResult->getDatabaseStatement();
if ($hydrationMode == Doctrine_ORM_Query::HYDRATE_NONE) {
return $stmt->fetchAll(PDO::FETCH_NUM);
}
$this->_tableAliases = $parserResult->getTableToClassAliasMap();
$this->_queryComponents = $parserResult->getQueryComponents();
if ($hydrationMode == Doctrine_ORM_Query::HYDRATE_ARRAY) {
$driver = new Doctrine_ORM_Internal_Hydration_ArrayDriver();
} else {
$driver = new Doctrine_ORM_Internal_Hydration_ObjectDriver($this->_em);
}
$s = microtime(true);
reset($this->_queryComponents);
$rootAlias = key($this->_queryComponents);
$rootEntityName = $this->_queryComponents[$rootAlias]['metadata']->getClassName();
// if only one class is involved we can make our lives easier
$isSimpleQuery = count($this->_queryComponents) <= 1;
// Lookup map to quickly discover/lookup existing entities in the result
// It's the identifier "memory"
$identifierMap = array();
// Holds for each class a pointer to the last previously seen element in the result set
$resultPointers = array();
// Holds the values of the identifier/primary key fields of entities,
// separated by a pipe '|' and grouped by DQL class alias (r, u, i, ... whatever)
// The $idTemplate is a prepared template. $id is set to a fresh template when
// starting to process a row.
$id = array();
$idTemplate = array();
if ($parserResult->isMixedQuery() || $hydrationMode == Doctrine_ORM_Query::HYDRATE_SCALAR) {
$result = array();
} else {
$result = $driver->getElementCollection($rootEntityName);
}
if ($stmt === false || $stmt === 0) {
return $result;
}
// Initialize
foreach ($this->_queryComponents as $dqlAlias => $component) {
$identifierMap[$dqlAlias] = array();
$resultPointers[$dqlAlias] = array();
$idTemplate[$dqlAlias] = '';
}
$cache = array();
// Evaluate HYDRATE_SINGLE_SCALAR
if ($hydrationMode == Doctrine_ORM_Query::HYDRATE_SINGLE_SCALAR) {
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
//TODO: Let this exception be raised by Query as QueryException
if (count($result) > 1 || count($result[0]) > 1) {
throw Doctrine_ORM_Exceptions_HydrationException::nonUniqueResult();
}
$result = $this->_gatherScalarRowData($result[0], $cache);
return array_shift($result);
}
$resultCounter = 0;
// Process result set
while ($data = $stmt->fetch(PDO::FETCH_ASSOC)) {
// Evaluate HYDRATE_SCALAR
if ($hydrationMode == Doctrine_ORM_Query::HYDRATE_SCALAR) {
$result[] = $this->_gatherScalarRowData($data, $cache);
continue;
}
// From here on its all about graph construction
// 1) Initialize
$id = $idTemplate; // initialize the id-memory
$nonemptyComponents = array();
$rowData = $this->_gatherRowData($data, $cache, $id, $nonemptyComponents);
// 2) Hydrate the data of the root entity from the current row
// Check for an existing element
$index = false;
if ($isSimpleQuery || ! isset($identifierMap[$rootAlias][$id[$rootAlias]])) {
$element = $driver->getElement($rowData[$rootAlias], $rootEntityName);
if ($field = $this->_getCustomIndexField($rootAlias)) {
if ($parserResult->isMixedQuery()) {
$result[] = array(
$driver->getFieldValue($element, $field) => $element
);
++$resultCounter;
} else {
$driver->addElementToIndexedCollection($result, $element, $field);
}
} else {
if ($parserResult->isMixedQuery()) {
$result[] = array($element);
++$resultCounter;
} else {
$driver->addElementToCollection($result, $element);
}
}
$identifierMap[$rootAlias][$id[$rootAlias]] = $driver->getLastKey($result);
} else {
$index = $identifierMap[$rootAlias][$id[$rootAlias]];
}
$driver->updateResultPointer($resultPointers, $result, $index, $rootAlias, false);
unset($rowData[$rootAlias]);
// end hydrate data of the root component for the current row
// Extract scalar values. They're appended at the end.
if (isset($rowData['scalars'])) {
$scalars = $rowData['scalars'];
unset($rowData['scalars']);
}
// 3) Now hydrate the rest of the data found in the current row, that
// belongs to other (related) entities.
foreach ($rowData as $dqlAlias => $data) {
$index = false;
$map = $this->_queryComponents[$dqlAlias];
$entityName = $map['metadata']->getClassName();
$parent = $map['parent'];
$relation = $map['relation'];
$relationAlias = $relation->getSourceFieldName();
$path = $parent . '.' . $dqlAlias;
// Get a reference to the right element in the result tree.
// This element will get the associated element attached.
if ($parserResult->isMixedQuery() && $parent == $rootAlias) {
$key = key(reset($resultPointers));
// TODO: Exception if $key === null ?
$baseElement =& $resultPointers[$parent][$key];
} else if (isset($resultPointers[$parent])) {
$baseElement =& $resultPointers[$parent];
} else {
unset($resultPointers[$dqlAlias]); // Ticket #1228
continue;
}
// Check the type of the relation (many or single-valued)
if ( ! $relation->isOneToOne()) {
// x-to-many relation
$oneToOne = false;
if (isset($nonemptyComponents[$dqlAlias])) {
$driver->initRelatedCollection($baseElement, $relationAlias);
$indexExists = isset($identifierMap[$path][$id[$parent]][$id[$dqlAlias]]);
$index = $indexExists ? $identifierMap[$path][$id[$parent]][$id[$dqlAlias]] : false;
$indexIsValid = $index !== false ? $driver->isIndexKeyInUse($baseElement, $relationAlias, $index) : false;
if ( ! $indexExists || ! $indexIsValid) {
$element = $driver->getElement($data, $entityName);
if ($field = $this->_getCustomIndexField($dqlAlias)) {
$driver->addRelatedIndexedElement($baseElement, $relationAlias, $element, $field);
} else {
$driver->addRelatedElement($baseElement, $relationAlias, $element);
}
$identifierMap[$path][$id[$parent]][$id[$dqlAlias]] = $driver->getLastKey(
$driver->getReferenceValue($baseElement, $relationAlias));
}
} else if ( ! $driver->isFieldSet($baseElement, $relationAlias)) {
if ($hydrationMode == Doctrine_ORM_Query::HYDRATE_ARRAY) {
$baseElement[$relationAlias] = array();
} else {
$driver->setRelatedElement($baseElement, $relationAlias,
$driver->getElementCollection($entityName));
}
}
} else {
// x-to-one relation
$oneToOne = true;
if ( ! isset($nonemptyComponents[$dqlAlias]) &&
! $driver->isFieldSet($baseElement, $relationAlias)) {
$driver->setRelatedElement($baseElement, $relationAlias,
$driver->getNullPointer());
} else if ( ! $driver->isFieldSet($baseElement, $relationAlias)) {
$driver->setRelatedElement($baseElement, $relationAlias,
$driver->getElement($data, $entityName));
}
}
if ($hydrationMode == Doctrine_ORM_Query::HYDRATE_ARRAY) {
$coll =& $baseElement[$relationAlias];
} else {
$coll = $driver->getReferenceValue($baseElement, $relationAlias);
}
if ($coll !== null) {
$driver->updateResultPointer($resultPointers, $coll, $index, $dqlAlias, $oneToOne);
}
}
// Append scalar values to mixed result sets
if (isset($scalars)) {
foreach ($scalars as $name => $value) {
$result[$resultCounter - 1][$name] = $value;
}
}
}
$stmt->closeCursor();
$driver->flush();
$e = microtime(true);
echo 'Hydration took: ' . ($e - $s) . PHP_EOL;
return $result;
}
}

View File

@ -1,65 +0,0 @@
<?php
/*
* $Id: Null.php 4723 2008-08-01 18:46:14Z romanb $
*
* 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\Internal;
/**
* Null class representing a null value that has been fetched from
* the database or a fetched, empty association. This is for internal use only.
* User code should never deal with this null object.
*
* Semantics are as follows:
*
* Regular PHP null : Value is undefined. When a field with that value is accessed
* and lazy loading is used the database is queried.
*
* Null object: Null valued of a field or empty association that has already been loaded.
* On access, the database is not queried.
*
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @link www.phpdoctrine.org
* @since 1.0
* @version $Revision: 4723 $
* @author Konsta Vesterinen <kvesteri@cc.hut.fi>
* @todo No longer needed?
* @DEPRECATED
*/
// static initializer
Doctrine_ORM_Internal_Null::$INSTANCE = new Doctrine_ORM_Internal_Null();
final class Doctrine_ORM_Internal_Null
{
public static $INSTANCE;
public function __construct() {}
public static function getInstance()
{
return self::$INSTANCE;
}
public function exists()
{
return false;
}
public function __toString()
{
return '';
}
}

View File

@ -23,6 +23,7 @@ namespace Doctrine\ORM\Mapping;
use \ReflectionClass;
use Doctrine\Common\DoctrineException;
use Doctrine\ORM\Exceptions\MappingException;
/**
* A <tt>ClassMetadata</tt> instance holds all the information (metadata) of an entity and
@ -506,7 +507,7 @@ class ClassMetadata
public function getFieldMapping($fieldName)
{
if ( ! isset($this->_fieldMappings[$fieldName])) {
throw Doctrine_MappingException::mappingNotFound($fieldName);
throw MappingException::mappingNotFound($fieldName);
}
return $this->_fieldMappings[$fieldName];
}
@ -620,10 +621,10 @@ class ClassMetadata
{
// Check mandatory fields
if ( ! isset($mapping['fieldName'])) {
throw Doctrine_ORM_Exceptions_MappingException::missingFieldName();
throw MappingException::missingFieldName();
}
if ( ! isset($mapping['type'])) {
throw Doctrine_ORM_Exceptions_MappingException::missingType();
throw MappingException::missingType();
}
if ( ! is_object($mapping['type'])) {
@ -648,9 +649,9 @@ class ClassMetadata
if (isset($mapping['idGenerator'])) {
if ( ! $this->_isIdGeneratorType($mapping['idGenerator'])) {
//TODO: check if the idGenerator specifies an existing generator by name
throw Doctrine_MappingException::invalidGeneratorType($mapping['idGenerator']);
throw MappingException::invalidGeneratorType($mapping['idGenerator']);
} else if (count($this->_identifier) > 1) {
throw Doctrine_MappingException::generatorNotAllowedWithCompositeId();
throw MappingException::generatorNotAllowedWithCompositeId();
}
$this->_generatorType = $mapping['idGenerator'];
}
@ -1055,12 +1056,12 @@ class ClassMetadata
public function setInheritanceType($type)
{
if ($parentClassNames = $this->getParentClasses()) {
throw new Doctrine_MappingException("All classes in an inheritance hierarchy"
throw new MappingException("All classes in an inheritance hierarchy"
. " must share the same inheritance mapping type and this type must be set"
. " in the root class of the hierarchy.");
}
if ( ! $this->_isInheritanceType($type)) {
throw Doctrine_MappingException::invalidInheritanceType($type);
throw MappingException::invalidInheritanceType($type);
}
$this->_inheritanceType = $type;
}

View File

@ -16,7 +16,7 @@
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information, see
* <http://www.phpdoctrine.org>.
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\ORM\Mapping;
@ -28,7 +28,6 @@ use Doctrine\DBAL\Platforms\AbstractPlatform;
* metadata mapping informations of a class which describes how a class should be mapped
* to a relational database.
*
* @author Konsta Vesterinen <kvesteri@cc.hut.fi>
* @author Roman Borschel <roman@code-factory.org>
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @version $Revision$
@ -58,7 +57,7 @@ class ClassMetadataFactory
/**
* Sets the cache driver used by the factory to cache ClassMetadata instances.
*
* @param object $cacheDriver
* @param Doctrine\ORM\Cache\Cache $cacheDriver
*/
public function setCacheDriver($cacheDriver)
{
@ -68,7 +67,7 @@ class ClassMetadataFactory
/**
* Gets the cache driver used by the factory to cache ClassMetadata instances.
*
* @return object
* @return Doctrine\ORM\Cache\Cache
*/
public function getCacheDriver()
{
@ -108,51 +107,43 @@ class ClassMetadataFactory
*/
protected function _loadMetadata($name)
{
// Collect parent classes, ignoring transient (not-mapped) classes.
$parentClass = $name;
$parentClasses = array();
$loadedParentClass = false;
while ($parentClass = get_parent_class($parentClass)) {
if (isset($this->_loadedMetadata[$parentClass])) {
$loadedParentClass = $parentClass;
break;
if ( ! $this->_driver->isTransient($parentClass)) {
$parentClasses[] = $parentClass;
}
$parentClasses[] = $parentClass;
}
$parentClasses = array_reverse($parentClasses);
$parentClasses[] = $name;
if ($loadedParentClass) {
$class = $this->_loadedMetadata[$loadedParentClass];
} else {
$rootClassOfHierarchy = count($parentClasses) > 0 ? array_shift($parentClasses) : $name;
$class = $this->_newClassMetadataInstance($rootClassOfHierarchy);
$this->_loadClassMetadata($class, $rootClassOfHierarchy);
$this->_loadedMetadata[$rootClassOfHierarchy] = $class;
}
if (count($parentClasses) == 0) {
return $class;
}
// load metadata of subclasses
// -> child1 -> child2 -> $name
// Move down the hierarchy of parent classes, starting from the topmost class
$parent = $class;
foreach ($parentClasses as $subclassName) {
$subClass = $this->_newClassMetadataInstance($subclassName);
$subClass->setInheritanceType($parent->getInheritanceType());
$subClass->setDiscriminatorMap($parent->getDiscriminatorMap());
$subClass->setDiscriminatorColumn($parent->getDiscriminatorColumn());
$subClass->setIdGeneratorType($parent->getIdGeneratorType());
$this->_addInheritedFields($subClass, $parent);
$this->_addInheritedRelations($subClass, $parent);
$this->_loadClassMetadata($subClass, $subclassName);
if ($parent->isInheritanceTypeSingleTable()) {
$subClass->setTableName($parent->getTableName());
$parent = null;
$visited = array();
foreach ($parentClasses as $className) {
$class = $this->_newClassMetadataInstance($className);
if ($parent) {
$class->setInheritanceType($parent->getInheritanceType());
$class->setDiscriminatorMap($parent->getDiscriminatorMap());
$class->setDiscriminatorColumn($parent->getDiscriminatorColumn());
$class->setIdGeneratorType($parent->getIdGeneratorType());
$this->_addInheritedFields($class, $parent);
$this->_addInheritedRelations($class, $parent);
}
$this->_loadedMetadata[$subclassName] = $subClass;
$parent = $subClass;
// Invoke driver
$this->_driver->loadMetadataForClass($className, $class);
$this->_completeIdGeneratorMapping($class);
if ($parent && $parent->isInheritanceTypeSingleTable()) {
$class->setTableName($parent->getTableName());
}
$this->_loadedMetadata[$className] = $class;
$parent = $class;
$class->setParentClasses($visited);
array_unshift($visited, $className);
}
}
@ -173,7 +164,7 @@ class ClassMetadataFactory
* @param Doctrine\ORM\Mapping\ClassMetadata $subClass
* @param Doctrine\ORM\Mapping\ClassMetadata $parentClass
*/
private function _addInheritedFields($subClass, $parentClass)
private function _addInheritedFields(ClassMetadata $subClass, ClassMetadata $parentClass)
{
foreach ($parentClass->getFieldMappings() as $fieldName => $mapping) {
if ( ! isset($mapping['inherited'])) {
@ -189,55 +180,30 @@ class ClassMetadataFactory
* @param Doctrine\ORM\Mapping\ClassMetadata $subClass
* @param Doctrine\ORM\Mapping\ClassMetadata $parentClass
*/
private function _addInheritedRelations($subClass, $parentClass)
private function _addInheritedRelations(ClassMetadata $subClass, ClassMetadata $parentClass)
{
foreach ($parentClass->getAssociationMappings() as $mapping) {
$subClass->addAssociationMapping($mapping);
}
}
/**
* Loads the metadata of a specified class.
* Completes the ID generator mapping. If "auto" is specified we choose the generator
* most appropriate for the targeted database platform.
*
* @param Doctrine_ClassMetadata $class The container for the metadata.
* @param string $name The name of the class for which the metadata will be loaded.
* @param Doctrine\ORM\Mapping\ClassMetadata $class
*/
private function _loadClassMetadata(ClassMetadata $class, $name)
private function _completeIdGeneratorMapping(ClassMetadata $class)
{
if ( ! class_exists($name) || empty($name)) {
throw new DoctrineException("Couldn't find class " . $name . ".");
}
$names = array();
$className = $name;
// get parent classes
//TODO: Skip Entity types MappedSuperclass/Transient
do {
if ($className == $name) {
continue;
}
$names[] = $className;
} while ($className = get_parent_class($className));
// save parents
$class->setParentClasses($names);
// load user-specified mapping metadata through the driver
$this->_driver->loadMetadataForClass($name, $class);
// Complete Id generator mapping. If AUTO is specified we choose the generator
// most appropriate for the target platform.
if ($class->getIdGeneratorType() == \Doctrine\ORM\Mapping\ClassMetadata::GENERATOR_TYPE_AUTO) {
if ($class->getIdGeneratorType() == ClassMetadata::GENERATOR_TYPE_AUTO) {
if ($this->_targetPlatform->prefersSequences()) {
$class->setIdGeneratorType(\Doctrine\ORM\Mapping\ClassMetadata::GENERATOR_TYPE_SEQUENCE);
$class->setIdGeneratorType(ClassMetadata::GENERATOR_TYPE_SEQUENCE);
} else if ($this->_targetPlatform->prefersIdentityColumns()) {
$class->setIdGeneratorType(\Doctrine\ORM\Mapping\ClassMetadata::GENERATOR_TYPE_IDENTITY);
$class->setIdGeneratorType(ClassMetadata::GENERATOR_TYPE_IDENTITY);
} else {
$class->setIdGeneratorType(\Doctrine\ORM\Mapping\ClassMetadata::GENERATOR_TYPE_TABLE);
$class->setIdGeneratorType(ClassMetadata::GENERATOR_TYPE_TABLE);
}
}
return $class;
}
}

View File

@ -153,4 +153,20 @@ class AnnotationDriver
}
}
/**
* Whether the class with the specified name should have its metadata loaded.
* This is only the case if it is annotated with either @DoctrineEntity or
* @DoctrineMappedSuperclass in the class doc block.
*
* @param string $className
* @return boolean
*/
public function isTransient($className)
{
$refClass = new \ReflectionClass($className);
$docComment = $refClass->getDocComment();
return strpos($docComment, '@DoctrineEntity') === false &&
strpos($docComment, '@DoctrineMappedSuperclass') === false;
}
}

View File

@ -21,6 +21,8 @@
namespace Doctrine\ORM\Mapping;
use Doctrine\ORM\Exceptions\MappingException;
/**
* Represents a one-to-many mapping.
*
@ -76,7 +78,7 @@ class OneToManyMapping extends AssociationMapping
// one-side MUST be inverse (must have mappedBy)
if ( ! isset($mapping['mappedBy'])) {
throw Doctrine_MappingException::oneToManyRequiresMappedBy($mapping['fieldName']);
throw MappingException::oneToManyRequiresMappedBy($mapping['fieldName']);
}
$this->_deleteOrphans = isset($mapping['deleteOrphans']) ?

View File

@ -21,6 +21,8 @@
namespace Doctrine\ORM\Mapping;
use Doctrine\ORM\Exceptions\MappingException;
/**
* A one-to-one mapping describes a uni-directional mapping from one entity
* to another entity.

View File

@ -24,8 +24,6 @@ namespace Doctrine\ORM;
use Doctrine\ORM\Mapping\AssociationMapping;
/**
* A persistent collection wrapper.
*
* A PersistentCollection represents a collection of elements that have persistent state.
* Collections of entities represent only the associations (links) to those entities.
* That means, if the collection is part of a many-many mapping and you remove

View File

@ -1,7 +1,22 @@
<?php
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
/*
* $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.doctrine-project.org>.
*/
namespace Doctrine\ORM\Persisters;

View File

@ -1,4 +1,23 @@
<?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.doctrine-project.org>.
*/
namespace Doctrine\ORM\Persisters;
@ -6,6 +25,8 @@ use Doctrine\ORM\PersistentCollection;
/**
* Persister for one-to-many collections.
*
* @since 2.0
*/
class OneToManyPersister extends AbstractCollectionPersister
{

View File

@ -1,7 +1,6 @@
<?php
/*
* $Id: Query.php 3938 2008-03-06 19:36:50Z romanb $
* $Id$
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
@ -17,7 +16,7 @@
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information, see
* <http://www.phpdoctrine.org>.
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\ORM;

View File

@ -9,9 +9,13 @@ namespace Doctrine\ORM\Query;
use Doctrine\ORM\Query\AST;
/**
* Description of SqlWalker
* The SqlWalker walks over an AST that represents a DQL query and constructs
* the corresponding SQL. The walking can start at any node, not only at some root
* node. Therefore it is possible to only generate SQL parts by simply walking over
* certain subtrees of the AST.
*
* @author robo
* @since 2.0
*/
class SqlWalker
{
@ -27,6 +31,9 @@ class SqlWalker
private $_dqlToSqlAliasMap = array();
private $_scalarAliasCounter = 0;
/**
* Initializes a new SqlWalker instance.
*/
public function __construct($em, $parserResult)
{
$this->_em = $em;
@ -157,9 +164,9 @@ class SqlWalker
$sql .= $sqlTableAlias . '.' . $class->getColumnName($fieldName) .
' AS ' . $sqlTableAlias . '__' . $class->getColumnName($fieldName);
} else if ($pathExpression->isSimpleStateFieldAssociationPathExpression()) {
throw new Doctrine_Exception("Not yet implemented.");
throw new DoctrineException("Not yet implemented.");
} else {
throw new Doctrine_ORM_Query_Exception("Encountered invalid PathExpression during SQL construction.");
throw new DoctrineException("Encountered invalid PathExpression during SQL construction.");
}
}
else if ($selectExpression->getExpression() instanceof AST\AggregateExpression) {

View File

@ -1,4 +1,23 @@
<?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.doctrine-project.org>.
*/
namespace Doctrine\Tests\Mocks;

View File

@ -11,9 +11,13 @@ namespace Doctrine\Tests\Mocks;
*
* @author robo
*/
class MetadataDriverMock {
class MetadataDriverMock
{
public function loadMetadataForClass($className, \Doctrine\ORM\Mapping\ClassMetadata $metadata) {
return;
}
public function isTransient($className) {
return false;
}
}

View File

@ -13,11 +13,6 @@ use Doctrine\Tests\Models\Forum\ForumAvatar;
require_once __DIR__ . '/../TestInit.php';
#require_once 'lib/mocks/Doctrine_EntityManagerMock.php';
#require_once 'lib/mocks/Doctrine_ConnectionMock.php';
#require_once 'lib/mocks/Doctrine_UnitOfWorkMock.php';
#require_once 'lib/mocks/Doctrine_IdentityIdGeneratorMock.php';
/**
* UnitOfWork tests.
*/