Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
D
doctrine-dbal
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Tomáš Trávníček
doctrine-dbal
Commits
2395888f
Commit
2395888f
authored
Jan 03, 2009
by
romanb
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
General work. Now using spl_object_hash.
parent
6be6f40e
Changes
39
Hide whitespace changes
Inline
Side-by-side
Showing
39 changed files
with
665 additions
and
1119 deletions
+665
-1119
ClassLoader.php
lib/Doctrine/Common/ClassLoader.php
+17
-9
EventManager.php
lib/Doctrine/Common/EventManager.php
+2
-2
Configuration.php
lib/Doctrine/DBAL/Configuration.php
+1
-2
PDOConnection.php
lib/Doctrine/DBAL/Driver/PDOConnection.php
+0
-3
Driver.php
lib/Doctrine/DBAL/Driver/PDOMySql/Driver.php
+2
-2
Driver.php
lib/Doctrine/DBAL/Driver/PDOSqlite/Driver.php
+2
-2
PDOStatement.php
lib/Doctrine/DBAL/Driver/PDOStatement.php
+0
-2
Statement.php
lib/Doctrine/DBAL/Driver/Statement.php
+7
-7
DriverManager.php
lib/Doctrine/DBAL/DriverManager.php
+10
-9
AbstractPlatform.php
lib/Doctrine/DBAL/Platforms/AbstractPlatform.php
+1
-1
Collection.php
lib/Doctrine/ORM/Collection.php
+16
-129
Configuration.php
lib/Doctrine/ORM/Configuration.php
+2
-2
Entity.php
lib/Doctrine/ORM/Entity.php
+0
-2
EntityManager.php
lib/Doctrine/ORM/EntityManager.php
+12
-152
EntityRepository.php
lib/Doctrine/ORM/EntityRepository.php
+1
-1
AbstractIdGenerator.php
lib/Doctrine/ORM/Id/AbstractIdGenerator.php
+22
-6
Assigned.php
lib/Doctrine/ORM/Id/Assigned.php
+27
-7
IdentityGenerator.php
lib/Doctrine/ORM/Id/IdentityGenerator.php
+8
-6
CommitOrderCalculator.php
lib/Doctrine/ORM/Internal/CommitOrderCalculator.php
+1
-1
CommitOrderNode.php
lib/Doctrine/ORM/Internal/CommitOrderNode.php
+4
-5
ArrayDriver.php
lib/Doctrine/ORM/Internal/Hydration/ArrayDriver.php
+4
-6
ObjectDriver.php
lib/Doctrine/ORM/Internal/Hydration/ObjectDriver.php
+66
-48
StandardHydrator.php
lib/Doctrine/ORM/Internal/Hydration/StandardHydrator.php
+8
-19
Null.php
lib/Doctrine/ORM/Internal/Null.php
+13
-12
AssociationMapping.php
lib/Doctrine/ORM/Mapping/AssociationMapping.php
+3
-1
ClassMetadata.php
lib/Doctrine/ORM/Mapping/ClassMetadata.php
+43
-107
OneToManyMapping.php
lib/Doctrine/ORM/Mapping/OneToManyMapping.php
+11
-2
OneToOneMapping.php
lib/Doctrine/ORM/Mapping/OneToOneMapping.php
+2
-2
AbstractEntityPersister.php
lib/Doctrine/ORM/Persisters/AbstractEntityPersister.php
+23
-364
StandardEntityPersister.php
lib/Doctrine/ORM/Persisters/StandardEntityPersister.php
+6
-10
UnitOfWork.php
lib/Doctrine/ORM/UnitOfWork.php
+155
-97
BasicHydrationTest.php
tests/Orm/Hydration/BasicHydrationTest.php
+1
-0
UnitOfWorkTest.php
tests/Orm/UnitOfWorkTest.php
+111
-80
Doctrine_EntityManagerMock.php
tests/lib/mocks/Doctrine_EntityManagerMock.php
+21
-6
Doctrine_EntityPersisterMock.php
tests/lib/mocks/Doctrine_EntityPersisterMock.php
+19
-11
Doctrine_IdentityIdGeneratorMock.php
tests/lib/mocks/Doctrine_IdentityIdGeneratorMock.php
+20
-0
Doctrine_SequenceMock.php
tests/lib/mocks/Doctrine_SequenceMock.php
+0
-2
Doctrine_UnitOfWorkMock.php
tests/lib/mocks/Doctrine_UnitOfWorkMock.php
+12
-2
ForumUser.php
tests/models/forum/ForumUser.php
+12
-0
No files found.
lib/Doctrine/Common/ClassLoader.php
View file @
2395888f
<?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
$_basePath
s
=
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
->
_basePath
s
[
$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
->
_basePath
s
[
$prefix
]
.
DIRECTORY_SEPARATOR
;
}
$class
.=
str_replace
(
$this
->
_namespaceSeparator
,
DIRECTORY_SEPARATOR
,
$className
)
.
$this
->
_fileExtension
;
...
...
lib/Doctrine/Common/EventManager.php
View file @
2395888f
...
...
@@ -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
)
{
...
...
lib/Doctrine/DBAL/Configuration.php
View file @
2395888f
...
...
@@ -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.
...
...
lib/Doctrine/DBAL/Driver/PDOConnection.php
View file @
2395888f
<?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
lib/Doctrine/DBAL/Driver/PDOMySql/Driver.php
View file @
2395888f
<?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
{
...
...
lib/Doctrine/DBAL/Driver/PDOSqlite/Driver.php
View file @
2395888f
...
...
@@ -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
)
{
...
...
lib/Doctrine/DBAL/Driver/PDOStatement.php
View file @
2395888f
...
...
@@ -2,5 +2,3 @@
class
Doctrine_DBAL_Driver_PDOStatement
extends
PDOStatement
implements
Doctrine_DBAL_Driver_Statement
{}
?>
\ No newline at end of file
lib/Doctrine/DBAL/Driver/Statement.php
View file @
2395888f
...
...
@@ -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
...
...
lib/Doctrine/DBAL/DriverManager.php
View file @
2395888f
...
...
@@ -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
,
...
...
lib/Doctrine/DBAL/Platforms/AbstractPlatform.php
View file @
2395888f
...
...
@@ -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
...
...
lib/Doctrine/ORM/Collection.php
View file @
2395888f
...
...
@@ -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
();
/**
* Th
is
entity that owns this collection.
* Th
e
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
...
...
lib/Doctrine/ORM/Configuration.php
View file @
2395888f
...
...
@@ -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
;
}
...
...
lib/Doctrine/ORM/Entity.php
View file @
2395888f
...
...
@@ -21,8 +21,6 @@
#namespace Doctrine\ORM;
#use \Serializable;
/**
* Entity marker interface.
*
...
...
lib/Doctrine/ORM/EntityManager.php
View file @
2395888f
...
...
@@ -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\Abstract
EntityPersister
*/
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
()
{
...
...
lib/Doctrine/ORM/EntityRepository.php
View file @
2395888f
...
...
@@ -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.
...
...
lib/Doctrine/ORM/Id/AbstractIdGenerator.php
View file @
2395888f
<?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
lib/Doctrine/ORM/Id/Assigned.php
View file @
2395888f
...
...
@@ -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
lib/Doctrine/ORM/Id/IdentityGenerator.php
View file @
2395888f
...
...
@@ -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
lib/Doctrine/ORM/Internal/CommitOrderCalculator.php
View file @
2395888f
...
...
@@ -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
...
...
lib/Doctrine/ORM/Internal/CommitOrderNode.php
View file @
2395888f
...
...
@@ -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
lib/Doctrine/ORM/Internal/Hydration/ArrayDriver.php
View file @
2395888f
...
...
@@ -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.
...
...
lib/Doctrine/ORM/Internal/Hydration/ObjectDriver.php
View file @
2395888f
...
...
@@ -16,20 +16,21 @@
*
* 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\Internal\Hydration;
/**
*
Hydration strategy used for creating graphs of entities
.
*
Defines the object hydration strategy
.
*
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @link www.
phpdoctrine
.org
* @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.
*/
class
Doctrine_ORM_Internal_Hydration_ObjectDriver
{
...
...
@@ -38,15 +39,18 @@ class Doctrine_ORM_Internal_Hydration_ObjectDriver
/** Memory for initialized relations */
private
$_initializedRelations
=
array
();
/** Null object */
private
$_nullObject
;
//
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->_nullObject = Doctrine_ORM_Internal_Null::$INSTANCE;
$this
->
_em
=
$em
;
$this
->
_uow
=
$this
->
_em
->
getUnitOfWork
();
}
public
function
getElementCollection
(
$component
)
...
...
@@ -59,7 +63,7 @@ class Doctrine_ORM_Internal_Hydration_ObjectDriver
public
function
getLastKey
(
$coll
)
{
// check needed because of mixed results.
// is_object instead of is_array because is_array is slow.
// is_object instead of is_array because is_array is slow
on large arrays
.
if
(
is_object
(
$coll
))
{
$coll
->
end
();
return
$coll
->
key
();
...
...
@@ -71,10 +75,8 @@ class Doctrine_ORM_Internal_Hydration_ObjectDriver
public
function
initRelatedCollection
(
$entity
,
$name
)
{
//$class = get_class($entity);
$oid
=
spl_object_id
(
$entity
);
$oid
=
spl_object_hash
(
$entity
);
$classMetadata
=
$this
->
_metadataMap
[
$oid
];
//$classMetadata = $this->_em->getClassMetadata(get_class($entity));
if
(
!
isset
(
$this
->
_initializedRelations
[
$oid
][
$name
]))
{
$relation
=
$classMetadata
->
getAssociationMapping
(
$name
);
$relatedClass
=
$this
->
_em
->
getClassMetadata
(
$relation
->
getTargetEntityName
());
...
...
@@ -83,6 +85,7 @@ class Doctrine_ORM_Internal_Hydration_ObjectDriver
$coll
->
_setHydrationFlag
(
true
);
$classMetadata
->
getReflectionProperty
(
$name
)
->
setValue
(
$entity
,
$coll
);
$this
->
_initializedRelations
[
$oid
][
$name
]
=
true
;
$this
->
_uow
->
setOriginalEntityProperty
(
$oid
,
$name
,
$coll
);
}
}
...
...
@@ -93,91 +96,102 @@ class Doctrine_ORM_Internal_Hydration_ObjectDriver
public
function
getNullPointer
()
{
return
$this
->
_nullObject
;
//TODO: Return VirtualProxy if lazy association
return
null
;
}
public
function
getElement
(
array
$data
,
$className
)
{
$entity
=
$this
->
_em
->
getUnitOfWork
()
->
createEntity
(
$className
,
$data
);
$this
->
_metadataMap
[
spl_object_id
(
$entity
)]
=
$this
->
_em
->
getClassMetadata
(
$className
);
$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_id
(
$entity1
)];
$classMetadata2
=
$this
->
_metadataMap
[
spl_object_id
(
$entity2
)];
//$classMetadata1 = $this->_em->getClassMetadata(get_class($entity1));
//$classMetadata2 = $this->_em->getClassMetadata(get_class($entity2));
$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
)
->
add
(
$entity2
,
$indexValue
);
}
/**
* 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_id
(
$entity1
)];
//$classMetadata1 = $this->_em->getClassMetadata(get_class($entity1));
$classMetadata1
->
getReflectionProperty
(
$property
)
->
getValue
(
$entity1
)
->
add
(
$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
)
{
$
classMetadata1
=
$this
->
_metadataMap
[
spl_object_id
(
$entity1
)]
;
//$classMetadata1 = $this->_em->getClassMetadata(get_class($entity1))
;
$classMetadata1
->
getReflectionProperty
(
$property
)
->
setValue
(
$entity1
,
$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
))
{
$
refProp
=
$targetClass
->
getReflectionProperty
(
$targetClass
->
getInverseAssociationMapping
(
$fieldName
)
->
getSourceFieldName
()
);
$
refProp
->
setValue
(
$entity2
,
$entity1
)
;
$
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
$targetClass
->
getReflectionProperty
(
$relation
->
getMappedByFieldName
())
->
setValue
(
$entity2
,
$entity1
);
$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_
id
(
$entity
)]
->
getReflectionProperty
(
$assocField
)
return
$this
->
_metadataMap
[
spl_object_
hash
(
$entity
)]
->
getReflectionProperty
(
$assocField
)
->
getValue
(
$entity
)
->
containsKey
(
$indexField
);
/*return $this->_em->getClassMetadata(get_class($entity))->getReflectionProperty($assocField)
->getValue($entity)->containsKey($indexField);*/
}
public
function
isFieldSet
(
$entity
,
$field
)
{
return
$this
->
_metadataMap
[
spl_object_
id
(
$entity
)]
->
getReflectionProperty
(
$field
)
return
$this
->
_metadataMap
[
spl_object_
hash
(
$entity
)]
->
getReflectionProperty
(
$field
)
->
getValue
(
$entity
)
!==
null
;
/*return $this->_em->getClassMetadata(get_class($entity))->getReflectionProperty($field)
->getValue($entity) !== null;*/
}
public
function
getFieldValue
(
$entity
,
$field
)
{
return
$this
->
_metadataMap
[
spl_object_
id
(
$entity
)]
->
getReflectionProperty
(
$field
)
return
$this
->
_metadataMap
[
spl_object_
hash
(
$entity
)]
->
getReflectionProperty
(
$field
)
->
getValue
(
$entity
);
/*return $this->_em->getClassMetadata(get_class($entity))->getReflectionProperty($field)
->getValue($entity);*/
}
public
function
getReferenceValue
(
$entity
,
$field
)
{
return
$this
->
_metadataMap
[
spl_object_
id
(
$entity
)]
->
getReflectionProperty
(
$field
)
return
$this
->
_metadataMap
[
spl_object_
hash
(
$entity
)]
->
getReflectionProperty
(
$field
)
->
getValue
(
$entity
);
/*return $this->_em->getClassMetadata(get_class($entity))->getReflectionProperty($field)
->getValue($entity);*/
}
public
function
addElementToIndexedCollection
(
$coll
,
$entity
,
$keyField
)
...
...
@@ -195,14 +209,15 @@ class Doctrine_ORM_Internal_Hydration_ObjectDriver
* 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 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
===
$this
->
_nullObject
)
{
if
(
$coll
===
/*$this->_nullObject*/
null
)
{
echo
"HERE!"
;
unset
(
$resultPointers
[
$dqlAlias
]);
// Ticket #1228
return
;
}
...
...
@@ -230,10 +245,13 @@ class Doctrine_ORM_Internal_Hydration_ObjectDriver
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
();
}
}
lib/Doctrine/ORM/Internal/Hydration/StandardHydrator.php
View file @
2395888f
...
...
@@ -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 t
ask t
o 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
;
}
//
c
heck the type of the relation (many or single-valued)
//
C
heck 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
[
$r
owNumber
][
$name
]
=
$value
;
$result
[
$r
esultCounter
-
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
)
{
...
...
lib/Doctrine/ORM/Internal/Null.php
View file @
2395888f
...
...
@@ -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
();
...
...
lib/Doctrine/ORM/Mapping/AssociationMapping.php
View file @
2395888f
...
...
@@ -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 */
...
...
lib/Doctrine/ORM/Mapping/ClassMetadata.php
View file @
2395888f
...
...
@@ -31,10 +31,8 @@
*
* @author Roman Borschel <roman@code-factory.org>
* @since 2.0
* @todo Rename to ClassDescriptor.
*/
class
Doctrine_ORM_Mapping_ClassMetadata
extends
Doctrine_Common_ClassMetadata
implements
Doctrine_Common_Configurable
,
Serializable
class
Doctrine_ORM_Mapping_ClassMetadata
extends
Doctrine_Common_ClassMetadata
implements
Serializable
{
/* The inheritance mapping types */
/**
...
...
@@ -136,7 +134,7 @@ class Doctrine_ORM_Mapping_ClassMetadata extends Doctrine_Common_ClassMetadata
/**
* The field names of all fields that are part of the identifier/primary key
* of the
describ
ed entity class.
* of the
mapp
ed entity class.
*
* @var array
*/
...
...
@@ -331,26 +329,49 @@ class Doctrine_ORM_Mapping_ClassMetadata extends Doctrine_Common_ClassMetadata
$prop
->
setAccessible
(
true
);
$this
->
_reflectionProperties
[
$prop
->
getName
()]
=
$prop
;
}
//$this->_isVirtualPropertyObject = is_subclass_of($entityName, 'Doctrine\Common\VirtualPropertyObject');
}
/**
* Gets the ReflectionClass instance of the mapped class.
*
* @return ReflectionClass
*/
public
function
getReflectionClass
()
{
return
$this
->
_reflectionClass
;
}
/**
* Gets the ReflectionPropertys of the mapped class.
*
* @return array An array of ReflectionProperty instances.
*/
public
function
getReflectionProperties
()
{
return
$this
->
_reflectionProperties
;
}
/**
* Gets a ReflectionProperty for a specific field of the mapped class.
*
* @param string $name
* @return ReflectionProperty
*/
public
function
getReflectionProperty
(
$name
)
{
return
$this
->
_reflectionProperties
[
$name
];
}
public
function
getSingleIdReflectionProperty
()
{
if
(
$this
->
_isIdentifierComposite
)
{
throw
new
Doctrine_Exception
(
"getSingleIdReflectionProperty called on entity with composite key."
);
}
return
$this
->
_reflectionProperties
[
$this
->
_identifier
[
0
]];
}
/**
*
getComponentName
*
Gets the name of the mapped class.
*
* @return string
*/
...
...
@@ -360,11 +381,11 @@ class Doctrine_ORM_Mapping_ClassMetadata extends Doctrine_Common_ClassMetadata
}
/**
* Gets the name of the root class of the entity hierarchy. If the entity described
* by th
e ClassMetadata
is not participating in a hierarchy, this is the same as the
* Gets the name of the root class of the
mapped
entity hierarchy. If the entity described
* by th
is ClassMetadata instance
is not participating in a hierarchy, this is the same as the
* name returned by {@link getClassName()}.
*
* @return string
* @return string
The name of the root class of the entity hierarchy.
*/
public
function
getRootClassName
()
{
...
...
@@ -387,7 +408,7 @@ class Doctrine_ORM_Mapping_ClassMetadata extends Doctrine_Common_ClassMetadata
}
/**
* Check if the class has a composite identifier.
* Check
s
if the class has a composite identifier.
*
* @param string $fieldName The field name
* @return boolean TRUE if the identifier is composite, FALSE otherwise.
...
...
@@ -449,12 +470,10 @@ class Doctrine_ORM_Mapping_ClassMetadata extends Doctrine_Common_ClassMetadata
if
(
!
array_key_exists
(
$name
,
$this
->
_tableOptions
))
{
throw
new
Doctrine_ClassMetadata_Exception
(
"Unknown table option: '
$name
'."
);
}
return
$this
->
_tableOptions
[
$name
];
}
/**
* getTableOptions
* returns all table options.
*
* @return array all options and their values
...
...
@@ -469,7 +488,7 @@ class Doctrine_ORM_Mapping_ClassMetadata extends Doctrine_Common_ClassMetadata
* If the column name for the field cannot be found, the given field name
* is returned.
*
* @param string $
alias
The field name.
* @param string $
fieldName
The field name.
* @return string The column name.
*/
public
function
getColumnName
(
$fieldName
)
...
...
@@ -479,7 +498,7 @@ class Doctrine_ORM_Mapping_ClassMetadata extends Doctrine_Common_ClassMetadata
}
/**
* Gets the mapping of a (regular) field
s
that holds some data but not a
* Gets the mapping of a (regular) field that holds some data but not a
* reference to another object.
*
* @param string $fieldName The field name.
...
...
@@ -490,7 +509,6 @@ class Doctrine_ORM_Mapping_ClassMetadata extends Doctrine_Common_ClassMetadata
if
(
!
isset
(
$this
->
_fieldMappings
[
$fieldName
]))
{
throw
Doctrine_MappingException
::
mappingNotFound
(
$fieldName
);
}
return
$this
->
_fieldMappings
[
$fieldName
];
}
...
...
@@ -499,14 +517,13 @@ class Doctrine_ORM_Mapping_ClassMetadata extends Doctrine_Common_ClassMetadata
*
* @param string $fieldName The field name that represents the association in
* the object model.
* @return Doctrine
::ORM::Mapping::
AssociationMapping The mapping.
* @return Doctrine
\ORM\Mapping\
AssociationMapping The mapping.
*/
public
function
getAssociationMapping
(
$fieldName
)
{
if
(
!
isset
(
$this
->
_associationMappings
[
$fieldName
]))
{
throw
new
Doctrine_Exception
(
"Mapping not found:
$fieldName
"
);
}
return
$this
->
_associationMappings
[
$fieldName
];
}
...
...
@@ -514,7 +531,7 @@ class Doctrine_ORM_Mapping_ClassMetadata extends Doctrine_Common_ClassMetadata
* Gets the inverse association mapping for the given fieldname.
*
* @param string $mappedByFieldName
* @return Doctrine
::ORM::Mapping::
AssociationMapping The mapping.
* @return Doctrine
\ORM\Mapping\
AssociationMapping The mapping.
*/
public
function
getInverseAssociationMapping
(
$mappedByFieldName
)
{
...
...
@@ -608,7 +625,7 @@ class Doctrine_ORM_Mapping_ClassMetadata extends Doctrine_Common_ClassMetadata
}
/**
* Validates & completes the field mapping.
Default values are applied here.
* Validates & completes the field mapping.
*
* @param array $mapping The field mapping to validated & complete.
* @return array The validated and completed field mapping.
...
...
@@ -689,59 +706,6 @@ class Doctrine_ORM_Mapping_ClassMetadata extends Doctrine_Common_ClassMetadata
//...
}
private
$_entityIdentifiers
=
array
();
/**
* Gets the identifier of an entity.
*
* @param object $entity
* @return array Map of identifier field names to values.
*/
public
function
getEntityIdentifier
(
$entity
)
{
$oid
=
spl_object_id
(
$entity
);
if
(
!
isset
(
$this
->
_entityIdentifiers
[
$oid
]))
{
if
(
!
$this
->
isIdentifierComposite
())
{
$idField
=
$this
->
_identifier
[
0
];
$idValue
=
$this
->
_reflectionProperties
[
$idField
]
->
getValue
(
$entity
);
if
(
isset
(
$idValue
))
{
//return array($idField => $idValue);
$this
->
_entityIdentifiers
[
$oid
]
=
array
(
$idField
=>
$idValue
);
}
else
{
return
false
;
}
//$this->_entityIdentifiers[$oid] = false;
}
else
{
$id
=
array
();
foreach
(
$this
->
getIdentifierFieldNames
()
as
$idFieldName
)
{
$idValue
=
$this
->
_reflectionProperties
[
$idFieldName
]
->
getValue
(
$entity
);
if
(
isset
(
$idValue
))
{
$id
[
$idFieldName
]
=
$idValue
;
}
}
//return $id;
$this
->
_entityIdentifiers
[
$oid
]
=
$id
;
}
}
return
$this
->
_entityIdentifiers
[
$oid
];
}
/**
*
*
* @param <type> $entity
* @param <type> $identifier
*/
public
function
setEntityIdentifier
(
$entity
,
$identifier
)
{
if
(
is_array
(
$identifier
))
{
foreach
(
$identifier
as
$fieldName
=>
$value
)
{
$this
->
_reflectionProperties
[
$fieldName
]
->
setValue
(
$entity
,
$value
);
}
}
else
{
$this
->
_reflectionProperties
[
$this
->
_identifier
[
0
]]
->
setValue
(
$entity
,
$identifier
);
}
}
/**
* Gets the identifier (primary key) field names of the class.
*
...
...
@@ -852,7 +816,7 @@ class Doctrine_ORM_Mapping_ClassMetadata extends Doctrine_Common_ClassMetadata
}
/**
* Sets the type of Id generator to use for th
is
class.
* Sets the type of Id generator to use for th
e mapped
class.
*/
public
function
setIdGeneratorType
(
$generatorType
)
{
...
...
@@ -860,9 +824,9 @@ class Doctrine_ORM_Mapping_ClassMetadata extends Doctrine_Common_ClassMetadata
}
/**
* Checks whether the class uses an Id generator.
* Checks whether the
mapped
class uses an Id generator.
*
* @return boolean TRUE if the class uses an Id generator, FALSE otherwise.
* @return boolean TRUE if the
mapped
class uses an Id generator, FALSE otherwise.
*/
public
function
usesIdGenerator
()
{
...
...
@@ -1010,7 +974,7 @@ class Doctrine_ORM_Mapping_ClassMetadata extends Doctrine_Common_ClassMetadata
}
/**
* Gets the inheritance mapping type used by the class.
* Gets the inheritance mapping type used by the
mapped
class.
*
* @return string
*/
...
...
@@ -1020,7 +984,7 @@ class Doctrine_ORM_Mapping_ClassMetadata extends Doctrine_Common_ClassMetadata
}
/**
* Sets the subclasses of the class.
* Sets the subclasses of the
mapped
class.
* All entity classes that participate in a hierarchy and have subclasses
* need to declare them this way.
*
...
...
@@ -1136,10 +1100,6 @@ class Doctrine_ORM_Mapping_ClassMetadata extends Doctrine_Common_ClassMetadata
*/
public
function
getInheritanceOption
(
$name
)
{
/*if ( ! array_key_exists($name, $this->_inheritanceOptions)) {
throw new Doctrine_ClassMetadata_Exception("Unknown inheritance option: '$name'.");
}*/
return
$this
->
_inheritanceOptions
[
$name
];
}
...
...
@@ -1179,7 +1139,6 @@ class Doctrine_ORM_Mapping_ClassMetadata extends Doctrine_Common_ClassMetadata
throw
Doctrine_MappingException
::
invalidInheritanceOption
(
$name
);
}
}
$this
->
_inheritanceOptions
[
$name
]
=
$value
;
}
...
...
@@ -1350,7 +1309,6 @@ class Doctrine_ORM_Mapping_ClassMetadata extends Doctrine_Common_ClassMetadata
public
function
serialize
()
{
//$contents = get_object_vars($this);
/* @TODO How to handle $this->_em and $this->_parser ? */
//return serialize($contents);
return
""
;
}
...
...
@@ -1506,7 +1464,7 @@ class Doctrine_ORM_Mapping_ClassMetadata extends Doctrine_Common_ClassMetadata
*/
public
function
setCustomRepositoryClass
(
$repositoryClassName
)
{
if
(
!
is_subclass_of
(
$repositoryClassName
,
'Doctrine
_
EntityRepository'
))
{
if
(
!
is_subclass_of
(
$repositoryClassName
,
'Doctrine
\ORM\
EntityRepository'
))
{
throw
new
Doctrine_ClassMetadata_Exception
(
"The custom repository must be a subclass"
.
" of Doctrine_EntityRepository."
);
}
...
...
@@ -1640,37 +1598,15 @@ class Doctrine_ORM_Mapping_ClassMetadata extends Doctrine_Common_ClassMetadata
{
return
$columnName
===
$this
->
_inheritanceOptions
[
'discriminatorColumn'
];
}
public
function
hasAttribute
(
$name
)
{
return
isset
(
$this
->
_attributes
[
$name
]);
}
public
function
getAttribute
(
$name
)
{
if
(
$this
->
hasAttribute
(
$name
))
{
return
$this
->
_attributes
[
$name
];
}
}
public
function
setAttribute
(
$name
,
$value
)
{
if
(
$this
->
hasAttribute
(
$name
))
{
$this
->
_attributes
[
$name
]
=
$value
;
}
}
public
function
hasAssociation
(
$fieldName
)
{
return
isset
(
$this
->
_associationMappings
[
$fieldName
]);
}
/**
*
*/
public
function
__toString
()
{
return
spl_object_hash
(
$this
);
return
__CLASS__
.
'@'
.
spl_object_hash
(
$this
);
}
}
lib/Doctrine/ORM/Mapping/OneToManyMapping.php
View file @
2395888f
...
...
@@ -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 complete
d
the mapping.
* Validates and complete
s
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
)
{
}
}
...
...
lib/Doctrine/ORM/Mapping/OneToOneMapping.php
View file @
2395888f
...
...
@@ -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?
...
...
lib/Doctrine/ORM/Persisters/AbstractEntityPersister.php
View file @
2395888f
...
...
@@ -41,7 +41,7 @@ abstract class Doctrine_ORM_Persisters_AbstractEntityPersister
/**
* Metadata object that descibes the mapping of the mapped entity class.
*
* @var Doctrine
_
ClassMetadata
* @var Doctrine
\ORM\Mapping\
ClassMetadata
*/
protected
$_classMetadata
;
...
...
@@ -53,26 +53,28 @@ abstract class Doctrine_ORM_Persisters_AbstractEntityPersister
protected
$_entityName
;
/**
* The
Doctrine_Connection object that the database connection of this mapper
.
* The
Connection instance
.
*
* @var Doctrine
::DBAL::
Connection $conn
* @var Doctrine
\DBAL\
Connection $conn
*/
protected
$_conn
;
/**
* The EntityManager.
* The EntityManager
instance
.
*
* @var Doctrine
::ORM::
EntityManager
* @var Doctrine
\ORM\
EntityManager
*/
protected
$_em
;
/**
* Null object.
*/
private
$_nullObject
;
//
private $_nullObject;
/**
* Constructs a new EntityPersister.
* Initializes a new instance of a class derived from AbstractEntityPersister
* that uses the given EntityManager and persists instances of the class described
* by the given class metadata descriptor.
*/
public
function
__construct
(
Doctrine_ORM_EntityManager
$em
,
Doctrine_ORM_Mapping_ClassMetadata
$classMetadata
)
{
...
...
@@ -80,31 +82,36 @@ abstract class Doctrine_ORM_Persisters_AbstractEntityPersister
$this
->
_entityName
=
$classMetadata
->
getClassName
();
$this
->
_conn
=
$em
->
getConnection
();
$this
->
_classMetadata
=
$classMetadata
;
$this
->
_nullObject
=
Doctrine_ORM_Internal_Null
::
$INSTANCE
;
//
$this->_nullObject = Doctrine_ORM_Internal_Null::$INSTANCE;
}
/**
* Inserts an entity.
*
* @param Doctrine
::ORM::
Entity $entity The entity to insert.
* @return
voi
d
* @param Doctrine
\ORM\
Entity $entity The entity to insert.
* @return
mixe
d
*/
public
function
insert
(
$entity
)
{
$insertData
=
array
();
$this
->
_prepareData
(
$entity
,
$insertData
,
true
);
$this
->
_conn
->
insert
(
$this
->
_classMetadata
->
getTableName
(),
$insertData
);
$idGen
=
$this
->
_em
->
getIdGenerator
(
$this
->
_classMetadata
->
getClassName
());
if
(
$idGen
->
isPostInsertGenerator
())
{
return
$idGen
->
generate
(
$entity
);
}
return
null
;
}
/**
* Updates an entity.
*
* @param Doctrine
::ORM::
Entity $entity The entity to update.
* @param Doctrine
\ORM\
Entity $entity The entity to update.
* @return void
*/
public
function
update
(
Doctrine_ORM_Entity
$entity
)
{
$dataChangeSet
=
$entity
->
_getDataChangeSet
();
/*
$dataChangeSet = $entity->_getDataChangeSet();
$referenceChangeSet = $entity->_getReferenceChangeSet();
foreach ($referenceChangeSet as $field => $change) {
...
...
@@ -118,14 +125,14 @@ abstract class Doctrine_ORM_Persisters_AbstractEntityPersister
}
//...
}
*/
//TODO: perform update
}
/**
* Deletes an entity.
*
* @param Doctrine
::ORM::
Entity $entity The entity to delete.
* @param Doctrine
\ORM\
Entity $entity The entity to delete.
* @return void
*/
public
function
delete
(
Doctrine_ORM_Entity
$entity
)
...
...
@@ -209,7 +216,6 @@ abstract class Doctrine_ORM_Persisters_AbstractEntityPersister
/**
* Callback that is invoked during the SQL construction process.
* @todo Move to ClassMetadata?
*/
public
function
getCustomJoins
()
{
...
...
@@ -218,7 +224,6 @@ abstract class Doctrine_ORM_Persisters_AbstractEntityPersister
/**
* Callback that is invoked during the SQL construction process.
* @todo Move to ClassMetadata?
*/
public
function
getCustomFields
()
{
...
...
@@ -226,24 +231,7 @@ abstract class Doctrine_ORM_Persisters_AbstractEntityPersister
}
/**
* Assumes that the keys of the given field array are field names and converts
* them to column names.
*
* @return array
*/
/*protected function _convertFieldToColumnNames(array $fields, Doctrine_ClassMetadata $class)
{
$converted = array();
foreach ($fields as $fieldName => $value) {
$converted[$class->getColumnName($fieldName)] = $value;
}
return $converted;
}*/
/**
* Returns an array of modified fields and values with data preparation
* adds column aggregation inheritance and converts Records into primary key values
* Prepares all the entity data for insertion into the database.
*
* @param array $array
* @return void
...
...
@@ -255,7 +243,7 @@ abstract class Doctrine_ORM_Persisters_AbstractEntityPersister
$type
=
$this
->
_classMetadata
->
getTypeOfField
(
$field
);
$columnName
=
$this
->
_classMetadata
->
getColumnName
(
$field
);
if
(
$newVal
===
Doctrine_ORM_Internal_Null
::
$INSTANCE
)
{
if
(
is_null
(
$newVal
)
)
{
$result
[
$columnName
]
=
null
;
}
else
if
(
is_object
(
$newVal
))
{
$assocMapping
=
$this
->
_classMetadata
->
getAssociationMapping
(
$field
);
...
...
@@ -301,336 +289,7 @@ abstract class Doctrine_ORM_Persisters_AbstractEntityPersister
$result
[
$discColumn
]
=
array_search
(
$this
->
_entityName
,
$discMap
);
}
}
#############################################################
# The following is old code that needs to be removed/ported
/**
* deletes all related composites
* this method is always called internally when a record is deleted
*
* @throws PDOException if something went wrong at database level
* @return void
*/
protected
function
_deleteComposites
(
Doctrine_ORM_Entity
$record
)
{
$classMetadata
=
$this
->
_classMetadata
;
foreach
(
$classMetadata
->
getRelations
()
as
$fk
)
{
if
(
$fk
->
isComposite
())
{
$obj
=
$record
->
get
(
$fk
->
getAlias
());
if
(
$obj
instanceof
Doctrine_ORM_Entity
&&
$obj
->
_state
()
!=
Doctrine_ORM_Entity
::
STATE_LOCKED
)
{
$obj
->
delete
(
$this
->
_mapper
->
getConnection
());
}
}
}
}
/**
* Returns the connection the mapper is currently using.
*
* @return Doctrine_Connection|null The connection object.
*/
public
function
getConnection
()
{
return
$this
->
_conn
;
}
public
function
getEntityManager
()
{
return
$this
->
_em
;
}
/**
* getComponentName
*
* @return void
* @deprecated Use getMappedClassName()
*/
public
function
getComponentName
()
{
return
$this
->
_domainClassName
;
}
/**
* Saves an entity.
*
* @param Doctrine_Entity $record The entity to save.
* @param Doctrine_Connection $conn The connection to use. Will default to the mapper's
* connection.
*/
public
function
save
(
Doctrine_ORM_Entity
$record
)
{
if
(
!
(
$record
instanceof
$this
->
_domainClassName
))
{
throw
new
Doctrine_Mapper_Exception
(
"Mapper of type "
.
$this
->
_domainClassName
.
"
can't save instances of type"
.
get_class
(
$record
)
.
"."
);
}
if
(
$conn
===
null
)
{
$conn
=
$this
->
_conn
;
}
$state
=
$record
->
_state
();
if
(
$state
===
Doctrine_ORM_Entity
::
STATE_LOCKED
)
{
return
false
;
}
$record
->
_state
(
Doctrine_ORM_Entity
::
STATE_LOCKED
);
try
{
$conn
->
beginInternalTransaction
();
$saveLater
=
$this
->
_saveRelated
(
$record
);
$record
->
_state
(
$state
);
if
(
$record
->
isValid
())
{
$this
->
_insertOrUpdate
(
$record
);
}
else
{
$conn
->
getTransaction
()
->
addInvalid
(
$record
);
}
$state
=
$record
->
_state
();
$record
->
_state
(
Doctrine_ORM_Entity
::
STATE_LOCKED
);
foreach
(
$saveLater
as
$fk
)
{
$alias
=
$fk
->
getAlias
();
if
(
$record
->
hasReference
(
$alias
))
{
$obj
=
$record
->
$alias
;
// check that the related object is not an instance of Doctrine_Null
if
(
!
(
$obj
instanceof
Doctrine_Null
))
{
$obj
->
save
(
$conn
);
}
}
}
// save the MANY-TO-MANY associations
$this
->
saveAssociations
(
$record
);
// reset state
$record
->
_state
(
$state
);
$conn
->
commit
();
}
catch
(
Exception
$e
)
{
$conn
->
rollback
();
throw
$e
;
}
return
true
;
}
/**
* Inserts or updates an entity, depending on it's state.
*
* @param Doctrine_Entity $record The entity to insert/update.
*/
protected
function
_insertOrUpdate
(
Doctrine_ORM_Entity
$record
)
{
//$record->preSave();
//$this->notifyEntityListeners($record, 'preSave', Doctrine_Event::RECORD_SAVE);
switch
(
$record
->
_state
())
{
case
Doctrine_ORM_Entity
::
STATE_TDIRTY
:
$this
->
_insert
(
$record
);
break
;
case
Doctrine_ORM_Entity
::
STATE_DIRTY
:
case
Doctrine_ORM_Entity
::
STATE_PROXY
:
$this
->
_update
(
$record
);
break
;
case
Doctrine_ORM_Entity
::
STATE_CLEAN
:
case
Doctrine_ORM_Entity
::
STATE_TCLEAN
:
// do nothing
break
;
}
//$record->postSave();
//$this->notifyEntityListeners($record, 'postSave', Doctrine_Event::RECORD_SAVE);
}
/**
* saves the given record
*
* @param Doctrine_Entity $record
* @return void
*/
public
function
saveSingleRecord
(
Doctrine_ORM_Entity
$record
)
{
$this
->
_insertOrUpdate
(
$record
);
}
/**
* saves all related records to $record
*
* @throws PDOException if something went wrong at database level
* @param Doctrine_Entity $record
*/
protected
function
_saveRelated
(
Doctrine_ORM_Entity
$record
)
{
$saveLater
=
array
();
foreach
(
$record
->
_getReferences
()
as
$k
=>
$v
)
{
$rel
=
$record
->
getTable
()
->
getRelation
(
$k
);
$local
=
$rel
->
getLocal
();
$foreign
=
$rel
->
getForeign
();
if
(
$rel
instanceof
Doctrine_Relation_ForeignKey
)
{
$saveLater
[
$k
]
=
$rel
;
}
else
if
(
$rel
instanceof
Doctrine_Relation_LocalKey
)
{
// ONE-TO-ONE relationship
$obj
=
$record
->
get
(
$rel
->
getAlias
());
// Protection against infinite function recursion before attempting to save
if
(
$obj
instanceof
Doctrine_ORM_Entity
&&
$obj
->
isModified
())
{
$obj
->
save
();
/** Can this be removed?
$id = array_values($obj->identifier());
foreach ((array) $rel->getLocal() as $k => $field) {
$record->set($field, $id[$k]);
}
*/
}
}
}
return
$saveLater
;
}
/**
* saveAssociations
*
* this method takes a diff of one-to-many / many-to-many original and
* current collections and applies the changes
*
* for example if original many-to-many related collection has records with
* primary keys 1,2 and 3 and the new collection has records with primary keys
* 3, 4 and 5, this method would first destroy the associations to 1 and 2 and then
* save new associations to 4 and 5
*
* @throws Doctrine_Connection_Exception if something went wrong at database level
* @param Doctrine_Entity $record
* @return void
*/
public
function
saveAssociations
(
Doctrine_ORM_Entity
$record
)
{
foreach
(
$record
->
_getReferences
()
as
$relationName
=>
$relatedObject
)
{
if
(
$relatedObject
===
Doctrine_Null
::
$INSTANCE
)
{
continue
;
}
$rel
=
$record
->
getTable
()
->
getRelation
(
$relationName
);
if
(
$rel
instanceof
Doctrine_Relation_Association
)
{
$relatedObject
->
save
(
$this
->
_conn
);
$assocTable
=
$rel
->
getAssociationTable
();
foreach
(
$relatedObject
->
getDeleteDiff
()
as
$r
)
{
$query
=
'DELETE FROM '
.
$assocTable
->
getTableName
()
.
' WHERE '
.
$rel
->
getForeign
()
.
' = ?'
.
' AND '
.
$rel
->
getLocal
()
.
' = ?'
;
// FIXME: composite key support
$ids1
=
$r
->
identifier
();
$id1
=
count
(
$ids1
)
>
0
?
array_pop
(
$ids1
)
:
null
;
$ids2
=
$record
->
identifier
();
$id2
=
count
(
$ids2
)
>
0
?
array_pop
(
$ids2
)
:
null
;
$this
->
_conn
->
execute
(
$query
,
array
(
$id1
,
$id2
));
}
$assocMapper
=
$this
->
_conn
->
getMapper
(
$assocTable
->
getComponentName
());
foreach
(
$relatedObject
->
getInsertDiff
()
as
$r
)
{
$assocRecord
=
$assocMapper
->
create
();
$assocRecord
->
set
(
$assocTable
->
getFieldName
(
$rel
->
getForeign
()),
$r
);
$assocRecord
->
set
(
$assocTable
->
getFieldName
(
$rel
->
getLocal
()),
$record
);
$assocMapper
->
save
(
$assocRecord
);
}
}
}
}
/**
* Updates an entity.
*
* @param Doctrine_Entity $record record to be updated
* @return boolean whether or not the update was successful
* @todo Move to Doctrine_Table (which will become Doctrine_Mapper).
*/
protected
function
_update
(
Doctrine_ORM_Entity
$record
)
{
$record
->
preUpdate
();
$this
->
notifyEntityListeners
(
$record
,
'preUpdate'
,
Doctrine_Event
::
RECORD_UPDATE
);
$table
=
$this
->
_classMetadata
;
$this
->
_doUpdate
(
$record
);
$record
->
postUpdate
();
$this
->
notifyEntityListeners
(
$record
,
'postUpdate'
,
Doctrine_Event
::
RECORD_UPDATE
);
return
true
;
}
abstract
protected
function
_doUpdate
(
Doctrine_ORM_Entity
$entity
);
/**
* Inserts an entity.
*
* @param Doctrine_Entity $record record to be inserted
* @return boolean
*/
protected
function
_insert
(
Doctrine_ORM_Entity
$record
)
{
//$record->preInsert();
//$this->notifyEntityListeners($record, 'preInsert', Doctrine_Event::RECORD_INSERT);
$this
->
_doInsert
(
$record
);
$this
->
addRecord
(
$record
);
//$record->postInsert();
//$this->notifyEntityListeners($record, 'postInsert', Doctrine_Event::RECORD_INSERT);
return
true
;
}
abstract
protected
function
_doInsert
(
Doctrine_ORM_Entity
$entity
);
/**
* Deletes given entity and all it's related entities.
*
* Triggered Events: onPreDelete, onDelete.
*
* @return boolean true on success, false on failure
* @throws Doctrine_Mapper_Exception
*/
public
function
delete_old
(
Doctrine_ORM_Entity
$record
)
{
if
(
!
$record
->
exists
())
{
return
false
;
}
if
(
!
(
$record
instanceof
$this
->
_domainClassName
))
{
throw
new
Doctrine_Mapper_Exception
(
"Mapper of type "
.
$this
->
_domainClassName
.
"
can't save instances of type"
.
get_class
(
$record
)
.
"."
);
}
if
(
$conn
==
null
)
{
$conn
=
$this
->
_conn
;
}
$record
->
preDelete
();
$this
->
notifyEntityListeners
(
$record
,
'preDelete'
,
Doctrine_Event
::
RECORD_DELETE
);
$table
=
$this
->
_classMetadata
;
$state
=
$record
->
_state
();
$record
->
_state
(
Doctrine_ORM_Entity
::
STATE_LOCKED
);
$this
->
_doDelete
(
$record
);
$record
->
postDelete
();
$this
->
notifyEntityListeners
(
$record
,
'postDelete'
,
Doctrine_Event
::
RECORD_DELETE
);
return
true
;
}
}
lib/Doctrine/ORM/Persisters/StandardEntityPersister.php
View file @
2395888f
...
...
@@ -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
;
...
...
lib/Doctrine/ORM/UnitOfWork.php
View file @
2395888f
...
...
@@ -32,11 +32,8 @@
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @link www.phpdoctrine.org
* @since 2.0
* @version $Revision: 4947 $
* @author Konsta Vesterinen <kvesteri@cc.hut.fi>
* @version $Revision$
* @author Roman Borschel <roman@code-factory.org>
* @todo Rename: Doctrine::ORM::UnitOfWork.
* @todo Turn connection exceptions into UnitOfWorkExceptions.
*/
class
Doctrine_ORM_UnitOfWork
{
...
...
@@ -89,6 +86,13 @@ class Doctrine_ORM_UnitOfWork
*/
protected
$_identityMap
=
array
();
/**
* Map of all identifiers. Keys are object ids.
*
* @var array
*/
private
$_entityIdentifiers
=
array
();
/**
* Map of the original entity data of entities fetched from the database.
* Keys are object ids. This is used for calculating changesets at commit time.
...
...
@@ -199,7 +203,7 @@ class Doctrine_ORM_UnitOfWork
public
function
commit
()
{
// Compute changes in managed entities
$this
->
_
computeDataChangeSet
();
$this
->
computeDataChangeSet
();
if
(
empty
(
$this
->
_newEntities
)
&&
empty
(
$this
->
_deletedEntities
)
&&
...
...
@@ -244,7 +248,7 @@ class Doctrine_ORM_UnitOfWork
*/
public
function
getDataChangeSet
(
$entity
)
{
$oid
=
spl_object_
id
(
$entity
);
$oid
=
spl_object_
hash
(
$entity
);
if
(
isset
(
$this
->
_dataChangeSets
[
$oid
]))
{
return
$this
->
_dataChangeSets
[
$oid
];
}
...
...
@@ -261,7 +265,7 @@ class Doctrine_ORM_UnitOfWork
* map are computed.
* @return void
*/
p
rivate
function
_
computeDataChangeSet
(
array
$entities
=
null
)
p
ublic
function
computeDataChangeSet
(
array
$entities
=
null
)
{
$entitySet
=
array
();
if
(
!
is_null
(
$entities
))
{
...
...
@@ -279,7 +283,7 @@ class Doctrine_ORM_UnitOfWork
foreach
(
$entitySet
as
$className
=>
$entities
)
{
$class
=
$this
->
_em
->
getClassMetadata
(
$className
);
foreach
(
$entities
as
$entity
)
{
$oid
=
spl_object_
id
(
$entity
);
$oid
=
spl_object_
hash
(
$entity
);
if
(
$this
->
getEntityState
(
$entity
)
==
self
::
STATE_MANAGED
)
{
if
(
!
$class
->
isInheritanceTypeNone
())
{
$class
=
$this
->
_em
->
getClassMetadata
(
get_class
(
$entity
));
...
...
@@ -317,7 +321,7 @@ class Doctrine_ORM_UnitOfWork
/**
* Executes all entity insertions for entities of the specified type.
*
* @param Doctrine
::ORM::Mapping::
ClassMetadata $class
* @param Doctrine
\ORM\Mapping\
ClassMetadata $class
*/
private
function
_executeInserts
(
$class
)
{
...
...
@@ -329,11 +333,14 @@ class Doctrine_ORM_UnitOfWork
$persister
=
$this
->
_em
->
getEntityPersister
(
$className
);
foreach
(
$this
->
_newEntities
as
$entity
)
{
if
(
get_class
(
$entity
)
==
$className
)
{
$persister
->
insert
(
$entity
);
if
(
$class
->
isIdGeneratorIdentity
())
{
$id
=
$this
->
_em
->
getIdGenerator
(
$class
->
getIdGeneratorType
());
$class
->
setEntityIdentifier
(
$entity
,
$id
);
$this
->
_entityStates
[
spl_object_id
(
$oid
)]
=
self
::
STATE_MANAGED
;
$returnVal
=
$persister
->
insert
(
$entity
);
if
(
!
is_null
(
$returnVal
))
{
$oid
=
spl_object_hash
(
$entity
);
$class
->
getReflectionProperty
(
$class
->
getSingleIdentifierFieldName
())
->
setValue
(
$entity
,
$returnVal
);
$this
->
_entityIdentifiers
[
$oid
]
=
array
(
$returnVal
);
$this
->
_entityStates
[
$oid
]
=
self
::
STATE_MANAGED
;
$this
->
addToIdentityMap
(
$entity
);
}
}
}
...
...
@@ -342,7 +349,7 @@ class Doctrine_ORM_UnitOfWork
/**
* Executes all entity updates for entities of the specified type.
*
* @param Doctrine
::ORM::Mapping::
ClassMetadata $class
* @param Doctrine
\ORM\Mapping\
ClassMetadata $class
*/
private
function
_executeUpdates
(
$class
)
{
...
...
@@ -358,7 +365,7 @@ class Doctrine_ORM_UnitOfWork
/**
* Executes all entity deletions for entities of the specified type.
*
* @param Doctrine
::ORM::Mapping::
ClassMetadata $class
* @param Doctrine
\ORM\Mapping\
ClassMetadata $class
*/
private
function
_executeDeletions
(
$class
)
{
...
...
@@ -441,11 +448,8 @@ class Doctrine_ORM_UnitOfWork
*/
public
function
registerNew
(
$entity
)
{
$oid
=
spl_object_
id
(
$entity
);
$oid
=
spl_object_
hash
(
$entity
);
/*if ( ! $entity->_identifier()) {
throw new Doctrine_Connection_Exception("Entity without identity cant be registered as new.");
}*/
if
(
isset
(
$this
->
_dirtyEntities
[
$oid
]))
{
throw
new
Doctrine_Connection_Exception
(
"Dirty object can't be registered as new."
);
}
...
...
@@ -457,7 +461,7 @@ class Doctrine_ORM_UnitOfWork
}
$this
->
_newEntities
[
$oid
]
=
$entity
;
if
(
$this
->
_em
->
getClassMetadata
(
get_class
(
$entity
))
->
getEntityIdentifier
(
$entity
))
{
if
(
isset
(
$this
->
_entityIdentifiers
[
$oid
]
))
{
$this
->
addToIdentityMap
(
$entity
);
}
}
...
...
@@ -465,36 +469,25 @@ class Doctrine_ORM_UnitOfWork
/**
* Checks whether an entity is registered as new on the unit of work.
*
* @param Doctrine
_ORM_
Entity $entity
* @param Doctrine
\ORM\
Entity $entity
* @return boolean
* @todo Rename to isScheduledForInsert().
*/
public
function
isRegisteredNew
(
$entity
)
{
return
isset
(
$this
->
_newEntities
[
spl_object_id
(
$entity
)]);
}
/**
* Registers a clean entity.
* The entity is simply put into the identity map.
*
* @param object $entity
*/
public
function
registerClean
(
$entity
)
{
$this
->
addToIdentityMap
(
$entity
);
return
isset
(
$this
->
_newEntities
[
spl_object_hash
(
$entity
)]);
}
/**
* Registers a dirty entity.
*
* @param Doctrine
::ORM::
Entity $entity
* @param Doctrine
\ORM\
Entity $entity
* @todo Rename to scheduleForUpdate().
*/
public
function
registerDirty
(
$entity
)
{
$oid
=
spl_object_
id
(
$entity
);
if
(
!
$entity
->
_identifier
(
))
{
$oid
=
spl_object_
hash
(
$entity
);
if
(
!
isset
(
$this
->
_entityIdentifiers
[
$oid
]
))
{
throw
new
Doctrine_Exception
(
"Entity without identity "
.
"can't be registered as dirty."
);
}
...
...
@@ -518,7 +511,7 @@ class Doctrine_ORM_UnitOfWork
*/
public
function
isRegisteredDirty
(
$entity
)
{
return
isset
(
$this
->
_dirtyEntities
[
spl_object_
id
(
$entity
)]);
return
isset
(
$this
->
_dirtyEntities
[
spl_object_
hash
(
$entity
)]);
}
/**
...
...
@@ -528,12 +521,13 @@ class Doctrine_ORM_UnitOfWork
*/
public
function
registerDeleted
(
$entity
)
{
$oid
=
spl_object_
id
(
$entity
);
$oid
=
spl_object_
hash
(
$entity
);
if
(
!
$this
->
isInIdentityMap
(
$entity
))
{
return
;
}
$this
->
removeFromIdentityMap
(
$entity
);
$className
=
get_class
(
$entity
);
if
(
isset
(
$this
->
_newEntities
[
$oid
]))
{
unset
(
$this
->
_newEntities
[
$oid
]);
...
...
@@ -552,13 +546,13 @@ class Doctrine_ORM_UnitOfWork
* Checks whether an entity is registered as removed/deleted with the unit
* of work.
*
* @param Doctrine
::ORM::
Entity $entity
* @param Doctrine
\ORM\
Entity $entity
* @return boolean
* @todo Rename to isScheduledForDelete().
*/
public
function
isRegisteredRemoved
(
$entity
)
{
return
isset
(
$this
->
_deletedEntities
[
spl_object_
id
(
$entity
)]);
return
isset
(
$this
->
_deletedEntities
[
spl_object_
hash
(
$entity
)]);
}
/**
...
...
@@ -570,25 +564,26 @@ class Doctrine_ORM_UnitOfWork
*/
public
function
detach
(
$entity
)
{
if
(
$this
->
isInIdentityMap
(
$entity
))
{
$this
->
removeFromIdentityMap
(
$entity
);
}
$oid
=
spl_object_hash
(
$entity
);
$this
->
removeFromIdentityMap
(
$entity
);
unset
(
$this
->
_newEntities
[
$oid
],
$this
->
_dirtyEntities
[
$oid
],
$this
->
_deletedEntities
[
$oid
],
$this
->
_entityIdentifiers
[
$oid
],
$this
->
_entityStates
[
$oid
]);
}
/**
* Enter description here...
*
* @param Doctrine
_ORM_
Entity $entity
* @param Doctrine
\ORM\
Entity $entity
* @return unknown
* @todo Rename to isScheduled()
*/
public
function
isEntityRegistered
(
$entity
)
{
$oid
=
spl_object_
id
(
$entity
);
$oid
=
spl_object_
hash
(
$entity
);
return
isset
(
$this
->
_newEntities
[
$oid
])
||
isset
(
$this
->
_dirtyEntities
[
$oid
])
||
isset
(
$this
->
_deletedEntities
[
$oid
])
||
$this
->
isInIdentityMap
(
$entity
);
isset
(
$this
->
_deletedEntities
[
$oid
]);
}
/**
...
...
@@ -606,10 +601,16 @@ class Doctrine_ORM_UnitOfWork
$numDetached
=
0
;
if
(
$entityName
!==
null
&&
isset
(
$this
->
_identityMap
[
$entityName
]))
{
$numDetached
=
count
(
$this
->
_identityMap
[
$entityName
]);
foreach
(
$this
->
_identityMap
[
$entityName
]
as
$entity
)
{
$this
->
detach
(
$entity
);
}
$this
->
_identityMap
[
$entityName
]
=
array
();
}
else
{
$numDetached
=
count
(
$this
->
_identityMap
);
$this
->
_identityMap
=
array
();
$this
->
_newEntities
=
array
();
$this
->
_dirtyEntities
=
array
();
$this
->
_deletedEntities
=
array
();
}
return
$numDetached
;
...
...
@@ -627,9 +628,9 @@ class Doctrine_ORM_UnitOfWork
public
function
addToIdentityMap
(
$entity
)
{
$classMetadata
=
$this
->
_em
->
getClassMetadata
(
get_class
(
$entity
));
$idHash
=
$this
->
getIdentifierHash
(
$
classMetadata
->
getEntityIdentifier
(
$entity
)
);
$idHash
=
$this
->
getIdentifierHash
(
$
this
->
_entityIdentifiers
[
spl_object_hash
(
$entity
)]
);
if
(
$idHash
===
''
)
{
throw
new
Doctrine_Exception
(
"Entity with oid '"
.
spl_object_
id
(
$entity
)
throw
new
Doctrine_Exception
(
"Entity with oid '"
.
spl_object_
hash
(
$entity
)
.
"' has no identity and therefore can't be added to the identity map."
);
}
$className
=
$classMetadata
->
getRootClassName
();
...
...
@@ -648,23 +649,22 @@ class Doctrine_ORM_UnitOfWork
*/
public
function
getEntityState
(
$entity
)
{
$oid
=
spl_object_id
(
$entity
);
return
isset
(
$this
->
_entityStates
[
$oid
])
?
$this
->
_entityStates
[
$oid
]
:
self
::
STATE_NEW
;
$oid
=
spl_object_hash
(
$entity
);
return
isset
(
$this
->
_entityStates
[
$oid
])
?
$this
->
_entityStates
[
$oid
]
:
self
::
STATE_NEW
;
}
/**
* Removes an entity from the identity map.
*
* @param Doctrine
_ORM_
Entity $entity
* @return
unknow
n
* @param Doctrine
\ORM\
Entity $entity
* @return
boolea
n
*/
public
function
removeFromIdentityMap
(
$entity
)
{
$classMetadata
=
$this
->
_em
->
getClassMetadata
(
get_class
(
$entity
));
$idHash
=
$this
->
getIdentifierHash
(
$
classMetadata
->
getEntityIdentifier
(
$entity
)
);
$idHash
=
$this
->
getIdentifierHash
(
$
this
->
_entityIdentifiers
[
spl_object_hash
(
$entity
)]
);
if
(
$idHash
===
''
)
{
throw
new
Doctrine_Exception
(
"Entity with oid '"
.
spl_object_
id
(
$entity
)
throw
new
Doctrine_Exception
(
"Entity with oid '"
.
spl_object_
hash
(
$entity
)
.
"' has no identity and therefore can't be removed from the identity map."
);
}
$className
=
$classMetadata
->
getRootClassName
();
...
...
@@ -681,7 +681,7 @@ class Doctrine_ORM_UnitOfWork
*
* @param string $idHash
* @param string $rootClassName
* @return Doctrine
::ORM::
Entity
* @return Doctrine
\ORM\
Entity
*/
public
function
getByIdHash
(
$idHash
,
$rootClassName
)
{
...
...
@@ -729,8 +729,12 @@ class Doctrine_ORM_UnitOfWork
*/
public
function
isInIdentityMap
(
$entity
)
{
$oid
=
spl_object_hash
(
$entity
);
if
(
!
isset
(
$this
->
_entityIdentifiers
[
$oid
]))
{
return
false
;
}
$classMetadata
=
$this
->
_em
->
getClassMetadata
(
get_class
(
$entity
));
$idHash
=
$this
->
getIdentifierHash
(
$
classMetadata
->
getEntityIdentifier
(
$entity
));
$idHash
=
$this
->
getIdentifierHash
(
$
this
->
_entityIdentifiers
[
$oid
]);
if
(
$idHash
===
''
)
{
return
false
;
}
...
...
@@ -765,15 +769,15 @@ class Doctrine_ORM_UnitOfWork
$this
->
_doSave
(
$entity
,
$visited
,
$insertNow
);
if
(
!
empty
(
$insertNow
))
{
// We have no choice. This means that there are new entities
// with an IDENTITY column key generation.
$this
->
_
computeDataChangeSet
(
$insertNow
);
// with an IDENTITY column key generation
strategy
.
$this
->
computeDataChangeSet
(
$insertNow
);
$commitOrder
=
$this
->
_getCommitOrder
(
$insertNow
);
foreach
(
$commitOrder
as
$class
)
{
$this
->
_executeInserts
(
$class
);
}
// remove them from _newEntities
$this
->
_newEntities
=
array_diff_key
(
$this
->
_newEntities
,
$insertNow
);
$this
->
_dataChangeSets
=
array
(
);
$this
->
_dataChangeSets
=
array
_diff_key
(
$this
->
_dataChangeSets
,
$insertNow
);
}
}
...
...
@@ -787,7 +791,7 @@ class Doctrine_ORM_UnitOfWork
*/
private
function
_doSave
(
$entity
,
array
&
$visited
,
array
&
$insertNow
)
{
$oid
=
spl_object_
id
(
$entity
);
$oid
=
spl_object_
hash
(
$entity
);
if
(
isset
(
$visited
[
$oid
]))
{
return
;
// Prevent infinite recursion
}
...
...
@@ -800,12 +804,16 @@ class Doctrine_ORM_UnitOfWork
// nothing to do
break
;
case
self
::
STATE_NEW
:
$
result
=
$this
->
_em
->
getIdGenerator
(
$class
->
getClassName
())
->
generate
(
$entity
);
if
(
$
result
==
Doctrine_ORM_Id_AbstractIdGenerator
::
POST_INSERT_INDICATOR
)
{
$
idGen
=
$this
->
_em
->
getIdGenerator
(
$class
->
getClassName
()
);
if
(
$
idGen
->
isPostInsertGenerator
()
)
{
$insertNow
[
$oid
]
=
$entity
;
}
else
{
$class
->
setEntityIdentifier
(
$entity
,
$result
);
$idValue
=
$idGen
->
generate
(
$entity
);
$this
->
_entityIdentifiers
[
$oid
]
=
array
(
$idValue
);
$this
->
_entityStates
[
$oid
]
=
self
::
STATE_MANAGED
;
if
(
!
$idGen
instanceof
Doctrine_ORM_Id_Assigned
)
{
$class
->
getSingleIdReflectionProperty
()
->
setValue
(
$entity
,
$idValue
);
}
}
$this
->
registerNew
(
$entity
);
break
;
...
...
@@ -844,19 +852,18 @@ class Doctrine_ORM_UnitOfWork
/**
* Enter description here...
*
* @param Doctrine
_ORM_
Entity $entity
* @param Doctrine
\ORM\
Entity $entity
* @param array $visited
*/
private
function
_doDelete
(
$entity
,
array
&
$visited
)
{
$oid
=
spl_object_
id
(
$entity
);
$oid
=
spl_object_
hash
(
$entity
);
if
(
isset
(
$visited
[
$oid
]))
{
return
;
// Prevent infinite recursion
}
$visited
[
$oid
]
=
$entity
;
// mark visited
//$class = $entity->getClass();
switch
(
$this
->
getEntityState
(
$entity
))
{
case
self
::
STATE_NEW
:
case
self
::
STATE_DELETED
:
...
...
@@ -951,47 +958,43 @@ class Doctrine_ORM_UnitOfWork
}
/**
* Creates an entity. Used for reconstitution
as well as initial cre
ation.
* Creates an entity. Used for reconstitution
of entities during hydr
ation.
*
* @param string $className The name of the entity class.
* @param array $data The data for the entity.
* @return Doctrine\ORM\Entity
* @internal Performance-sensitive method.
*/
public
function
createEntity
(
$className
,
array
$data
,
Doctrine_Query
$query
=
null
)
public
function
createEntity
(
$className
,
array
$data
,
$query
=
null
)
{
$className
=
$this
->
_inferCorrectClassName
(
$data
,
$className
);
$classMetadata
=
$this
->
_em
->
getClassMetadata
(
$className
);
if
(
!
empty
(
$data
))
{
$id
=
array
();
if
(
$classMetadata
->
isIdentifierComposite
())
{
$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
->
getIdentifierHash
(
$id
);
$entity
=
$this
->
tryGetByIdHash
(
$idHash
,
$classMetadata
->
getRootClassName
());
if
(
$entity
)
{
$this
->
_mergeData
(
$entity
,
$data
,
$classMetadata
/*, $query->getHint('doctrine.refresh')*/
);
return
$entity
;
}
else
{
$entity
=
new
$className
;
$this
->
_mergeData
(
$entity
,
$data
,
$classMetadata
,
true
);
$this
->
addToIdentityMap
(
$entity
);
}
}
$idHash
=
$this
->
getIdentifierHash
(
$id
);
}
else
{
$id
=
array
(
$data
[
$classMetadata
->
getSingleIdentifierFieldName
()]);
$idHash
=
$id
[
0
];
}
$entity
=
$this
->
tryGetByIdHash
(
$idHash
,
$classMetadata
->
getRootClassName
());
if
(
$entity
)
{
$oid
=
spl_object_hash
(
$entity
);
$this
->
_mergeData
(
$entity
,
$data
,
$classMetadata
/*, $query->getHint('doctrine.refresh')*/
);
return
$entity
;
}
else
{
$entity
=
new
$className
;
$oid
=
spl_object_hash
(
$entity
);
$this
->
_mergeData
(
$entity
,
$data
,
$classMetadata
,
true
);
$this
->
_entityIdentifiers
[
$oid
]
=
$id
;
$this
->
addToIdentityMap
(
$entity
);
}
$this
->
_originalEntityData
[
spl_object_id
(
$entity
)
]
=
$data
;
$this
->
_originalEntityData
[
$oid
]
=
$data
;
return
$entity
;
}
...
...
@@ -1011,11 +1014,11 @@ class Doctrine_ORM_UnitOfWork
$class
->
getReflectionProperty
(
$field
)
->
setValue
(
$entity
,
$value
);
}
}
else
{
$oid
=
spl_object_
id
(
$entity
);
$oid
=
spl_object_
hash
(
$entity
);
foreach
(
$data
as
$field
=>
$value
)
{
$currentValue
=
$class
->
getReflectionProperty
(
$field
)
->
getValue
(
$entity
);
if
(
!
isset
(
$this
->
_originalEntityData
[
$oid
])
||
$currentValue
==
$this
->
_originalEntityData
[
$oid
])
{
if
(
!
isset
(
$this
->
_originalEntityData
[
$oid
]
[
$field
]
)
||
$currentValue
==
$this
->
_originalEntityData
[
$oid
]
[
$field
]
)
{
$class
->
getReflectionProperty
(
$field
)
->
setValue
(
$entity
,
$value
);
}
}
...
...
@@ -1058,6 +1061,61 @@ class Doctrine_ORM_UnitOfWork
{
return
$this
->
_identityMap
;
}
/**
* Gets the original data of an entity. The original data is the data that was
* present at the time the entity was reconstituted from the database.
*
* @param object $entity
* @return array
*/
public
function
getOriginalEntityData
(
$entity
)
{
$oid
=
spl_object_hash
(
$entity
);
if
(
isset
(
$this
->
_originalEntityData
[
$oid
]))
{
return
$this
->
_originalEntityData
[
$oid
];
}
return
array
();
}
/**
* INTERNAL:
* For hydration purposes only.
*
* Sets a property of the original data array of an entity.
*
* @param string $oid
* @param string $property
* @param mixed $value
*/
public
function
setOriginalEntityProperty
(
$oid
,
$property
,
$value
)
{
$this
->
_originalEntityData
[
$oid
][
$property
]
=
$value
;
}
/**
* INTERNAL:
* For hydration purposes only.
*
* Adds a managed collection to the UnitOfWork.
*
* @param Doctrine\ORM\Collection $coll
*/
public
function
addManagedCollection
(
Doctrine_ORM_Collection
$coll
)
{
}
/**
* Gets the identifier of an entity.
*
* @param object $entity
* @return array The identifier values.
*/
public
function
getEntityIdentifier
(
$entity
)
{
return
$this
->
_entityIdentifiers
[
spl_object_hash
(
$entity
)];
}
}
...
...
tests/Orm/Hydration/BasicHydrationTest.php
View file @
2395888f
...
...
@@ -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
)
{
//...
}
...
...
tests/Orm/UnitOfWorkTest.php
View file @
2395888f
...
...
@@ -2,7 +2,8 @@
require_once
'lib/DoctrineTestInit.php'
;
require_once
'lib/mocks/Doctrine_EntityManagerMock.php'
;
require_once
'lib/mocks/Doctrine_ConnectionMock.php'
;
require_once
'lib/mocks/Doctrine_ClassMetadataMock.php'
;
require_once
'lib/mocks/Doctrine_UnitOfWorkMock.php'
;
require_once
'lib/mocks/Doctrine_IdentityIdGeneratorMock.php'
;
/**
* UnitOfWork tests.
...
...
@@ -12,16 +13,11 @@ require_once 'lib/mocks/Doctrine_ClassMetadataMock.php';
class
Orm_UnitOfWorkTest
extends
Doctrine_OrmTestCase
{
private
$_unitOfWork
;
private
$_user
;
// Mocks
// Provides a sequence mock to the UnitOfWork
private
$_connectionMock
;
// The sequence mock
private
$_idGeneratorMock
;
// The persister mock used by the UnitOfWork
private
$_persisterMock
;
// The EntityManager mock that provides the mock persister
private
$_emMock
;
...
...
@@ -30,106 +26,141 @@ class Orm_UnitOfWorkTest extends Doctrine_OrmTestCase
$this
->
_connectionMock
=
new
Doctrine_ConnectionMock
(
array
());
$this
->
_emMock
=
Doctrine_EntityManagerMock
::
create
(
$this
->
_connectionMock
,
"uowMockEm"
);
$this
->
_idGeneratorMock
=
new
Doctrine_SequenceMock
(
$this
->
_emMock
);
$this
->
_emMock
->
setIdGenerator
(
'ForumUser'
,
$this
->
_idGeneratorMock
);
$this
->
_emMock
->
setIdGenerator
(
'ForumAvatar'
,
$this
->
_idGeneratorMock
);
$this
->
_persisterMock
=
new
Doctrine_EntityPersisterMock
(
$this
->
_emMock
,
$this
->
_emMock
->
getClassMetadata
(
"ForumUser"
));
$this
->
_emMock
->
setEntityPersister
(
$this
->
_persisterMock
);
$this
->
_emMock
->
activate
();
// SUT
$this
->
_unitOfWork
=
$this
->
_emMock
->
getUnitOfWork
();
$this
->
_user
=
new
ForumUser
();
$this
->
_user
->
id
=
1
;
$this
->
_user
->
username
=
'romanb'
;
$this
->
_unitOfWork
=
new
Doctrine_UnitOfWorkMock
(
$this
->
_emMock
);
$this
->
_emMock
->
setUnitOfWork
(
$this
->
_unitOfWork
);
}
protected
function
tearDown
()
{
//$this->_user->free();
}
/* Basic registration tests */
public
function
testRegisterNew
()
{
// registerNew() is normally called in save()/persist()
$this
->
_unitOfWork
->
registerNew
(
$this
->
_user
);
$this
->
assertTrue
(
$this
->
_unitOfWork
->
isRegisteredNew
(
$this
->
_user
));
$this
->
assertTrue
(
$this
->
_unitOfWork
->
isInIdentityMap
(
$this
->
_user
));
$this
->
assertFalse
(
$this
->
_unitOfWork
->
isRegisteredDirty
(
$this
->
_user
));
$this
->
assertFalse
(
$this
->
_unitOfWork
->
isRegisteredRemoved
(
$this
->
_user
));
}
/*public function testRegisterNewPerf() {
$s = microtime(true);
for ($i=1; $i<40000; $i++) {
$user = new ForumUser();
$user->id = $i;
$this->_unitOfWork->registerNew($user);
}
$e = microtime(true);
echo $e - $s . " seconds" . PHP_EOL;
}*/
public
function
testRegisterRemovedOnNewEntityIsIgnored
()
{
$this
->
assertFalse
(
$this
->
_unitOfWork
->
isRegisteredRemoved
(
$this
->
_user
));
$this
->
_unitOfWork
->
registerDeleted
(
$this
->
_user
);
$this
->
assertFalse
(
$this
->
_unitOfWork
->
isRegisteredRemoved
(
$this
->
_user
));
$user
=
new
ForumUser
();
$user
->
username
=
'romanb'
;
$this
->
assertFalse
(
$this
->
_unitOfWork
->
isRegisteredRemoved
(
$user
));
$this
->
_unitOfWork
->
registerDeleted
(
$user
);
$this
->
assertFalse
(
$this
->
_unitOfWork
->
isRegisteredRemoved
(
$user
));
}
/* Operational tests */
public
function
testSavingSingleEntityWithIdentityColumnForcesInsert
()
{
$this
->
_unitOfWork
->
save
(
$this
->
_user
);
$this
->
assertEquals
(
1
,
count
(
$this
->
_persisterMock
->
getInserts
()));
// insert forced
$this
->
assertEquals
(
0
,
count
(
$this
->
_persisterMock
->
getUpdates
()));
$this
->
assertEquals
(
0
,
count
(
$this
->
_persisterMock
->
getDeletes
()));
$this
->
assertTrue
(
$this
->
_unitOfWork
->
isInIdentityMap
(
$this
->
_user
));
{
// Setup fake persister and id generator for identity generation
$userPersister
=
new
Doctrine_EntityPersisterMock
(
$this
->
_emMock
,
$this
->
_emMock
->
getClassMetadata
(
"ForumUser"
));
$this
->
_emMock
->
setEntityPersister
(
'ForumUser'
,
$userPersister
);
$idGeneratorMock
=
new
Doctrine_IdentityIdGeneratorMock
(
$this
->
_emMock
);
$this
->
_emMock
->
setIdGenerator
(
'ForumUser'
,
$idGeneratorMock
);
$userPersister
->
setMockIdGeneratorType
(
Doctrine_ORM_Mapping_ClassMetadata
::
GENERATOR_TYPE_IDENTITY
);
// Test
$user
=
new
ForumUser
();
$user
->
username
=
'romanb'
;
$this
->
_unitOfWork
->
save
(
$user
);
// Check
$this
->
assertEquals
(
1
,
count
(
$userPersister
->
getInserts
()));
// insert forced
$this
->
assertEquals
(
0
,
count
(
$userPersister
->
getUpdates
()));
$this
->
assertEquals
(
0
,
count
(
$userPersister
->
getDeletes
()));
$this
->
assertTrue
(
$this
->
_unitOfWork
->
isInIdentityMap
(
$user
));
// should no longer be scheduled for insert
$this
->
assertFalse
(
$this
->
_unitOfWork
->
isRegisteredNew
(
$
this
->
_
user
));
$this
->
assertFalse
(
$this
->
_unitOfWork
->
isRegisteredNew
(
$user
));
// should have an id
$this
->
assertTrue
(
is_numeric
(
$
this
->
_
user
->
id
));
$this
->
assertTrue
(
is_numeric
(
$user
->
id
));
// Now lets check whether a subsequent commit() does anything
$this
->
_persisterMock
->
reset
();
$userPersister
->
reset
();
// Test
$this
->
_unitOfWork
->
commit
();
// shouldnt do anything
//
verify that nothing happened
$this
->
assertEquals
(
0
,
count
(
$
this
->
_persisterMock
->
getInserts
()));
$this
->
assertEquals
(
0
,
count
(
$
this
->
_persisterMock
->
getUpdates
()));
$this
->
assertEquals
(
0
,
count
(
$
this
->
_persisterMock
->
getDeletes
()));
//
Check. Verify that nothing happened.
$this
->
assertEquals
(
0
,
count
(
$
userPersister
->
getInserts
()));
$this
->
assertEquals
(
0
,
count
(
$
userPersister
->
getUpdates
()));
$this
->
assertEquals
(
0
,
count
(
$
userPersister
->
getDeletes
()));
}
public
function
testCommitOrder
()
/**
* Tests a scenario where a save() operation is cascaded from a ForumUser
* to its associated ForumAvatar, both entities using IDENTITY id generation.
*/
public
function
testCascadedIdentityColumnInsert
()
{
// Setup fake persister and id generator for identity generation
//ForumUser
$userPersister
=
new
Doctrine_EntityPersisterMock
(
$this
->
_emMock
,
$this
->
_emMock
->
getClassMetadata
(
"ForumUser"
));
$this
->
_emMock
->
setEntityPersister
(
'ForumUser'
,
$userPersister
);
$userIdGeneratorMock
=
new
Doctrine_IdentityIdGeneratorMock
(
$this
->
_emMock
);
$this
->
_emMock
->
setIdGenerator
(
'ForumUser'
,
$userIdGeneratorMock
);
$userPersister
->
setMockIdGeneratorType
(
Doctrine_ORM_Mapping_ClassMetadata
::
GENERATOR_TYPE_IDENTITY
);
// ForumAvatar
$avatarPersister
=
new
Doctrine_EntityPersisterMock
(
$this
->
_emMock
,
$this
->
_emMock
->
getClassMetadata
(
"ForumAvatar"
));
$this
->
_emMock
->
setEntityPersister
(
'ForumAvatar'
,
$avatarPersister
);
$avatarIdGeneratorMock
=
new
Doctrine_IdentityIdGeneratorMock
(
$this
->
_emMock
);
$this
->
_emMock
->
setIdGenerator
(
'ForumAvatar'
,
$avatarIdGeneratorMock
);
$avatarPersister
->
setMockIdGeneratorType
(
Doctrine_ORM_Mapping_ClassMetadata
::
GENERATOR_TYPE_IDENTITY
);
// Test
$user
=
new
ForumUser
();
$user
->
username
=
'romanb'
;
$avatar
=
new
ForumAvatar
();
$this
->
_user
->
avatar
=
$avatar
;
$this
->
_unitOfWork
->
save
(
$this
->
_user
);
// save cascaded to avatar
$this
->
assertEquals
(
2
,
count
(
$this
->
_persisterMock
->
getInserts
()));
// insert forced
$this
->
assertEquals
(
0
,
count
(
$this
->
_persisterMock
->
getUpdates
()));
$this
->
assertEquals
(
0
,
count
(
$this
->
_persisterMock
->
getDeletes
()));
// verify order of inserts()s
$inserts
=
$this
->
_persisterMock
->
getInserts
();
$this
->
assertSame
(
$avatar
,
$inserts
[
0
]);
$this
->
assertSame
(
$this
->
_user
,
$inserts
[
1
]);
//...
$user
->
avatar
=
$avatar
;
$this
->
_unitOfWork
->
save
(
$user
);
// save cascaded to avatar
$this
->
assertTrue
(
is_numeric
(
$user
->
id
));
$this
->
assertTrue
(
is_numeric
(
$avatar
->
id
));
$this
->
assertEquals
(
1
,
count
(
$userPersister
->
getInserts
()));
// insert forced
$this
->
assertEquals
(
0
,
count
(
$userPersister
->
getUpdates
()));
$this
->
assertEquals
(
0
,
count
(
$userPersister
->
getDeletes
()));
$this
->
assertEquals
(
1
,
count
(
$avatarPersister
->
getInserts
()));
// insert forced
$this
->
assertEquals
(
0
,
count
(
$avatarPersister
->
getUpdates
()));
$this
->
assertEquals
(
0
,
count
(
$avatarPersister
->
getDeletes
()));
}
public
function
testComputeDataChangeSet
()
{
$user1
=
new
ForumUser
();
$user1
->
id
=
1
;
$user1
->
username
=
"romanb"
;
$user1
->
avatar
=
new
ForumAvatar
();
// Fake managed state
$this
->
_unitOfWork
->
setEntityState
(
$user1
,
Doctrine_ORM_UnitOfWork
::
STATE_MANAGED
);
$user2
=
new
ForumUser
();
$user2
->
id
=
2
;
$user2
->
username
=
"jwage"
;
$this
->
_unitOfWork
->
setEntityState
(
$user2
,
Doctrine_ORM_UnitOfWork
::
STATE_MANAGED
);
$this
->
_unitOfWork
->
setOriginalEntityData
(
$user1
,
array
(
'id'
=>
1
,
'username'
=>
'roman'
));
$this
->
_unitOfWork
->
setOriginalEntityData
(
$user2
,
array
(
'id'
=>
2
,
'username'
=>
'jon'
));
$this
->
_unitOfWork
->
computeDataChangeSet
(
array
(
$user1
,
$user2
));
$user1ChangeSet
=
$this
->
_unitOfWork
->
getDataChangeSet
(
$user1
);
$this
->
assertTrue
(
is_array
(
$user1ChangeSet
));
$this
->
assertEquals
(
2
,
count
(
$user1ChangeSet
));
$this
->
assertTrue
(
isset
(
$user1ChangeSet
[
'username'
]));
$this
->
assertEquals
(
array
(
'roman'
=>
'romanb'
),
$user1ChangeSet
[
'username'
]);
$this
->
assertTrue
(
isset
(
$user1ChangeSet
[
'avatar'
]));
$this
->
assertSame
(
array
(
null
=>
$user1
->
avatar
),
$user1ChangeSet
[
'avatar'
]);
$user2ChangeSet
=
$this
->
_unitOfWork
->
getDataChangeSet
(
$user2
);
$this
->
assertTrue
(
is_array
(
$user2ChangeSet
));
$this
->
assertEquals
(
1
,
count
(
$user2ChangeSet
));
$this
->
assertTrue
(
isset
(
$user2ChangeSet
[
'username'
]));
$this
->
assertEquals
(
array
(
'jon'
=>
'jwage'
),
$user2ChangeSet
[
'username'
]);
}
/*
public function testSavingSingleEntityWithSequenceIdGeneratorSchedulesInsert()
{
...
...
tests/lib/mocks/Doctrine_EntityManagerMock.php
View file @
2395888f
...
...
@@ -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
)
...
...
tests/lib/mocks/Doctrine_EntityPersisterMock.php
View file @
2395888f
<?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
tests/lib/mocks/Doctrine_IdentityIdGeneratorMock.php
0 → 100644
View file @
2395888f
<?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
;
}
}
?>
tests/lib/mocks/Doctrine_SequenceMock.php
View file @
2395888f
...
...
@@ -15,8 +15,6 @@ class Doctrine_SequenceMock extends Doctrine_ORM_Id_SequenceGenerator
return
$this
->
_sequenceNumber
++
;
}
/**
* @override
*/
...
...
tests/lib/mocks/Doctrine_UnitOfWorkMock.php
View file @
2395888f
...
...
@@ -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
;
}
}
tests/models/forum/ForumUser.php
View file @
2395888f
...
...
@@ -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'
,
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment