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
ae1b9371
Commit
ae1b9371
authored
Jul 21, 2009
by
romanb
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[2.0] Fixed #2366.
parent
be0088f0
Changes
11
Show whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
203 additions
and
53 deletions
+203
-53
EntityManager.php
lib/Doctrine/ORM/EntityManager.php
+2
-3
ObjectHydrator.php
lib/Doctrine/ORM/Internal/Hydration/ObjectHydrator.php
+1
-1
AssociationMapping.php
lib/Doctrine/ORM/Mapping/AssociationMapping.php
+12
-12
PersistentCollection.php
lib/Doctrine/ORM/PersistentCollection.php
+17
-8
ElementCollectionPersister.php
lib/Doctrine/ORM/Persisters/ElementCollectionPersister.php
+1
-0
ManyToManyPersister.php
lib/Doctrine/ORM/Persisters/ManyToManyPersister.php
+1
-1
OneToManyPersister.php
lib/Doctrine/ORM/Persisters/OneToManyPersister.php
+50
-6
StandardEntityPersister.php
lib/Doctrine/ORM/Persisters/StandardEntityPersister.php
+4
-18
UnitOfWork.php
lib/Doctrine/ORM/UnitOfWork.php
+66
-1
BasicFunctionalTest.php
tests/Doctrine/Tests/ORM/Functional/BasicFunctionalTest.php
+48
-2
OneToOneBidirectionalAssociationTest.php
...s/ORM/Functional/OneToOneBidirectionalAssociationTest.php
+1
-1
No files found.
lib/Doctrine/ORM/EntityManager.php
View file @
ae1b9371
...
...
@@ -413,13 +413,12 @@ class EntityManager
* Refreshes the persistent state of an entity from the database,
* overriding any local changes that have not yet been persisted.
*
* @param object $entity
* @todo Implementation
* @param object $entity The entity to refresh.
*/
public
function
refresh
(
$entity
)
{
$this
->
_errorIfClosed
();
throw
DoctrineException
::
notImplemented
(
);
$this
->
_unitOfWork
->
refresh
(
$entity
);
}
/**
...
...
lib/Doctrine/ORM/Internal/Hydration/ObjectHydrator.php
View file @
ae1b9371
...
...
@@ -260,7 +260,7 @@ class ObjectHydrator extends AbstractHydrator
}
else
{
// Eager load
//TODO: Allow more efficient and configurable batching of these loads
$assoc
->
load
(
$entity
,
new
$
class
Name
,
$this
->
_em
,
$joinColumns
);
$assoc
->
load
(
$entity
,
new
$
assoc
->
targetEntity
Name
,
$this
->
_em
,
$joinColumns
);
}
}
else
{
//TODO: Eager load
...
...
lib/Doctrine/ORM/Mapping/AssociationMapping.php
View file @
ae1b9371
...
...
@@ -37,8 +37,18 @@ namespace Doctrine\ORM\Mapping;
*/
abstract
class
AssociationMapping
{
const
FETCH_MANUAL
=
1
;
/**
* Specifies that an association is to be fetched when it is first accessed.
*
* @var integer
*/
const
FETCH_LAZY
=
2
;
/**
* Specifies that an association is to be fetched when the owner of the
* association is fetched.
*
* @var integer
*/
const
FETCH_EAGER
=
3
;
/**
...
...
@@ -66,7 +76,7 @@ abstract class AssociationMapping
*
* @var integer
*/
public
$fetchMode
=
self
::
FETCH_
MANUAL
;
public
$fetchMode
=
self
::
FETCH_
LAZY
;
/**
* Flag that indicates whether the class that defines this mapping is
...
...
@@ -244,16 +254,6 @@ abstract class AssociationMapping
return
$this
->
fetchMode
==
self
::
FETCH_LAZY
;
}
/**
* Whether the target entity/entities of the association are manually fetched.
*
* @return boolean
*/
public
function
isManuallyFetched
()
{
return
$this
->
fetchMode
==
self
::
FETCH_MANUAL
;
}
/**
* Whether the source entity of this association represents the owning side.
*
...
...
lib/Doctrine/ORM/PersistentCollection.php
View file @
ae1b9371
...
...
@@ -198,7 +198,7 @@ final class PersistentCollection extends \Doctrine\Common\Collections\Collection
public
function
remove
(
$key
)
{
//TODO: delete entity if shouldDeleteOrphans
/*if ($this->_association->isOneToMany() && $this->_association->shouldDeleteOrphans
()
) {
/*if ($this->_association->isOneToMany() && $this->_association->shouldDeleteOrphans) {
$this->_em->remove($removed);
}*/
$removed
=
parent
::
remove
(
$key
);
...
...
@@ -209,8 +209,8 @@ final class PersistentCollection extends \Doctrine\Common\Collections\Collection
}
/**
* When the collection is a Map this is like put(key,value)/add(key,value).
* When the collection is a List this is like add(position,value).
* When the collection is
used as
a Map this is like put(key,value)/add(key,value).
* When the collection is
used as
a List this is like add(position,value).
*
* @param integer $key
* @param mixed $value
...
...
@@ -302,6 +302,9 @@ final class PersistentCollection extends \Doctrine\Common\Collections\Collection
}
/**
* Initializes the collection by loading its contents from the database.
*/
private
function
_initialize
()
{
...
...
@@ -375,15 +378,21 @@ final class PersistentCollection extends \Doctrine\Common\Collections\Collection
{
//TODO: Register collection as dirty with the UoW if necessary
//TODO: If oneToMany() && shouldDeleteOrphan() delete entities
/*if ($this->_association->isOneToMany() && $this->_association->shouldDeleteOrphans
()
) {
/*if ($this->_association->isOneToMany() && $this->_association->shouldDeleteOrphans) {
foreach ($this->_data as $entity) {
$this->_em->remove($entity);
}
}*/
parent
::
clear
();
if
(
$this
->
_association
->
isOwningSide
)
{
$this
->
_changed
();
$this
->
_em
->
getUnitOfWork
()
->
scheduleCollectionDeletion
(
$this
);
}
}
/**
* Marks this collection as changed/dirty.
*/
private
function
_changed
()
{
$this
->
_isDirty
=
true
;
...
...
lib/Doctrine/ORM/Persisters/ElementCollectionPersister.php
View file @
ae1b9371
...
...
@@ -25,6 +25,7 @@ namespace Doctrine\ORM\Persisters;
* Persister for collections of basic elements / value types.
*
* @author robo
* @todo Implementation once support for collections of basic elements (i.e. strings) is added.
*/
class
ElementCollectionPersister
extends
AbstractCollectionPersister
{
...
...
lib/Doctrine/ORM/Persisters/ManyToManyPersister.php
View file @
ae1b9371
...
...
@@ -108,7 +108,7 @@ class ManyToManyPersister extends AbstractCollectionPersister
$mapping
=
$coll
->
getMapping
();
$joinTable
=
$mapping
->
getJoinTable
();
$whereClause
=
''
;
foreach
(
$mapping
->
getSourceToRelationKeyColumns
()
as
$relationColumn
)
{
foreach
(
$mapping
->
sourceToRelationKeyColumns
as
$relationColumn
)
{
if
(
$whereClause
!==
''
)
$whereClause
.=
' AND '
;
$whereClause
.=
"
$relationColumn
= ?"
;
}
...
...
lib/Doctrine/ORM/Persisters/OneToManyPersister.php
View file @
ae1b9371
...
...
@@ -26,18 +26,23 @@ use Doctrine\ORM\PersistentCollection;
/**
* Persister for one-to-many collections.
*
* This persister is only used for uni-directional one-to-many mappings.
* IMPORTANT:
* This persister is only used for uni-directional one-to-many mappings on a foreign key
* (which are not yet supported). So currently this persister is not used.
*
* @since 2.0
* @author Roman Borschel <roman@code-factory.org>
* @todo Complete implementation when the support for uni-directional one-to-many mappings
* on a foreign key gets added.
*/
class
OneToManyPersister
extends
AbstractCollectionPersister
{
/**
* {@inheritdoc}
* Generates the SQL UPDATE that updates a particular row's foreign
* key to null.
*
* @param
<type>
$coll
* @return
<type>
* @param
PersistentCollection
$coll
* @return
string
* @override
*/
protected
function
_getDeleteRowSql
(
PersistentCollection
$coll
)
...
...
@@ -63,14 +68,53 @@ class OneToManyPersister extends AbstractCollectionPersister
return
array
(
"UPDATE
$table
SET
$setClause
WHERE
$whereClause
"
,
$this
->
_uow
->
getEntityIdentifier
(
$element
));
}
protected
function
_getInsertRowSql
()
protected
function
_getInsertRowSql
(
PersistentCollection
$coll
)
{
return
"UPDATE xxx SET foreign_key = yyy WHERE foreign_key = zzz"
;
}
/* Not used for OneToManyPersister */
protected
function
_getUpdateRowSql
()
protected
function
_getUpdateRowSql
(
PersistentCollection
$coll
)
{
return
;
}
/**
* Generates the SQL UPDATE that updates all the foreign keys to null.
*
* @param PersistentCollection $coll
*/
protected
function
_getDeleteSql
(
PersistentCollection
$coll
)
{
}
/**
* Gets the SQL parameters for the corresponding SQL statement to delete
* the given collection.
*
* @param PersistentCollection $coll
*/
protected
function
_getDeleteSqlParameters
(
PersistentCollection
$coll
)
{}
/**
* Gets the SQL parameters for the corresponding SQL statement to insert the given
* element of the given collection into the database.
*
* @param PersistentCollection $coll
* @param mixed $element
*/
protected
function
_getInsertRowSqlParameters
(
PersistentCollection
$coll
,
$element
)
{}
/**
* Gets the SQL parameters for the corresponding SQL statement to delete the given
* element from the given collection.
*
* @param PersistentCollection $coll
* @param mixed $element
*/
protected
function
_getDeleteRowSqlParameters
(
PersistentCollection
$coll
,
$element
)
{}
}
\ No newline at end of file
lib/Doctrine/ORM/Persisters/StandardEntityPersister.php
View file @
ae1b9371
...
...
@@ -70,13 +70,6 @@ class StandardEntityPersister
*/
protected
$_em
;
/**
* The EventManager instance.
*
* @var Doctrine\Common\EventManager
*/
protected
$_evm
;
/**
* Queued inserts.
*
...
...
@@ -96,7 +89,6 @@ class StandardEntityPersister
{
$this
->
_em
=
$em
;
$this
->
_platform
=
$em
->
getConnection
()
->
getDatabasePlatform
();
$this
->
_evm
=
$em
->
getEventManager
();
$this
->
_entityName
=
$class
->
name
;
$this
->
_conn
=
$em
->
getConnection
();
$this
->
_class
=
$class
;
...
...
@@ -206,17 +198,9 @@ class StandardEntityPersister
);
$tableName
=
$this
->
_class
->
primaryTable
[
'name'
];
if
(
$this
->
_evm
->
hasListeners
(
Events
::
preUpdate
))
{
$this
->
_preUpdate
(
$entity
);
}
if
(
isset
(
$updateData
[
$tableName
])
&&
$updateData
[
$tableName
])
{
$this
->
_doUpdate
(
$entity
,
$tableName
,
$updateData
[
$tableName
],
$id
);
}
if
(
$this
->
_evm
->
hasListeners
(
Events
::
postUpdate
))
{
$this
->
_postUpdate
(
$entity
);
}
}
/**
...
...
@@ -458,7 +442,9 @@ class StandardEntityPersister
$proxy
=
$this
->
_em
->
getProxyFactory
()
->
getAssociationProxy
(
$entity
,
$assoc
,
$joinColumnValues
);
$this
->
_class
->
reflFields
[
$field
]
->
setValue
(
$entity
,
$proxy
);
}
else
{
//TODO: Eager fetch
// Eager load
//TODO: Allow more efficient and configurable batching of these loads
$assoc
->
load
(
$entity
,
new
$assoc
->
targetEntityName
,
$this
->
_em
,
$joinColumnValues
);
}
}
else
{
// Inject collection
...
...
lib/Doctrine/ORM/UnitOfWork.php
View file @
ae1b9371
...
...
@@ -1310,6 +1310,71 @@ class UnitOfWork implements PropertyChangedListener
return
$managedCopy
;
}
/**
*
*
* @param $entity
* @return unknown_type
*/
public
function
refresh
(
$entity
)
{
$visited
=
array
();
return
$this
->
_doRefresh
(
$entity
,
$visited
);
}
/**
* Executes a refresh operation on an entity.
*
* @param object $entity The entity to refresh.
* @param array $visited The already visited entities during cascades.
*/
private
function
_doRefresh
(
$entity
,
array
&
$visited
)
{
$oid
=
spl_object_hash
(
$entity
);
if
(
isset
(
$visited
[
$oid
]))
{
return
;
// Prevent infinite recursion
}
$visited
[
$oid
]
=
$entity
;
// mark visited
$class
=
$this
->
_em
->
getClassMetadata
(
get_class
(
$entity
));
switch
(
$this
->
getEntityState
(
$entity
))
{
case
self
::
STATE_MANAGED
:
$this
->
getEntityPersister
(
$class
->
name
)
->
load
(
array_combine
(
$class
->
identifier
,
$this
->
_entityIdentifiers
[
$oid
]),
$entity
);
break
;
default
:
throw
DoctrineException
::
updateMe
(
"NEW, REMOVED or DETACHED entity can not be refreshed."
);
}
$this
->
_cascadeRefresh
(
$entity
,
$visited
);
}
/**
* Cascades a refresh operation to associated entities.
*
* @param object $entity
* @param array $visited
*/
private
function
_cascadeRefresh
(
$entity
,
array
&
$visited
)
{
$class
=
$this
->
_em
->
getClassMetadata
(
get_class
(
$entity
));
foreach
(
$class
->
associationMappings
as
$assocMapping
)
{
if
(
!
$assocMapping
->
isCascadeRefresh
)
{
continue
;
}
$relatedEntities
=
$class
->
reflFields
[
$assocMapping
->
sourceFieldName
]
->
getValue
(
$entity
);
if
(
$relatedEntities
instanceof
Collection
)
{
foreach
(
$relatedEntities
as
$relatedEntity
)
{
$this
->
_doRefresh
(
$relatedEntity
,
$visited
);
}
}
else
if
(
$relatedEntities
!==
null
)
{
$this
->
_doRefresh
(
$relatedEntities
,
$visited
);
}
}
}
/**
* Cascades a merge operation to associated entities.
*
...
...
@@ -1324,7 +1389,7 @@ class UnitOfWork implements PropertyChangedListener
if
(
!
$assocMapping
->
isCascadeMerge
)
{
continue
;
}
$relatedEntities
=
$class
->
reflFields
[
$assocMapping
->
getSourceFieldName
()
]
$relatedEntities
=
$class
->
reflFields
[
$assocMapping
->
sourceFieldName
]
->
getValue
(
$entity
);
if
(
$relatedEntities
instanceof
Collection
)
{
foreach
(
$relatedEntities
as
$relatedEntity
)
{
...
...
tests/Doctrine/Tests/ORM/Functional/BasicFunctionalTest.php
View file @
ae1b9371
...
...
@@ -173,8 +173,8 @@ class BasicFunctionalTest extends \Doctrine\Tests\OrmFunctionalTestCase
array
())
->
fetchColumn
();
$this
->
assertEquals
(
10
,
$count
);
//
$user->groups->clear();
unset
(
$user
->
groups
);
$user
->
groups
->
clear
();
//
unset($user->groups);
$this
->
_em
->
flush
();
...
...
@@ -184,6 +184,35 @@ class BasicFunctionalTest extends \Doctrine\Tests\OrmFunctionalTestCase
$this
->
assertEquals
(
0
,
$count
);
}
/* NOT YET IMPLEMENTED
public function testOneToManyOrphanDelete()
{
$user = new CmsUser;
$user->name = 'Guilherme';
$user->username = 'gblanco';
$user->status = 'developer';
for ($i=0; $i<3; ++$i) {
$phone = new CmsPhonenumber;
$phone->phonenumber = 100 + $i;
$user->addPhonenumber($phone);
}
$this->_em->persist($user);
$this->_em->flush();
$user->getPhonenumbers()->remove(0);
$this->_em->flush();
// Check that the links in the association table have been deleted
$count = $this->_em->getConnection()->execute("SELECT COUNT(*) FROM cms_phonenumbers",
array())->fetchColumn();
$this->assertEquals(2, $count); // only 2 remaining
}*/
public
function
testBasicQuery
()
{
$user
=
new
CmsUser
;
...
...
@@ -304,4 +333,21 @@ class BasicFunctionalTest extends \Doctrine\Tests\OrmFunctionalTestCase
$query
=
$this
->
_em
->
createQuery
(
"select u, g from Doctrine\Tests\Models\CMS\CmsUser u inner join u.groups g"
);
$this
->
assertEquals
(
0
,
count
(
$query
->
getResultList
()));
}
public
function
testBasicRefresh
()
{
$user
=
new
CmsUser
;
$user
->
name
=
'Guilherme'
;
$user
->
username
=
'gblanco'
;
$user
->
status
=
'developer'
;
$this
->
_em
->
persist
(
$user
);
$this
->
_em
->
flush
();
$user
->
status
=
'mascot'
;
$this
->
assertEquals
(
'mascot'
,
$user
->
status
);
$this
->
_em
->
refresh
(
$user
);
$this
->
assertEquals
(
'developer'
,
$user
->
status
);
}
}
\ No newline at end of file
tests/Doctrine/Tests/ORM/Functional/OneToOneBidirectionalAssociationTest.php
View file @
ae1b9371
...
...
@@ -83,7 +83,7 @@ class OneToOneBidirectionalAssociationTest extends \Doctrine\Tests\OrmFunctional
$this
->
_createFixture
();
$this
->
_em
->
getConfiguration
()
->
setAllowPartialObjects
(
false
);
$metadata
=
$this
->
_em
->
getClassMetadata
(
'Doctrine\Tests\Models\ECommerce\ECommerceCustomer'
);
$metadata
->
getAssociationMapping
(
'
cart'
)
->
fetchMode
=
AssociationMapping
::
FETCH_LAZY
;
$metadata
->
getAssociationMapping
(
'
mentor'
)
->
fetchMode
=
AssociationMapping
::
FETCH_EAGER
;
$query
=
$this
->
_em
->
createQuery
(
'select c from Doctrine\Tests\Models\ECommerce\ECommerceCustomer c'
);
$result
=
$query
->
getResultList
();
...
...
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