Commit 2395888f authored by romanb's avatar romanb

General work. Now using spl_object_hash.

parent 6be6f40e
<?php
/**
* A class loader used to load class files on demand.
*
* Usage recommendation:
* 1) Use only 1 class loader instance.
* 2) Prepend the base paths to your class libraries (including Doctrine's) to your include path.
* 2) Set the base paths to your class libraries (including Doctrine's) through
* $classLoader->setBasePath($prefix, $basePath);
* Example:
* $classLoader->setBasePath('Doctrine', '/usr/local/phplibs/doctrine/lib');
* Then, when trying to load the class Doctrine\ORM\EntityManager, for example
* the classloader will look for /usr/local/phplibs/doctrine/lib/Doctrine/ORM/EntityManager.php
*
* 3) DO NOT setCheckFileExists(true). Doing so is expensive in terms of performance.
* 4) Use an opcode-cache (i.e. APC) (STRONGLY RECOMMENDED).
*
* @since 2.0
* @author romanb <roman@code-factory.org>
......@@ -16,7 +22,7 @@ class Doctrine_Common_ClassLoader
private $_namespaceSeparator = '_';
private $_fileExtension = '.php';
private $_checkFileExists = false;
private $_basePath;
private $_basePaths = array();
public function __construct()
{
......@@ -38,19 +44,20 @@ class Doctrine_Common_ClassLoader
}
/**
* Sets a static base path that is prepended to the path derived from the class itself.
* Sets a static base path for classes with a certain prefix that is prepended
* to the path derived from the class itself.
*
* @param string $basePath
*/
public function setBasePath($basePath)
public function setBasePath($classPrefix, $basePath)
{
$this->_basePath = $basePath;
$this->_basePaths[$classPrefix] = $basePath;
}
/**
* Loads the given class or interface.
*
* @param string $classname The name of the class to load.
* @param string $classname The name of the class to load.
* @return boolean TRUE if the class has been successfully loaded, FALSE otherwise.
*/
public function loadClass($className)
......@@ -59,9 +66,10 @@ class Doctrine_Common_ClassLoader
return false;
}
$prefix = substr($className, 0, strpos($className, $this->_namespaceSeparator));
$class = '';
if ($this->_basePath) {
$class .= $this->_basePath . DIRECTORY_SEPARATOR;
if (isset($this->_basePaths[$prefix])) {
$class .= $this->_basePaths[$prefix] . DIRECTORY_SEPARATOR;
}
$class .= str_replace($this->_namespaceSeparator, DIRECTORY_SEPARATOR, $className)
. $this->_fileExtension;
......
......@@ -19,7 +19,7 @@
* <http://www.phpdoctrine.org>.
*/
#namespace Doctrine::Common;
#namespace Doctrine\Common;
/**
* The EventManager is the central point of Doctrine's event listener system.
......@@ -101,7 +101,7 @@ class Doctrine_Common_EventManager
* Adds an EventSubscriber. The subscriber is asked for all the events he is
* interested in and added as a listener for these events.
*
* @param Doctrine::Common::Event::EventSubscriber $subscriber The subscriber.
* @param Doctrine\Common\EventSubscriber $subscriber The subscriber.
*/
public function addEventSubscriber(Doctrine_Common_EventSubscriber $subscriber)
{
......
......@@ -22,8 +22,7 @@
#namespace Doctrine\DBAL;
/**
* The Configuration is the container for all configuration options of Doctrine.
* It combines all configuration options from DBAL & ORM.
* Configuration container for the Doctrine DBAL.
*
* INTERNAL: When adding a new configuration option just write a getter/setter
* pair and add the option to the _attributes array with a proper default value.
......
<?php
/**
* PDO implementation of the driver Connection interface.
* Used by all PDO-based drivers.
......@@ -16,5 +15,3 @@ class Doctrine_DBAL_Driver_PDOConnection extends PDO implements Doctrine_DBAL_Dr
$this->setAttribute(PDO::ATTR_CASE, PDO::CASE_LOWER);
}
}
?>
\ No newline at end of file
<?php
#namespace Doctrine::DBAL::Driver::PDOMySql;
#namespace Doctrine\DBAL\Driver\PDOMySql;
#use Doctrine::DBAL::Driver;
#use Doctrine\DBAL\Driver;
class Doctrine_DBAL_Driver_PDOMySql_Driver implements Doctrine_DBAL_Driver
{
......
......@@ -58,8 +58,8 @@ class Doctrine_DBAL_Driver_PDOSqlite_Driver implements Doctrine_DBAL_Driver
/**
* Gets the schema manager that is relevant for this driver.
*
* @param Doctrine::DBAL::Connection $conn
* @return Doctrine::DBAL::Schema::AbstractSchemaManager
* @param Doctrine\DBAL\Connection $conn
* @return Doctrine\DBAL\Schema\AbstractSchemaManager
*/
public function getSchemaManager(Doctrine_DBAL_Connection $conn)
{
......
......@@ -2,5 +2,3 @@
class Doctrine_DBAL_Driver_PDOStatement extends PDOStatement implements Doctrine_DBAL_Driver_Statement
{}
?>
\ No newline at end of file
......@@ -18,16 +18,16 @@
* and is licensed under the LGPL. For more information, see
* <http://www.phpdoctrine.org>.
*/
#namespace Doctrine::DBAL::Driver;
#namespace Doctrine\DBAL\Driver;
/**
* Statement interface.
* Drivers must implement this interface.
*
* This resembles the PDOStatement interface.
* Statement interface.
* Drivers must implement this interface.
*
* This resembles the PDOStatement interface.
*
* @author Konsta Vesterinen <kvesteri@cc.hut.fi>
* @author Konsta Vesterinen <kvesteri@cc.hut.fi>
* @author Roman Borschel <roman@code-factory.org>
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @link www.doctrine-project.org
......
......@@ -19,10 +19,10 @@
* <http://www.phpdoctrine.org>.
*/
#namespace Doctrine::DBAL;
#namespace Doctrine\DBAL;
/**
* Factory for creating Doctrine::DBAL::Connection instances.
* Factory for creating Doctrine\DBAL\Connection instances.
*
* @author Roman Borschel <roman@code-factory.org>
* @since 2.0
......@@ -43,12 +43,13 @@ final class Doctrine_DBAL_DriverManager
'pdo_firebird' => 'Doctrine_DBAL_Driver_PDOFirebird_Driver',
'pdo_informix' => 'Doctrine_DBAL_Driver_PDOInformix_Driver',
);
/** Private constructor. This class cannot be instantiated. */
private function __construct() {}
/**
* Creates a connection object based on the specified parameters.
* This method returns a Doctrine::DBAL::Connection which wraps the underlying
* This method returns a Doctrine\DBAL\Connection which wraps the underlying
* driver connection.
*
* $params must contain at least one of the following.
......@@ -79,16 +80,16 @@ final class Doctrine_DBAL_DriverManager
*
* <b>pdo</b>:
* You can pass an existing PDO instance through this parameter. The PDO
* instance will be wrapped in a Doctrine::DBAL::Connection.
* instance will be wrapped in a Doctrine\DBAL\Connection.
*
* <b>wrapperClass</b>:
* You may specify a custom wrapper class through the 'wrapperClass'
* parameter but this class MUST inherit from Doctrine::DBAL::Connection.
* parameter but this class MUST inherit from Doctrine\DBAL\Connection.
*
* @param array $params The parameters.
* @param Doctrine::Common::Configuration The configuration to use.
* @param Doctrine::Common::EventManager The event manager to use.
* @return Doctrine::DBAL::Connection
* @param Doctrine\DBAL\Configuration The configuration to use.
* @param Doctrine\Common\EventManager The event manager to use.
* @return Doctrine\DBAL\Connection
*/
public static function getConnection(array $params,
Doctrine_DBAL_Configuration $config = null,
......
......@@ -19,7 +19,7 @@
* <http://www.phpdoctrine.org>.
*/
#namespace Doctrine::DBAL::Platforms;
#namespace Doctrine\DBAL\Platforms;
/**
* Base class for all DatabasePlatforms. The DatabasePlatforms are the central
......
......@@ -19,10 +19,10 @@
* <http://www.phpdoctrine.org>.
*/
#namespace Doctrine::ORM;
#namespace Doctrine\ORM;
/**
* A persistent collection.
* A persistent collection wrapper.
*
* A collection object is strongly typed in the sense that it can only contain
* entities of a specific type or one of it's subtypes. A collection object is
......@@ -73,7 +73,7 @@ class Doctrine_ORM_Collection implements Countable, IteratorAggregate, Serializa
protected $_snapshot = array();
/**
* This entity that owns this collection.
* The entity that owns this collection.
*
* @var Doctrine\ORM\Entity
*/
......@@ -468,7 +468,7 @@ class Doctrine_ORM_Collection implements Countable, IteratorAggregate, Serializa
public function add($value, $key = null)
{
if ( ! $value instanceof $this->_entityBaseType) {
throw new Doctrine_Record_Exception('Value variable in collection is not an instance of Doctrine_Entity.');
throw new Doctrine_Exception('Invalid instance.');
}
// TODO: Really prohibit duplicates?
......@@ -511,121 +511,6 @@ class Doctrine_ORM_Collection implements Countable, IteratorAggregate, Serializa
//TODO: Register collection as dirty with the UoW if necessary
//$this->_changed();
}
/**
* INTERNAL:
* loadRelated
*
* @param mixed $name
* @return boolean
* @todo New implementation & maybe move elsewhere.
*/
/*public function loadRelated($name = null)
{
$list = array();
$query = new Doctrine_Query($this->_mapper->getConnection());
if ( ! isset($name)) {
foreach ($this->_data as $record) {
// FIXME: composite key support
$ids = $record->identifier();
$value = count($ids) > 0 ? array_pop($ids) : null;
if ($value !== null) {
$list[] = $value;
}
}
$query->from($this->_mapper->getComponentName()
. '(' . implode(", ",$this->_mapper->getTable()->getPrimaryKeys()) . ')');
$query->where($this->_mapper->getComponentName()
. '.id IN (' . substr(str_repeat("?, ", count($list)),0,-2) . ')');
return $query;
}
$rel = $this->_mapper->getTable()->getRelation($name);
if ($rel instanceof Doctrine_Relation_LocalKey || $rel instanceof Doctrine_Relation_ForeignKey) {
foreach ($this->_data as $record) {
$list[] = $record[$rel->getLocal()];
}
} else {
foreach ($this->_data as $record) {
$ids = $record->identifier();
$value = count($ids) > 0 ? array_pop($ids) : null;
if ($value !== null) {
$list[] = $value;
}
}
}
$dql = $rel->getRelationDql(count($list), 'collection');
$coll = $query->query($dql, $list);
$this->populateRelated($name, $coll);
}*/
/**
* INTERNAL:
* populateRelated
*
* @param string $name
* @param Doctrine_Collection $coll
* @return void
* @todo New implementation & maybe move elsewhere.
*/
/*protected function populateRelated($name, Doctrine_Collection $coll)
{
$rel = $this->_mapper->getTable()->getRelation($name);
$table = $rel->getTable();
$foreign = $rel->getForeign();
$local = $rel->getLocal();
if ($rel instanceof Doctrine_Relation_LocalKey) {
foreach ($this->_data as $key => $record) {
foreach ($coll as $k => $related) {
if ($related[$foreign] == $record[$local]) {
$this->_data[$key]->_setRelated($name, $related);
}
}
}
} else if ($rel instanceof Doctrine_Relation_ForeignKey) {
foreach ($this->_data as $key => $record) {
if ( ! $record->exists()) {
continue;
}
$sub = new Doctrine_Collection($rel->getForeignComponentName());
foreach ($coll as $k => $related) {
if ($related[$foreign] == $record[$local]) {
$sub->add($related);
$coll->remove($k);
}
}
$this->_data[$key]->_setRelated($name, $sub);
}
} else if ($rel instanceof Doctrine_Relation_Association) {
// @TODO composite key support
$identifier = (array)$this->_mapper->getClassMetadata()->getIdentifier();
$asf = $rel->getAssociationFactory();
$name = $table->getComponentName();
foreach ($this->_data as $key => $record) {
if ( ! $record->exists()) {
continue;
}
$sub = new Doctrine_Collection($rel->getForeignComponentName());
foreach ($coll as $k => $related) {
$idField = $identifier[0];
if ($related->get($local) == $record[$idField]) {
$sub->add($related->get($name));
}
}
$this->_data[$key]->_setRelated($name, $sub);
}
}
}*/
/**
* INTERNAL:
......@@ -661,7 +546,8 @@ class Doctrine_ORM_Collection implements Countable, IteratorAggregate, Serializa
}
/**
* INTERNAL: Returns the data of the last snapshot.
* INTERNAL:
* Returns the data of the last snapshot.
*
* @return array returns the data in last snapshot
*/
......@@ -671,7 +557,8 @@ class Doctrine_ORM_Collection implements Countable, IteratorAggregate, Serializa
}
/**
* INTERNAL: Processes the difference of the last snapshot and the current data.
* INTERNAL:
* Processes the difference of the last snapshot and the current data.
*
* an example:
* Snapshot with the objects 1, 2 and 4
......@@ -719,7 +606,7 @@ class Doctrine_ORM_Collection implements Countable, IteratorAggregate, Serializa
}
/**
* Populate a Doctrine_Collection from an array of data.
* Populate a Collection from an array of data.
*
* @param string $array
* @return void
......@@ -733,7 +620,7 @@ class Doctrine_ORM_Collection implements Countable, IteratorAggregate, Serializa
}
/**
* Synchronizes a Doctrine_Collection with data from an array.
* Synchronizes a Collection with data from an array.
*
* it expects an array representation of a Doctrine_Collection similar to the return
* value of the toArray() method. It will create Dectrine_Records that don't exist
......@@ -760,7 +647,8 @@ class Doctrine_ORM_Collection implements Countable, IteratorAggregate, Serializa
}
/**
* INTERNAL: getDeleteDiff
* INTERNAL:
* getDeleteDiff
*
* @return array
*/
......@@ -786,17 +674,17 @@ class Doctrine_ORM_Collection implements Countable, IteratorAggregate, Serializa
*/
protected function _compareRecords($a, $b)
{
if ($a->getOid() == $b->getOid()) {
if ($a === $b) {
return 0;
}
return ($a->getOid() > $b->getOid()) ? 1 : -1;
return 1;
}
/**
*
* @param <type> $deep
*/
public function free($deep = false)
/*public function free($deep = false)
{
foreach ($this->getData() as $key => $record) {
if ( ! ($record instanceof Doctrine_Null)) {
......@@ -810,8 +698,7 @@ class Doctrine_ORM_Collection implements Countable, IteratorAggregate, Serializa
$this->_owner->free($deep);
$this->_owner = null;
}
}
}*/
/**
* getIterator
......
......@@ -24,7 +24,7 @@
#use Doctrine\DBAL\Configuration;
/**
* The Configuration is the container for all configuration options of Doctrine.
* Configuration container for all configuration options of Doctrine.
* It combines all configuration options from DBAL & ORM.
*
* INTERNAL: When adding a new configuration option just write a getter/setter
......@@ -72,7 +72,7 @@ class Doctrine_ORM_Configuration extends Doctrine_DBAL_Configuration
return $this->_attributes['metadataCacheImpl'];
}
public function setMetadataCacheImpl(Doctrine_Cache_Interface $cacheImpl)
public function setMetadataCacheImpl($cacheImpl)
{
$this->_attributes['metadataCacheImpl'] = $cacheImpl;
}
......
......@@ -21,8 +21,6 @@
#namespace Doctrine\ORM;
#use \Serializable;
/**
* Entity marker interface.
*
......
......@@ -86,14 +86,14 @@ class Doctrine_ORM_EntityManager
/**
* The database connection used by the EntityManager.
*
* @var Doctrine_Connection
* @var Connection
*/
private $_conn;
/**
* The metadata factory, used to retrieve the metadata of entity classes.
*
* @var Doctrine::ORM::Mapping::ClassMetadataFactory
* @var Doctrine\ORM\Mapping\ClassMetadataFactory
*/
private $_metadataFactory;
......@@ -131,19 +131,8 @@ class Doctrine_ORM_EntityManager
* @var EventManager
*/
private $_eventManager;
/**
* Container that is used temporarily during hydration.
*
* @var array
*/
private $_tmpEntityData = array();
private $_idGenerators = array();
private $_closed = false;
private $_originalEntityData = array();
/**
* Creates a new EntityManager that operates on the given database connection.
......@@ -220,6 +209,7 @@ class Doctrine_ORM_EntityManager
* Returns the metadata for a class.
*
* @return Doctrine_Metadata
* @internal Performance-sensitive method.
*/
public function getClassMetadata($className)
{
......@@ -262,8 +252,7 @@ class Doctrine_ORM_EntityManager
* Creates a new Query object.
*
* @param string The DQL string.
* @return Doctrine::ORM::Query
* @todo package:orm
* @return Doctrine\ORM\Query
*/
public function createQuery($dql = "")
{
......@@ -271,7 +260,6 @@ class Doctrine_ORM_EntityManager
if ( ! empty($dql)) {
$query->setDql($dql);
}
return $query;
}
......@@ -281,16 +269,16 @@ class Doctrine_ORM_EntityManager
* This is usually not of interest for users, mainly for internal use.
*
* @param string $entityName The name of the Entity.
* @return Doctrine::ORM::Internal::EntityPersister
* @return Doctrine\ORM\Persister\AbstractEntityPersister
*/
public function getEntityPersister($entityName)
{
if ( ! isset($this->_persisters[$entityName])) {
$class = $this->getClassMetadata($entityName);
if ($class->getInheritanceType() == Doctrine::INHERITANCE_TYPE_JOINED) {
if ($class->getInheritanceType() == Doctrine_ORM_Mapping_ClassMetadata::INHERITANCE_TYPE_JOINED) {
$persister = new Doctrine_EntityPersister_JoinedSubclass($this, $class);
} else {
$persister = new Doctrine_EntityPersister_Standard($this, $class);
$persister = new Doctrine_ORM_Persisters_StandardEntityPersister($this, $class);
}
$this->_persisters[$entityName] = $persister;
}
......@@ -444,7 +432,7 @@ class Doctrine_ORM_EntityManager
/**
* Removes the given entity from the persistent store.
*
* @param Doctrine::ORM::Entity $entity
* @param Doctrine\ORM\Entity $entity
* @return void
*/
public function delete(Doctrine_ORM_Entity $entity)
......@@ -506,93 +494,6 @@ class Doctrine_ORM_EntityManager
return $repository;
}
/**
* Creates an entity. Used for reconstitution as well as initial creation.
*
* @param string $className The name of the entity class.
* @param array $data The data for the entity.
* @return Doctrine\ORM\Entity
*/
public function createEntity($className, array $data, Doctrine_Query $query = null)
{
$this->_errorIfNotActiveOrClosed();
$this->_tmpEntityData = $data;
$className = $this->_inferCorrectClassName($data, $className);
$classMetadata = $this->getClassMetadata($className);
if ( ! empty($data)) {
$identifierFieldNames = $classMetadata->getIdentifier();
$isNew = false;
foreach ($identifierFieldNames as $fieldName) {
if ( ! isset($data[$fieldName])) {
// id field not found return new entity
$isNew = true;
break;
}
$id[] = $data[$fieldName];
}
if ($isNew) {
$entity = new $className;
} else {
$idHash = $this->_unitOfWork->getIdentifierHash($id);
$entity = $this->_unitOfWork->tryGetByIdHash($idHash, $classMetadata->getRootClassName());
if ($entity) {
$this->_mergeData($entity, $data/*, $classMetadata, $query->getHint('doctrine.refresh')*/);
return $entity;
} else {
$entity = new $className;
$this->_unitOfWork->addToIdentityMap($entity);
}
}
} else {
$entity = new $className;
}
//$this->_originalEntityData[$entity->getOid()] = $data;
return $entity;
}
/**
* Merges the given data into the given entity, optionally overriding
* local changes.
*
* @param Doctrine\ORM\Entity $entity
* @param array $data
* @param boolean $overrideLocalChanges
* @return void
*/
private function _mergeData(Doctrine_ORM_Entity $entity, /*$class,*/ array $data, $overrideLocalChanges = false) {
if ($overrideLocalChanges) {
foreach ($data as $field => $value) {
$entity->_internalSetField($field, $value);
}
} else {
foreach ($data as $field => $value) {
$currentValue = $entity->get($field);
if ( ! isset($currentValue) || $entity->_internalGetField($field) === null) {
$entity->_internalSetField($field, $value);
}
}
}
// NEW
/*if ($overrideLocalChanges) {
foreach ($data as $field => $value) {
$class->getReflectionProperty($field)->setValue($entity, $value);
}
} else {
foreach ($data as $field => $value) {
$currentValue = $class->getReflectionProperty($field)->getValue($entity);
if ( ! isset($this->_originalEntityData[$entity->getOid()]) ||
$currentValue == $this->_originalEntityData[$entity->getOid()]) {
$class->getReflectionProperty($field)->setValue($entity, $value);
}
}
}*/
}
/**
* Checks if the instance is managed by the EntityManager.
*
......@@ -606,51 +507,10 @@ class Doctrine_ORM_EntityManager
! $this->_unitOfWork->isRegisteredRemoved($entity);
}
/**
* INTERNAL: For internal hydration purposes only.
*
* Gets the temporarily stored entity data.
*
* @return array
*/
public function _getTmpEntityData()
{
$data = $this->_tmpEntityData;
$this->_tmpEntityData = array();
return $data;
}
/**
* Check the dataset for a discriminator column to determine the correct
* class to instantiate. If no discriminator column is found, the given
* classname will be returned.
*
* @param array $data
* @param string $className
* @return string The name of the class to instantiate.
*/
private function _inferCorrectClassName(array $data, $className)
{
$class = $this->getClassMetadata($className);
$discCol = $class->getInheritanceOption('discriminatorColumn');
if ( ! $discCol) {
return $className;
}
$discMap = $class->getInheritanceOption('discriminatorMap');
if (isset($data[$discCol], $discMap[$data[$discCol]])) {
return $discMap[$data[$discCol]];
} else {
return $className;
}
}
/**
* Gets the EventManager used by the EntityManager.
*
* @return Doctrine::Common::EventManager
* @return Doctrine\Common\EventManager
*/
public function getEventManager()
{
......@@ -660,7 +520,7 @@ class Doctrine_ORM_EntityManager
/**
* Gets the Configuration used by the EntityManager.
*
* @return Doctrine::Common::Configuration
* @return Doctrine\ORM\Configuration
*/
public function getConfiguration()
{
......@@ -682,7 +542,7 @@ class Doctrine_ORM_EntityManager
/**
* Gets the UnitOfWork used by the EntityManager to coordinate operations.
*
* @return Doctrine::ORM::UnitOfWork
* @return Doctrine\ORM\UnitOfWork
*/
public function getUnitOfWork()
{
......@@ -747,7 +607,7 @@ class Doctrine_ORM_EntityManager
/**
* Static lookup to get the currently active EntityManager.
*
* @return Doctrine::ORM::EntityManager
* @return Doctrine\ORM\EntityManager
*/
public static function getActiveEntityManager()
{
......
......@@ -19,7 +19,7 @@
* <http://www.phpdoctrine.org>.
*/
#namespace Doctrine::ORM;
#namespace Doctrine\ORM;
/**
* A repository provides the illusion of an in-memory Entity store.
......
<?php
#namespace Doctrine::ORM::Id;
#namespace Doctrine\ORM\Id;
/**
* Enter description here...
......@@ -8,17 +8,33 @@
* @todo Rename to AbstractIdGenerator
*/
abstract class Doctrine_ORM_Id_AbstractIdGenerator
{
const POST_INSERT_INDICATOR = 'POST_INSERT_INDICATOR';
{
protected $_em;
public function __construct(Doctrine_ORM_EntityManager $em)
{
$this->_em = $em;
}
/**
* Generates an identifier for an entity.
*
* @param Doctrine\ORM\Entity $entity
* @return mixed
*/
abstract public function generate($entity);
/**
* Gets whether this generator is a post-insert generator which means that
* {@link generate()} must be called after the entity has been inserted
* into the database.
* By default, this method returns FALSE. Generators that have this requirement
* must override this method and return TRUE.
*
* @return boolean
*/
public function isPostInsertGenerator() {
return false;
}
}
?>
\ No newline at end of file
......@@ -4,23 +4,43 @@
* Special generator for application-assigned identifiers (doesnt really generate anything).
*
* @since 2.0
* @author Roman Borschel <roman@code-factory.org>
*/
class Doctrine_ORM_Id_Assigned extends Doctrine_ORM_Id_AbstractIdGenerator
{
/**
* Enter description here...
* Returns the identifier assigned to the given entity.
*
* @param Doctrine_ORM_Entity $entity
* @return unknown
* @param Doctrine\ORM\Entity $entity
* @return mixed
* @override
*/
public function generate($entity)
{
if ( ! $entity->_identifier()) {
throw new Doctrine_Exception("Entity '$entity' is missing an assigned Id");
$class = $this->_em->getClassMetadata(get_class($entity));
if ($class->isIdentifierComposite()) {
$identifier = array();
$idFields = $class->getIdentifierFieldNames();
foreach ($idFields as $idField) {
$identifier[] =
$value = $class->getReflectionProperty($idField)->getValue($entity);
if (isset($value)) {
$identifier[] = $value;
}
}
} else {
$value = $class->getReflectionProperty($class->getSingleIdentifierFieldName())
->getValue($entity);
if (isset($value)) {
$identifier = array($value);
}
}
return $entity->_identifier();
if ( ! $identifier) {
throw new Doctrine_Exception("Entity '$entity' is missing an assigned ID.");
}
return $identifier;
}
}
?>
\ No newline at end of file
......@@ -10,14 +10,16 @@ class Doctrine_ORM_Id_IdentityGenerator extends Doctrine_ORM_Id_AbstractIdGenera
* @override
*/
public function generate($entity)
{
return self::POST_INSERT_INDICATOR;
}
public function getPostInsertId()
{
return $this->_em->getConnection()->lastInsertId();
}
/**
* @return boolean
* @override
*/
public function isPostInsertGenerator() {
return true;
}
}
?>
\ No newline at end of file
......@@ -19,7 +19,7 @@
* <http://www.phpdoctrine.org>.
*/
#namespace Doctrine::ORM::Internal;
#namespace Doctrine\ORM\Internal;
/**
* The CommitOrderCalculator is used by the UnitOfWork to sort out the
......
......@@ -19,11 +19,11 @@
* <http://www.phpdoctrine.org>.
*/
#namespace Doctrine::ORM::Internal;
#namespace Doctrine\ORM\Internal;
/**
* A CommitOrderNode is a temporary wrapper around ClassMetadata instances
* that is used to sort the order of commits.
* that is used to sort the order of commits in a UnitOfWork.
*
* @since 2.0
* @author Roman Borschel <roman@code-factory.org>
......@@ -53,7 +53,7 @@ class Doctrine_ORM_Internal_CommitOrderNode
* Creates a new node.
*
* @param mixed $wrappedObj The object to wrap.
* @param Doctrine::ORM::Internal::CommitOrderCalculator $calc The calculator.
* @param Doctrine\ORM\Internal\CommitOrderCalculator $calc The calculator.
*/
public function __construct($wrappedObj, Doctrine_ORM_Internal_CommitOrderCalculator $calc)
{
......@@ -155,7 +155,7 @@ class Doctrine_ORM_Internal_CommitOrderNode
/**
* Adds a directed dependency (an edge on the graph). "$this -before-> $other".
*
* @param Doctrine::ORM::Internal::CommitOrderNode $node
* @param Doctrine\ORM\Internal\CommitOrderNode $node
*/
public function before(Doctrine_ORM_Internal_CommitOrderNode $node)
{
......@@ -163,4 +163,3 @@ class Doctrine_ORM_Internal_CommitOrderNode
}
}
?>
\ No newline at end of file
......@@ -19,7 +19,7 @@
* <http://www.phpdoctrine.org>.
*/
#namespace Doctrine::ORM::Internal::Hydration;
#namespace Doctrine\ORM\Internal\Hydration;
/**
* Defines an array hydration strategy.
......@@ -32,8 +32,7 @@
* @author Roman Borschel <roman@code-factory.org>
*/
class Doctrine_ORM_Internal_Hydration_ArrayDriver
{
{
/**
*
*/
......@@ -66,8 +65,7 @@ class Doctrine_ORM_Internal_Hydration_ArrayDriver
}
}
public function addRelatedIndexedElement(array &$entity1, $property, array &$entity2,
$indexField)
public function addRelatedIndexedElement(array &$entity1, $property, array &$entity2, $indexField)
{
$entity1[$property][$entity2[$indexField]] = $entity2;
}
......@@ -134,7 +132,7 @@ class Doctrine_ORM_Internal_Hydration_ArrayDriver
* last seen instance of each Entity type. This is used for graph construction.
*
* @param array $resultPointers The result pointers.
* @param array|Collection $coll The element.
* @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.
......
......@@ -22,7 +22,7 @@
#namespace Doctrine\ORM\Internal\Hydration;
/**
* The hydrator has the tedious to process result sets returned by the database
* 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
......@@ -63,10 +63,6 @@ class Doctrine_ORM_Internal_Hydration_StandardHydrator extends Doctrine_ORM_Inte
*
* This is method defines the core of Doctrine's object population algorithm.
*
* @todo: Detailed documentation. Refactor (too long & nesting level).
*
* @param mixed $stmt
* @param array $tableAliases Array that maps table aliases (SQL alias => DQL alias)
* @param array $aliasMap Array that maps DQL aliases to their components
* (DQL alias => array(
* 'metadata' => Table object,
......@@ -134,8 +130,6 @@ class Doctrine_ORM_Internal_Hydration_StandardHydrator extends Doctrine_ORM_Inte
// Initialize
foreach ($this->_queryComponents as $dqlAlias => $component) {
// disable lazy-loading of related elements during hydration
//$component['metadata']->setAttribute('loadReferences', false);
$identifierMap[$dqlAlias] = array();
$resultPointers[$dqlAlias] = array();
$idTemplate[$dqlAlias] = '';
......@@ -152,7 +146,8 @@ class Doctrine_ORM_Internal_Hydration_StandardHydrator extends Doctrine_ORM_Inte
$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
......@@ -178,12 +173,14 @@ class Doctrine_ORM_Internal_Hydration_StandardHydrator extends Doctrine_ORM_Inte
$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);
}
......@@ -226,7 +223,7 @@ class Doctrine_ORM_Internal_Hydration_StandardHydrator extends Doctrine_ORM_Inte
continue;
}
// check the type of the relation (many or single-valued)
// Check the type of the relation (many or single-valued)
if ( ! $relation->isOneToOne()) {
// x-to-many relation
$oneToOne = false;
......@@ -270,7 +267,6 @@ class Doctrine_ORM_Internal_Hydration_StandardHydrator extends Doctrine_ORM_Inte
$coll =& $baseElement[$relationAlias];
} else {
$coll = $driver->getReferenceValue($baseElement, $relationAlias);
//$baseElement->_internalGetReference($relationAlias);
}
if ($coll !== null) {
......@@ -279,11 +275,9 @@ class Doctrine_ORM_Internal_Hydration_StandardHydrator extends Doctrine_ORM_Inte
}
// Append scalar values to mixed result sets
//TODO: we dont need to count every time here, instead count with the loop
if (isset($scalars)) {
$rowNumber = count($result) - 1;
foreach ($scalars as $name => $value) {
$result[$rowNumber][$name] = $value;
$result[$resultCounter - 1][$name] = $value;
}
}
}
......@@ -291,11 +285,6 @@ class Doctrine_ORM_Internal_Hydration_StandardHydrator extends Doctrine_ORM_Inte
$stmt->closeCursor();
$driver->flush();
/*// re-enable lazy loading
foreach ($this->_queryComponents as $dqlAlias => $data) {
$data['metadata']->setAttribute('loadReferences', true);
}*/
$e = microtime(true);
echo 'Hydration took: ' . ($e - $s) . PHP_EOL;
......@@ -514,7 +503,6 @@ class Doctrine_ORM_Internal_Hydration_StandardHydrator extends Doctrine_ORM_Inte
}
/**
* prepareValue
* this method performs special data preparation depending on
* the type of the given column
*
......@@ -536,6 +524,7 @@ class Doctrine_ORM_Internal_Hydration_StandardHydrator extends Doctrine_ORM_Inte
* for the field can be skipped. Used i.e. during hydration to
* improve performance on large and/or complex results.
* @return mixed prepared value
* @todo Remove. Should be handled by the Type classes. No need for this switch stuff.
*/
public function prepareValue(Doctrine_ClassMetadata $class, $fieldName, $value, $typeHint = null)
{
......
......@@ -18,20 +18,20 @@
* and is licensed under the LGPL. For more information, see
* <http://www.phpdoctrine.org>.
*/
#namespace Doctrine::ORM::Internal;
#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.
* 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
......@@ -39,6 +39,7 @@
* @since 1.0
* @version $Revision: 4723 $
* @author Konsta Vesterinen <kvesteri@cc.hut.fi>
* @todo No longer needed?
*/
// static initializer
Doctrine_ORM_Internal_Null::$INSTANCE = new Doctrine_ORM_Internal_Null();
......
......@@ -28,7 +28,7 @@
* @since 2.0
* @todo Rename to AssociationMapping.
*/
class Doctrine_ORM_Mapping_AssociationMapping implements Serializable
abstract class Doctrine_ORM_Mapping_AssociationMapping implements Serializable
{
const FETCH_MANUAL = 1;
const FETCH_LAZY = 2;
......@@ -443,6 +443,8 @@ class Doctrine_ORM_Mapping_AssociationMapping implements Serializable
{
return false;
}
abstract public function lazyLoadFor($entity);
/* Serializable implementation */
......
This diff is collapsed.
......@@ -19,7 +19,7 @@
* <http://www.phpdoctrine.org>.
*/
#namespace Doctrine::ORM::Mapping;
#namespace Doctrine\ORM\Mapping;
/**
* Represents a one-to-many mapping.
......@@ -66,7 +66,7 @@ class Doctrine_ORM_Mapping_OneToManyMapping extends Doctrine_ORM_Mapping_Associa
}
/**
* Validates and completed the mapping.
* Validates and completes the mapping.
*
* @param array $mapping The mapping to validate and complete.
* @return array The validated and completed mapping.
......@@ -106,6 +106,15 @@ class Doctrine_ORM_Mapping_OneToManyMapping extends Doctrine_ORM_Mapping_Associa
return true;
}
/**
*
* @param <type> $entity
* @override
*/
public function lazyLoadFor($entity)
{
}
}
......
......@@ -130,10 +130,10 @@ class Doctrine_ORM_Mapping_OneToOneMapping extends Doctrine_ORM_Mapping_Associat
/**
* Lazy-loads the associated entity for a given entity.
*
* @param Doctrine::ORM::Entity $entity
* @param Doctrine\ORM\Entity $entity
* @return void
*/
public function lazyLoadFor(Doctrine_ORM_Entity $entity)
public function lazyLoadFor($entity)
{
if ($entity->getClassName() != $this->_sourceClass->getClassName()) {
//error?
......
......@@ -30,7 +30,7 @@
* @author Roman Borschel <roman@code-factory.org>
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @version $Revision$
* @link www.phpdoctrine.org
* @link www.doctrine-project.org
* @since 2.0
*/
class Doctrine_ORM_Persisters_StandardEntityPersister extends Doctrine_ORM_Persisters_AbstractEntityPersister
......@@ -40,10 +40,8 @@ class Doctrine_ORM_Persisters_StandardEntityPersister extends Doctrine_ORM_Persi
*/
protected function _doDelete(Doctrine_ORM_Entity $record)
{
$conn = $this->_conn;
$metadata = $this->_classMetadata;
try {
$conn->beginInternalTransaction();
/*try {
$this->_conn->beginInternalTransaction();
$this->_deleteComposites($record);
$record->_state(Doctrine_ORM_Entity::STATE_TDIRTY);
......@@ -57,18 +55,16 @@ class Doctrine_ORM_Persisters_StandardEntityPersister extends Doctrine_ORM_Persi
} catch (Exception $e) {
$conn->rollback();
throw $e;
}
}*/
}
/**
* Inserts a single entity into the database, without any related entities.
* Inserts a single entity into the database.
*
* @param Doctrine_Entity $record The entity to insert.
* @param Doctrine\ORM\Entity $entity The entity to insert.
*/
protected function _doInsert(Doctrine_ORM_Entity $record)
{
$conn = $this->_conn;
$fields = $record->getPrepared();
if (empty($fields)) {
return false;
......
This diff is collapsed.
......@@ -871,6 +871,7 @@ class Orm_Hydration_BasicHydrationTest extends Doctrine_OrmTestCase
$this->assertEquals(3, count($result[0]->boards));
$this->assertTrue(isset($result[1]->boards));
$this->assertEquals(1, count($result[1]->boards));
} else if ($hydrationMode == Doctrine_ORM_Query::HYDRATE_SCALAR) {
//...
}
......
This diff is collapsed.
......@@ -2,6 +2,9 @@
require_once 'lib/mocks/Doctrine_EntityPersisterMock.php';
/**
* Special EntityManager mock used for testing purposes.
*/
class Doctrine_EntityManagerMock extends Doctrine_ORM_EntityManager
{
private $_persisterMock;
......@@ -13,8 +16,8 @@ class Doctrine_EntityManagerMock extends Doctrine_ORM_EntityManager
*/
public function getEntityPersister($entityName)
{
return isset($this->_persisterMock) ? $this->_persisterMock :
parent::getEntityPersister($entityName);
return isset($this->_persisterMock[$entityName]) ?
$this->_persisterMock[$entityName] : parent::getEntityPersister($entityName);
}
/**
......@@ -27,24 +30,36 @@ class Doctrine_EntityManagerMock extends Doctrine_ORM_EntityManager
/* Mock API */
/**
* Sets a (mock) UnitOfWork that will be returned when getUnitOfWork() is called.
*
* @param <type> $uow
*/
public function setUnitOfWork($uow)
{
$this->_uowMock = $uow;
}
public function setEntityPersister($persister)
/**
* Sets a (mock) persister for an entity class that will be returned when
* getEntityPersister() is invoked for that class.
*
* @param <type> $entityName
* @param <type> $persister
*/
public function setEntityPersister($entityName, $persister)
{
$this->_persisterMock = $persister;
$this->_persisterMock[$entityName] = $persister;
}
/**
* Mock factory method.
* Mock factory method to create an EntityManager.
*
* @param unknown_type $conn
* @param unknown_type $name
* @param Doctrine_Configuration $config
* @param Doctrine_EventManager $eventManager
* @return unknown
* @return Doctrine\ORM\EntityManager
*/
public static function create($conn, $name, Doctrine_ORM_Configuration $config = null,
Doctrine_Common_EventManager $eventManager = null)
......
<?php
/**
* EntityPersister implementation used for mocking during tests.
*/
class Doctrine_EntityPersisterMock extends Doctrine_ORM_Persisters_StandardEntityPersister
{
private $_inserts = array();
private $_updates = array();
private $_deletes = array();
private $_identityColumnValueCounter = 0;
private $_mockIdGeneratorType;
/**
* @param <type> $entity
* @return <type>
* @override
*/
public function insert($entity)
{
$class = $this->_em->getClassMetadata(get_class($entity));
if ($class->isIdGeneratorIdentity()) {
$class->setEntityIdentifier($entity, $this->_identityColumnValueCounter++);
$this->_em->getUnitOfWork()->addToIdentityMap($entity);
}
$this->_inserts[] = $entity;
if ( ! is_null($this->_mockIdGeneratorType) && $this->_mockIdGeneratorType == Doctrine_ORM_Mapping_ClassMetadata::GENERATOR_TYPE_IDENTITY
|| $this->_classMetadata->isIdGeneratorIdentity()) {
return $this->_identityColumnValueCounter++;
}
return null;
}
public function setMockIdGeneratorType($genType) {
$this->_mockIdGeneratorType = $genType;
}
public function update(Doctrine_ORM_Entity $entity)
......@@ -51,7 +61,5 @@ class Doctrine_EntityPersisterMock extends Doctrine_ORM_Persisters_StandardEntit
$this->_updates = array();
$this->_deletes = array();
}
}
?>
\ No newline at end of file
<?php
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
/**
* Description of Doctrine_IdentityIdGeneratorMock
*
* @author robo
*/
class Doctrine_IdentityIdGeneratorMock extends Doctrine_ORM_Id_IdentityGenerator
{
private $_mockPostInsertId;
public function setMockPostInsertId($id) {
$this->_mockPostInsertId = $id;
}
}
?>
......@@ -15,8 +15,6 @@ class Doctrine_SequenceMock extends Doctrine_ORM_Id_SequenceGenerator
return $this->_sequenceNumber++;
}
/**
* @override
*/
......
......@@ -17,7 +17,7 @@ class Doctrine_UnitOfWorkMock extends Doctrine_ORM_UnitOfWork {
* @override
*/
public function getDataChangeSet($entity) {
$oid = spl_object_id($entity);
$oid = spl_object_hash($entity);
return isset($this->_mockDataChangeSets[$oid]) ?
$this->_mockDataChangeSets[$oid] : parent::getDataChangeSet($entity);
}
......@@ -25,7 +25,17 @@ class Doctrine_UnitOfWorkMock extends Doctrine_ORM_UnitOfWork {
/* MOCK API */
public function setDataChangeSet($entity, array $mockChangeSet) {
$this->_mockDataChangeSets[spl_object_id($entity)] = $mockChangeSet;
$this->_mockDataChangeSets[spl_object_hash($entity)] = $mockChangeSet;
}
public function setEntityState($entity, $state)
{
$this->_entityStates[spl_object_hash($entity)] = $state;
}
public function setOriginalEntityData($entity, array $originalData)
{
$this->_originalEntityData[spl_object_hash($entity)] = $originalData;
}
}
......@@ -13,6 +13,18 @@ class ForumUser
public static function initMetadata($mapping)
{
/*$mapping->setClassMetadata(array(
'doctrine.inheritanceType' => 'joined',
'doctrine.discriminatorColumn' => 'dtype',
'doctrine.discriminatorMap' => array('user' => 'ForumUser', 'admin' => 'ForumAdministrator'),
'doctrine.subclasses' => array('ForumAdministrator')
));
$mapping->setFieldMetadata('id', array(
'doctrine.type' => 'integer',
'doctrine.id' => true,
'doctrine.idGenerator' => 'auto'
));*/
// inheritance mapping
$mapping->setInheritanceType('joined', array(
'discriminatorColumn' => 'dtype',
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment