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
e2d678cc
Commit
e2d678cc
authored
Oct 22, 2009
by
romanb
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[2.0] Refactorings to reduce duplicated code and increase efficiency.
parent
c54d5825
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
80 additions
and
108 deletions
+80
-108
ObjectHydrator.php
lib/Doctrine/ORM/Internal/Hydration/ObjectHydrator.php
+5
-59
ClassMetadataFactory.php
lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php
+2
-1
JoinedSubclassPersister.php
lib/Doctrine/ORM/Persisters/JoinedSubclassPersister.php
+11
-0
StandardEntityPersister.php
lib/Doctrine/ORM/Persisters/StandardEntityPersister.php
+15
-45
UnitOfWork.php
lib/Doctrine/ORM/UnitOfWork.php
+46
-2
HydrationPerformanceTest.php
...ctrine/Tests/ORM/Performance/HydrationPerformanceTest.php
+1
-1
No files found.
lib/Doctrine/ORM/Internal/Hydration/ObjectHydrator.php
View file @
e2d678cc
...
...
@@ -42,30 +42,22 @@ class ObjectHydrator extends AbstractHydrator
/* The following parts are reinitialized on every hydration run. */
private
$_allowPartialObjects
=
false
;
private
$_identifierMap
;
private
$_resultPointers
;
private
$_idTemplate
;
private
$_resultCounter
;
private
$_fetchedAssociations
;
private
$_rootAliases
=
array
();
private
$_initializedCollections
=
array
();
private
$_existingCollections
=
array
();
private
$_proxyFactory
;
//private $_createdEntities;
/** @override */
protected
function
_prepare
()
{
$this
->
_allowPartialObjects
=
isset
(
$this
->
_hints
[
Query
::
HINT_FORCE_PARTIAL_LOAD
]);
$this
->
_proxyFactory
=
$this
->
_em
->
getProxyFactory
();
$this
->
_identifierMap
=
$this
->
_resultPointers
=
$this
->
_idTemplate
=
$this
->
_fetchedAssociations
=
array
();
$this
->
_idTemplate
=
array
();
$this
->
_resultCounter
=
0
;
foreach
(
$this
->
_rsm
->
aliasMap
as
$dqlAlias
=>
$className
)
{
...
...
@@ -85,13 +77,13 @@ class ObjectHydrator extends AbstractHydrator
$targetClass
=
$this
->
_getClassMetadata
(
$targetClassName
);
$this
->
_ce
[
$targetClassName
]
=
$targetClass
;
$assoc
=
$targetClass
->
associationMappings
[
$this
->
_rsm
->
relationMap
[
$dqlAlias
]];
$this
->
_
fetchedAssociations
[
$assoc
->
sourceEntityName
][
$assoc
->
sourceFieldName
]
=
true
;
$this
->
_
hints
[
'fetched'
]
[
$assoc
->
sourceEntityName
][
$assoc
->
sourceFieldName
]
=
true
;
if
(
$assoc
->
mappedByFieldName
)
{
$this
->
_
fetchedAssociations
[
$assoc
->
targetEntityName
][
$assoc
->
mappedByFieldName
]
=
true
;
$this
->
_
hints
[
'fetched'
]
[
$assoc
->
targetEntityName
][
$assoc
->
mappedByFieldName
]
=
true
;
}
else
{
if
(
isset
(
$targetClass
->
inverseMappings
[
$className
][
$assoc
->
sourceFieldName
]))
{
$inverseAssoc
=
$targetClass
->
inverseMappings
[
$className
][
$assoc
->
sourceFieldName
];
$this
->
_
fetchedAssociations
[
$assoc
->
targetEntityName
][
$inverseAssoc
->
sourceFieldName
]
=
true
;
$this
->
_
hints
[
'fetched'
]
[
$assoc
->
targetEntityName
][
$inverseAssoc
->
sourceFieldName
]
=
true
;
}
}
}
...
...
@@ -186,53 +178,7 @@ class ObjectHydrator extends AbstractHydrator
unset
(
$data
[
$discrColumn
]);
}
$entity
=
$this
->
_uow
->
createEntity
(
$className
,
$data
,
$this
->
_hints
);
//FIXME: If $entity comes from the identity map there is no need to do this!
// Properly initialize any unfetched associations, if partial objects are not allowed.
if
(
!
$this
->
_allowPartialObjects
)
{
$oid
=
spl_object_hash
(
$entity
);
foreach
(
$this
->
_getClassMetadata
(
$className
)
->
associationMappings
as
$field
=>
$assoc
)
{
// Check if the association is not among the fetch-joined associatons already.
if
(
!
isset
(
$this
->
_fetchedAssociations
[
$className
][
$field
]))
{
if
(
$assoc
->
isOneToOne
())
{
$joinColumns
=
array
();
foreach
(
$assoc
->
targetToSourceKeyColumns
as
$srcColumn
)
{
$joinColumns
[
$srcColumn
]
=
$data
[
$assoc
->
joinColumnFieldNames
[
$srcColumn
]];
}
//TODO: If its in the identity map just get it from there if possible!
if
(
$assoc
->
isLazilyFetched
()
/*&& ! $assoc->isOptional*/
)
{
// Inject proxy
$proxy
=
$this
->
_proxyFactory
->
getAssociationProxy
(
$entity
,
$assoc
,
$joinColumns
);
$this
->
_uow
->
setOriginalEntityProperty
(
$oid
,
$field
,
$proxy
);
$this
->
_ce
[
$className
]
->
reflFields
[
$field
]
->
setValue
(
$entity
,
$proxy
);
}
else
{
// Eager load
//TODO: Allow more efficient and configurable batching of these loads
$assoc
->
load
(
$entity
,
new
$assoc
->
targetEntityName
,
$this
->
_em
,
$joinColumns
);
}
}
else
{
// Inject collection
$reflField
=
$this
->
_ce
[
$className
]
->
reflFields
[
$field
];
$pColl
=
new
PersistentCollection
(
$this
->
_em
,
$this
->
_getClassMetadata
(
$assoc
->
targetEntityName
),
$reflField
->
getValue
(
$entity
)
?:
new
ArrayCollection
);
$pColl
->
setOwner
(
$entity
,
$assoc
);
$reflField
->
setValue
(
$entity
,
$pColl
);
if
(
$assoc
->
isLazilyFetched
())
{
$pColl
->
setInitialized
(
false
);
}
else
{
//TODO: Allow more efficient and configurable batching of these loads
$assoc
->
load
(
$entity
,
$pColl
,
$this
->
_em
);
}
$this
->
_uow
->
setOriginalEntityProperty
(
$oid
,
$field
,
$pColl
);
}
}
}
}
return
$entity
;
return
$this
->
_uow
->
createEntity
(
$className
,
$data
,
$this
->
_hints
);
}
private
function
_getEntityFromIdentityMap
(
$className
,
array
$data
)
...
...
lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php
View file @
e2d678cc
...
...
@@ -185,7 +185,8 @@ class ClassMetadataFactory
$class
->
setIdentifier
(
$parent
->
identifier
);
$class
->
setVersioned
(
$parent
->
isVersioned
);
$class
->
setVersionField
(
$parent
->
versionField
);
$class
->
setDiscriminatorMap
(
$parent
->
discriminatorMap
);
$class
->
setDiscriminatorMap
(
$parent
->
discriminatorMap
);
$class
->
resultColumnNames
=
$parent
->
resultColumnNames
;
}
// Invoke driver
...
...
lib/Doctrine/ORM/Persisters/JoinedSubclassPersister.php
View file @
e2d678cc
...
...
@@ -282,6 +282,7 @@ class JoinedSubclassPersister extends StandardEntityPersister
$tableAliases
[
$className
]
=
't'
.
$aliasIndex
++
;
}
// Add regular columns
$columnList
=
''
;
foreach
(
$this
->
_class
->
fieldMappings
as
$fieldName
=>
$mapping
)
{
$tableAlias
=
isset
(
$mapping
[
'inherited'
])
?
...
...
@@ -290,6 +291,15 @@ class JoinedSubclassPersister extends StandardEntityPersister
$columnList
.=
$tableAlias
.
'.'
.
$this
->
_class
->
getQuotedColumnName
(
$fieldName
,
$this
->
_platform
);
}
// Add foreign key columns
foreach
(
$this
->
_class
->
associationMappings
as
$assoc2
)
{
if
(
$assoc2
->
isOwningSide
&&
$assoc2
->
isOneToOne
())
{
foreach
(
$assoc2
->
targetToSourceKeyColumns
as
$srcColumn
)
{
$columnList
.=
', '
.
$assoc2
->
getQuotedJoinColumnName
(
$srcColumn
,
$this
->
_platform
);
}
}
}
// Add discriminator column
if
(
$this
->
_class
->
rootEntityName
==
$this
->
_class
->
name
)
{
$columnList
.=
', '
.
$baseTableAlias
.
'.'
.
...
...
@@ -315,6 +325,7 @@ class JoinedSubclassPersister extends StandardEntityPersister
// OUTER JOIN sub tables
foreach
(
$this
->
_class
->
subClasses
as
$subClassName
)
{
//FIXME: Add columns and foreign key columns of inherited classes to the select list
$subClass
=
$this
->
_em
->
getClassMetadata
(
$subClassName
);
$tableAlias
=
$tableAliases
[
$subClassName
];
$sql
.=
' LEFT JOIN '
.
$subClass
->
getQuotedTableName
(
$this
->
_platform
)
.
' '
.
$tableAlias
.
' ON '
;
...
...
lib/Doctrine/ORM/Persisters/StandardEntityPersister.php
View file @
e2d678cc
...
...
@@ -27,6 +27,7 @@ use Doctrine\Common\DoctrineException,
Doctrine\DBAL\Types\Type
,
Doctrine\ORM\EntityManager
,
Doctrine\ORM\UnitOfWork
,
Doctrine\ORM\Query
,
Doctrine\ORM\PersistentCollection
,
Doctrine\ORM\Mapping\ClassMetadata
,
Doctrine\ORM\Events
;
...
...
@@ -236,9 +237,8 @@ class StandardEntityPersister
if
(
$isVersioned
=
$this
->
_class
->
isVersioned
)
{
$versionField
=
$this
->
_class
->
versionField
;
$versionFieldType
=
$this
->
_class
->
getTypeOfField
(
$versionField
);
$where
[
$this
->
_class
->
fieldNames
[
$versionField
]]
=
Type
::
getType
(
$this
->
_class
->
fieldMappings
[
$versionField
][
'type'
]
)
->
convertToDatabaseValue
(
$entity
->
version
,
$this
->
_platform
);
$where
[
$versionField
]
=
Type
::
getType
(
$versionFieldType
)
->
convertToDatabaseValue
(
$entity
->
version
,
$this
->
_platform
);
$versionFieldColumnName
=
$this
->
_class
->
getQuotedColumnName
(
$versionField
,
$this
->
_platform
);
if
(
$versionFieldType
==
'integer'
)
{
$set
[]
=
$versionFieldColumnName
.
' = '
.
$versionFieldColumnName
.
' + 1'
;
...
...
@@ -504,16 +504,15 @@ class StandardEntityPersister
}
else
if
(
$this
->
_class
->
discriminatorColumn
!==
null
&&
$column
==
$this
->
_class
->
discriminatorColumn
[
'name'
])
{
$entityName
=
$this
->
_class
->
discriminatorMap
[
$value
];
}
else
{
$data
[
$column
]
=
$value
;
$joinColumnValues
[
$column
]
=
$value
;
}
}
if
(
$entity
===
null
)
{
$entity
=
$this
->
_em
->
getUnitOfWork
()
->
createEntity
(
$entityName
,
$data
);
}
else
{
foreach
(
$data
as
$field
=>
$value
)
{
$this
->
_class
->
reflFields
[
$field
]
->
setValue
(
$entity
,
$value
);
}
$hints
=
array
();
if
(
$entity
!==
null
)
{
$hints
[
Query
::
HINT_REFRESH
]
=
true
;
$id
=
array
();
if
(
$this
->
_class
->
isIdentifierComposite
)
{
foreach
(
$this
->
_class
->
identifier
as
$fieldName
)
{
...
...
@@ -524,37 +523,8 @@ class StandardEntityPersister
}
$this
->
_em
->
getUnitOfWork
()
->
registerManaged
(
$entity
,
$id
,
$data
);
}
// Initialize associations
foreach
(
$this
->
_class
->
associationMappings
as
$field
=>
$assoc
)
{
if
(
$assoc
->
isOneToOne
())
{
if
(
$assoc
->
isLazilyFetched
())
{
// Inject proxy
$proxy
=
$this
->
_em
->
getProxyFactory
()
->
getAssociationProxy
(
$entity
,
$assoc
,
$joinColumnValues
);
$this
->
_class
->
reflFields
[
$field
]
->
setValue
(
$entity
,
$proxy
);
}
else
{
// Eager load
//TODO: Allow more efficient and configurable batching of these loads
$assoc
->
load
(
$entity
,
new
$assoc
->
targetEntityName
,
$this
->
_em
,
$joinColumnValues
);
}
}
else
{
// Inject collection
$coll
=
new
PersistentCollection
(
$this
->
_em
,
$this
->
_em
->
getClassMetadata
(
$assoc
->
targetEntityName
),
/*$this->_class->reflFields[$field]->getValue($entity) ?:*/
new
ArrayCollection
);
$coll
->
setOwner
(
$entity
,
$assoc
);
$this
->
_class
->
reflFields
[
$field
]
->
setValue
(
$entity
,
$coll
);
if
(
$assoc
->
isLazilyFetched
())
{
$coll
->
setInitialized
(
false
);
}
else
{
//TODO: Allow more efficient and configurable batching of these loads
$assoc
->
load
(
$entity
,
$coll
,
$this
->
_em
);
}
}
}
return
$entity
;
return
$this
->
_em
->
getUnitOfWork
()
->
createEntity
(
$entityName
,
$data
,
$hints
);
}
/**
...
...
@@ -566,22 +536,23 @@ class StandardEntityPersister
protected
function
_getSelectEntitiesSql
(
array
&
$criteria
,
$assoc
=
null
)
{
$columnList
=
''
;
// Add regular columns to select list
foreach
(
$this
->
_class
->
fieldNames
as
$field
)
{
if
(
$columnList
!=
''
)
$columnList
.=
', '
;
$columnList
.=
$this
->
_class
->
getQuotedColumnName
(
$field
,
$this
->
_platform
);
}
$joinColumnNames
=
array
();
// Add join columns (foreign keys) to select list
foreach
(
$this
->
_class
->
associationMappings
as
$assoc2
)
{
if
(
$assoc2
->
isOwningSide
&&
$assoc2
->
isOneToOne
())
{
foreach
(
$assoc2
->
targetToSourceKeyColumns
as
$srcColumn
)
{
$joinColumnNames
[]
=
$srcColumn
;
$columnList
.=
', '
.
$assoc2
->
getQuotedJoinColumnName
(
$srcColumn
,
$this
->
_platform
);
}
}
}
$joinSql
=
''
;
// Construct WHERE conditions
$conditionSql
=
''
;
foreach
(
$criteria
as
$field
=>
$value
)
{
if
(
$conditionSql
!=
''
)
{
...
...
@@ -600,7 +571,6 @@ class StandardEntityPersister
return
'SELECT '
.
$columnList
.
' FROM '
.
$this
->
_class
->
getQuotedTableName
(
$this
->
_platform
)
.
$joinSql
.
(
$conditionSql
?
' WHERE '
.
$conditionSql
:
''
);
}
...
...
lib/Doctrine/ORM/UnitOfWork.php
View file @
e2d678cc
...
...
@@ -1653,7 +1653,7 @@ class UnitOfWork implements PropertyChangedListener
* @return object The created entity instance.
* @internal Highly performance-sensitive method.
*/
public
function
createEntity
(
$className
,
array
$data
,
$hints
=
array
())
public
function
createEntity
(
$className
,
array
$data
,
&
$hints
=
array
())
{
$class
=
$this
->
_em
->
getClassMetadata
(
$className
);
...
...
@@ -1695,9 +1695,53 @@ class UnitOfWork implements PropertyChangedListener
}
}
}
// Properly initialize any unfetched associations, if partial objects are not allowed.
if
(
!
isset
(
$hints
[
Query
::
HINT_FORCE_PARTIAL_LOAD
]))
{
foreach
(
$class
->
associationMappings
as
$field
=>
$assoc
)
{
// Check if the association is not among the fetch-joined associatons already.
if
(
!
isset
(
$hints
[
'fetched'
][
$className
][
$field
]))
{
if
(
$assoc
->
isOneToOne
())
{
$joinColumns
=
array
();
if
(
$assoc
->
isOwningSide
)
{
foreach
(
$assoc
->
targetToSourceKeyColumns
as
$srcColumn
)
{
$joinColumns
[
$srcColumn
]
=
$data
[
$assoc
->
joinColumnFieldNames
[
$srcColumn
]];
}
}
//TODO: If its in the identity map just get it from there if possible!
if
(
$assoc
->
isLazilyFetched
()
/*&& $assoc->isOwningSide)*/
)
{
// Inject proxy
$proxy
=
$this
->
_em
->
getProxyFactory
()
->
getAssociationProxy
(
$entity
,
$assoc
,
$joinColumns
);
$this
->
_originalEntityData
[
$oid
][
$field
]
=
$proxy
;
$class
->
reflFields
[
$field
]
->
setValue
(
$entity
,
$proxy
);
}
else
{
// Eager load
//TODO: Allow more efficient and configurable batching of these loads
$assoc
->
load
(
$entity
,
new
$assoc
->
targetEntityName
,
$this
->
_em
,
$joinColumns
);
}
}
else
{
// Inject collection
$reflField
=
$class
->
reflFields
[
$field
];
$pColl
=
new
PersistentCollection
(
$this
->
_em
,
$this
->
_em
->
getClassMetadata
(
$assoc
->
targetEntityName
),
$reflField
->
getValue
(
$entity
)
?:
new
ArrayCollection
);
$pColl
->
setOwner
(
$entity
,
$assoc
);
$reflField
->
setValue
(
$entity
,
$pColl
);
if
(
$assoc
->
isLazilyFetched
())
{
$pColl
->
setInitialized
(
false
);
}
else
{
//TODO: Allow more efficient and configurable batching of these loads
$assoc
->
load
(
$entity
,
$pColl
,
$this
->
_em
);
}
$this
->
_originalEntityData
[
$oid
][
$field
]
=
$pColl
;
}
}
}
}
}
//TODO: These should be invoked later,
because associations are not yet
loaded here.
//TODO: These should be invoked later,
after hydration, because associations may not yet be
loaded here.
if
(
isset
(
$class
->
lifecycleCallbacks
[
Events
::
postLoad
]))
{
$class
->
invokeLifecycleCallbacks
(
Events
::
postLoad
,
$entity
);
}
...
...
tests/Doctrine/Tests/ORM/Performance/HydrationPerformanceTest.php
View file @
e2d678cc
...
...
@@ -339,7 +339,7 @@ class HydrationPerformanceTest extends \Doctrine\Tests\OrmPerformanceTestCase
*
* MAXIMUM TIME: 1 second
*/
public
function
testMixedQueryFetchJoinFullObjectHydrationPerformance200Rows
()
public
function
testMixedQueryFetchJoinFullObjectHydrationPerformance200
0
Rows
()
{
$rsm
=
new
ResultSetMapping
;
$rsm
->
addEntityResult
(
'Doctrine\Tests\Models\CMS\CmsUser'
,
'u'
);
...
...
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