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
e1f2b8ab
Commit
e1f2b8ab
authored
Jul 30, 2009
by
romanb
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[2.0] Implemented support for mapped superclasses. Fixed #2353.
parent
77206615
Changes
19
Hide whitespace changes
Inline
Side-by-side
Showing
19 changed files
with
350 additions
and
116 deletions
+350
-116
ArrayCollection.php
lib/Doctrine/Common/Collections/ArrayCollection.php
+1
-2
EntityManager.php
lib/Doctrine/ORM/EntityManager.php
+16
-18
EntityRepository.php
lib/Doctrine/ORM/EntityRepository.php
+28
-22
ArrayHydrator.php
lib/Doctrine/ORM/Internal/Hydration/ArrayHydrator.php
+9
-5
ObjectHydrator.php
lib/Doctrine/ORM/Internal/Hydration/ObjectHydrator.php
+8
-6
ClassMetadata.php
lib/Doctrine/ORM/Mapping/ClassMetadata.php
+13
-4
ClassMetadataFactory.php
lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php
+22
-9
AnnotationDriver.php
lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php
+13
-11
DoctrineAnnotations.php
lib/Doctrine/ORM/Mapping/Driver/DoctrineAnnotations.php
+3
-0
NativeQuery.php
lib/Doctrine/ORM/NativeQuery.php
+1
-1
OptimisticLockException.php
lib/Doctrine/ORM/OptimisticLockException.php
+1
-2
ResultSetMapping.php
lib/Doctrine/ORM/Query/ResultSetMapping.php
+11
-6
QueryBuilder.php
lib/Doctrine/ORM/QueryBuilder.php
+14
-13
SchemaTool.php
lib/Doctrine/ORM/Tools/SchemaTool.php
+6
-5
UnitOfWork.php
lib/Doctrine/ORM/UnitOfWork.php
+1
-12
AllTests.php
tests/Doctrine/Tests/ORM/Functional/AllTests.php
+1
-0
MappedSuperclassTest.php
tests/Doctrine/Tests/ORM/Functional/MappedSuperclassTest.php
+111
-0
AllTests.php
tests/Doctrine/Tests/ORM/Mapping/AllTests.php
+1
-0
BasicInheritanceMappingTest.php
...octrine/Tests/ORM/Mapping/BasicInheritanceMappingTest.php
+90
-0
No files found.
lib/Doctrine/Common/Collections/ArrayCollection.php
View file @
e1f2b8ab
...
...
@@ -302,8 +302,7 @@ class ArrayCollection implements Collection
*/
public
function
isEmpty
()
{
// Note: Little "trick". Empty arrays evaluate to FALSE. No need to count().
return
!
(
bool
)
$this
->
_elements
;
return
!
$this
->
_elements
;
}
/**
...
...
lib/Doctrine/ORM/EntityManager.php
View file @
e1f2b8ab
...
...
@@ -21,13 +21,13 @@
namespace
Doctrine\ORM
;
use
Doctrine\Common\EventManager
;
use
Doctrine\Common\DoctrineException
;
use
Doctrine\DBAL\Connection
;
use
Doctrine\ORM\Mapping\ClassMetadata
;
use
Doctrine\ORM\Mapping\ClassMetadataFactory
;
use
Doctrine\ORM\Proxy\ProxyFactory
;
use
Doctrine\ORM\Proxy\ProxyClassGenerator
;
use
Doctrine\Common\EventManager
,
Doctrine\Common\DoctrineException
,
Doctrine\DBAL\Connection
,
Doctrine\ORM\Mapping\ClassMetadata
,
Doctrine\ORM\Mapping\ClassMetadataFactory
,
Doctrine\ORM\Proxy\ProxyFactory
,
Doctrine\ORM\Proxy\ProxyClassGenerator
;
/**
* The EntityManager is the central access point to ORM functionality.
...
...
@@ -146,7 +146,6 @@ class EntityManager
$this
->
_metadataFactory
=
new
ClassMetadataFactory
(
$this
);
$this
->
_metadataFactory
->
setCacheDriver
(
$this
->
_config
->
getMetadataCacheImpl
());
$this
->
_unitOfWork
=
new
UnitOfWork
(
$this
);
//FIX: this should be in a factory
$this
->
_proxyFactory
=
new
ProxyFactory
(
$this
,
new
ProxyClassGenerator
(
$this
,
$this
->
_config
->
getCacheDir
()));
}
...
...
@@ -179,7 +178,7 @@ class EntityManager
}
/**
* Commits a
running transa
ction.
* Commits a
transaction on the underlying database conne
ction.
*
* This causes a flush() of the EntityManager if the flush mode is set to
* AUTO or COMMIT.
...
...
@@ -482,8 +481,7 @@ class EntityManager
* Determines whether an entity instance is managed in this EntityManager.
*
* @param object $entity
* @return boolean TRUE if this EntityManager currently manages the given entity
* (and has it in the identity map), FALSE otherwise.
* @return boolean TRUE if this EntityManager currently manages the given entity, FALSE otherwise.
*/
public
function
contains
(
$entity
)
{
...
...
@@ -514,12 +512,12 @@ class EntityManager
/**
* Throws an exception if the EntityManager is closed or currently not active.
*
* @throws EntityManagerException If the EntityManager is closed
or not active
.
* @throws EntityManagerException If the EntityManager is closed.
*/
private
function
_errorIfClosed
()
{
if
(
$this
->
_closed
)
{
throw
EntityManagerException
::
notActiveOrC
losed
();
throw
EntityManagerException
::
c
losed
();
}
}
...
...
@@ -543,19 +541,19 @@ class EntityManager
if
(
!
isset
(
$this
->
_hydrators
[
$hydrationMode
]))
{
switch
(
$hydrationMode
)
{
case
Query
::
HYDRATE_OBJECT
:
$this
->
_hydrators
[
$hydrationMode
]
=
new
\Doctrine\ORM\
Internal\Hydration\ObjectHydrator
(
$this
);
$this
->
_hydrators
[
$hydrationMode
]
=
new
Internal\Hydration\ObjectHydrator
(
$this
);
break
;
case
Query
::
HYDRATE_ARRAY
:
$this
->
_hydrators
[
$hydrationMode
]
=
new
\Doctrine\ORM\
Internal\Hydration\ArrayHydrator
(
$this
);
$this
->
_hydrators
[
$hydrationMode
]
=
new
Internal\Hydration\ArrayHydrator
(
$this
);
break
;
case
Query
::
HYDRATE_SCALAR
:
$this
->
_hydrators
[
$hydrationMode
]
=
new
\Doctrine\ORM\
Internal\Hydration\ScalarHydrator
(
$this
);
$this
->
_hydrators
[
$hydrationMode
]
=
new
Internal\Hydration\ScalarHydrator
(
$this
);
break
;
case
Query
::
HYDRATE_SINGLE_SCALAR
:
$this
->
_hydrators
[
$hydrationMode
]
=
new
\Doctrine\ORM\
Internal\Hydration\SingleScalarHydrator
(
$this
);
$this
->
_hydrators
[
$hydrationMode
]
=
new
Internal\Hydration\SingleScalarHydrator
(
$this
);
break
;
case
Query
::
HYDRATE_NONE
:
$this
->
_hydrators
[
$hydrationMode
]
=
new
\Doctrine\ORM\
Internal\Hydration\NoneHydrator
(
$this
);
$this
->
_hydrators
[
$hydrationMode
]
=
new
Internal\Hydration\NoneHydrator
(
$this
);
break
;
default
:
throw
DoctrineException
::
updateMe
(
"No hydrator found for hydration mode '
$hydrationMode
'."
);
...
...
lib/Doctrine/ORM/EntityRepository.php
View file @
e1f2b8ab
...
...
@@ -36,23 +36,28 @@ namespace Doctrine\ORM;
*/
class
EntityRepository
{
pr
otected
$_entityName
;
pr
otected
$_em
;
pr
otected
$_classMetadata
;
pr
ivate
$_entityName
;
pr
ivate
$_em
;
pr
ivate
$_class
;
public
function
__construct
(
$em
,
\Doctrine\ORM\Mapping\ClassMetadata
$classMetadata
)
/**
* Initializes a new <tt>EntityRepository</tt>.
*
* @param EntityManager $em The EntityManager to use.
* @param ClassMetadata $classMetadata The class descriptor.
*/
public
function
__construct
(
$em
,
\Doctrine\ORM\Mapping\ClassMetadata
$class
)
{
$this
->
_entityName
=
$class
Metadata
->
name
;
$this
->
_entityName
=
$class
->
name
;
$this
->
_em
=
$em
;
$this
->
_class
Metadata
=
$classMetadata
;
$this
->
_class
=
$class
;
}
/**
*
c
reates a new Doctrine_Query object and adds the component name
* of this table as the query 'from' part
*
C
reates a new Doctrine_Query object and adds the component name
* of this table as the query 'from' part
.
*
* @param string Optional alias name for component aliasing.
*
* @return Doctrine_Query
*/
protected
function
_createQuery
(
$alias
=
''
)
...
...
@@ -68,26 +73,26 @@ class EntityRepository
*/
public
function
clear
()
{
$this
->
_em
->
getUnitOfWork
()
->
clearIdentitiesForEntity
(
$this
->
_classMetadata
->
rootEntityName
);
$this
->
_em
->
clear
(
$this
->
_class
->
rootEntityName
);
}
/**
* Finds an entity by its primary key.
* Finds an entity by its primary key
/ identifier
.
*
* @param $id
The identifier.
* @param int $hydrationMode
The hydration mode to use.
* @return mixed
Array or Doctrine_Entity or false if no result
* @param $id The identifier.
* @param int $hydrationMode The hydration mode to use.
* @return mixed
Array or Object or false if no result.
*/
public
function
find
(
$id
,
$hydrationMode
=
null
)
{
// Check identity map first
if
(
$entity
=
$this
->
_em
->
getUnitOfWork
()
->
tryGetById
(
$id
,
$this
->
_class
Metadata
->
rootEntityName
))
{
if
(
$entity
=
$this
->
_em
->
getUnitOfWork
()
->
tryGetById
(
$id
,
$this
->
_class
->
rootEntityName
))
{
return
$entity
;
// Hit!
}
if
(
!
is_array
(
$id
)
||
count
(
$id
)
<=
1
)
{
$value
=
is_array
(
$id
)
?
array_values
(
$id
)
:
array
(
$id
);
$id
=
array_combine
(
$this
->
_class
Metadata
->
identifier
,
$value
);
$id
=
array_combine
(
$this
->
_class
->
identifier
,
$value
);
}
return
$this
->
_em
->
getUnitOfWork
()
->
getEntityPersister
(
$this
->
_entityName
)
->
load
(
$id
);
...
...
@@ -127,9 +132,10 @@ class EntityRepository
*/
protected
function
findOneBy
(
$fieldName
,
$value
,
$hydrationMode
=
null
)
{
$results
=
$this
->
_createQuery
()
->
where
(
$fieldName
.
' = ?'
)
->
limit
(
1
)
->
execute
(
array
(
$value
),
$hydrationMode
);
return
$hydrationMode
===
Doctrine
::
HYDRATE_ARRAY
?
array_shift
(
$results
)
:
$results
->
getFirst
();
$results
=
$this
->
_createQuery
()
->
where
(
$fieldName
.
' = ?'
)
->
setMaxResults
(
1
)
->
execute
(
array
(
$value
),
$hydrationMode
);
return
$hydrationMode
===
Query
::
HYDRATE_ARRAY
?
array_shift
(
$results
)
:
$results
->
getFirst
();
}
/**
...
...
@@ -162,10 +168,10 @@ class EntityRepository
$fieldName
=
Doctrine
::
tableize
(
$by
);
$hydrationMode
=
isset
(
$arguments
[
1
])
?
$arguments
[
1
]
:
null
;
if
(
$this
->
_class
Metadata
->
hasField
(
$fieldName
))
{
if
(
$this
->
_class
->
hasField
(
$fieldName
))
{
return
$this
->
$method
(
$fieldName
,
$arguments
[
0
],
$hydrationMode
);
}
else
if
(
$this
->
_class
Metadata
->
hasRelation
(
$by
))
{
$relation
=
$this
->
_class
Metadata
->
getRelation
(
$by
);
}
else
if
(
$this
->
_class
->
hasRelation
(
$by
))
{
$relation
=
$this
->
_class
->
getRelation
(
$by
);
if
(
$relation
[
'type'
]
===
Doctrine_Relation
::
MANY
)
{
throw
DoctrineException
::
updateMe
(
'Cannot findBy many relationship.'
);
}
...
...
lib/Doctrine/ORM/Internal/Hydration/ArrayHydrator.php
View file @
e1f2b8ab
...
...
@@ -42,12 +42,12 @@ class ArrayHydrator extends AbstractHydrator
/** @override */
protected
function
_prepare
()
{
$this
->
_isSimpleQuery
=
$this
->
_rsm
->
getEntityResultCount
(
)
<=
1
;
$this
->
_isSimpleQuery
=
count
(
$this
->
_rsm
->
aliasMap
)
<=
1
;
$this
->
_identifierMap
=
array
();
$this
->
_resultPointers
=
array
();
$this
->
_idTemplate
=
array
();
$this
->
_resultCounter
=
0
;
foreach
(
$this
->
_rsm
->
getAliasMap
()
as
$dqlAlias
=>
$className
)
{
foreach
(
$this
->
_rsm
->
aliasMap
as
$dqlAlias
=>
$className
)
{
$this
->
_identifierMap
[
$dqlAlias
]
=
array
();
$this
->
_resultPointers
[
$dqlAlias
]
=
array
();
$this
->
_idTemplate
[
$dqlAlias
]
=
''
;
...
...
@@ -89,8 +89,6 @@ class ArrayHydrator extends AbstractHydrator
// It's a joined result
$parent
=
$this
->
_rsm
->
parentAliasMap
[
$dqlAlias
];
$relation
=
$this
->
_rsm
->
relationMap
[
$dqlAlias
];
$relationAlias
=
$relation
->
getSourceFieldName
();
$path
=
$parent
.
'.'
.
$dqlAlias
;
// Get a reference to the right element in the result tree.
...
...
@@ -105,6 +103,11 @@ class ArrayHydrator extends AbstractHydrator
unset
(
$this
->
_resultPointers
[
$dqlAlias
]);
// Ticket #1228
continue
;
}
$relation
=
$this
->
_rsm
->
relationMap
[
$dqlAlias
];
$relationAlias
=
$relation
->
sourceFieldName
;
//$relationAlias = $this->_rsm->relationMap[$dqlAlias];
//$relation = $this->_ce[$parentClass]->associationMappings[$relationField];
// Check the type of the relation (many or single-valued)
if
(
!
$relation
->
isOneToOne
())
{
...
...
@@ -113,9 +116,11 @@ class ArrayHydrator extends AbstractHydrator
if
(
!
isset
(
$baseElement
[
$relationAlias
]))
{
$baseElement
[
$relationAlias
]
=
array
();
}
$indexExists
=
isset
(
$this
->
_identifierMap
[
$path
][
$id
[
$parent
]][
$id
[
$dqlAlias
]]);
$index
=
$indexExists
?
$this
->
_identifierMap
[
$path
][
$id
[
$parent
]][
$id
[
$dqlAlias
]]
:
false
;
$indexIsValid
=
$index
!==
false
?
isset
(
$baseElement
[
$relationAlias
][
$index
])
:
false
;
if
(
!
$indexExists
||
!
$indexIsValid
)
{
$element
=
$data
;
if
(
isset
(
$this
->
_rsm
->
indexByMap
[
$dqlAlias
]))
{
...
...
@@ -176,7 +181,6 @@ class ArrayHydrator extends AbstractHydrator
$index
=
$this
->
_identifierMap
[
$dqlAlias
][
$id
[
$dqlAlias
]];
}
$this
->
updateResultPointer
(
$result
,
$index
,
$dqlAlias
,
false
);
//unset($rowData[$rootAlias]);
}
}
...
...
lib/Doctrine/ORM/Internal/Hydration/ObjectHydrator.php
View file @
e1f2b8ab
...
...
@@ -92,6 +92,7 @@ class ObjectHydrator extends AbstractHydrator
// Remember which associations are "fetch joined"
if
(
isset
(
$this
->
_rsm
->
relationMap
[
$dqlAlias
]))
{
$assoc
=
$this
->
_rsm
->
relationMap
[
$dqlAlias
];
//$assoc = $class->associationMappings[$this->_rsm->relationMap[$dqlAlias]];
$this
->
_fetchedAssociations
[
$assoc
->
sourceEntityName
][
$assoc
->
sourceFieldName
]
=
true
;
if
(
$assoc
->
mappedByFieldName
)
{
$this
->
_fetchedAssociations
[
$assoc
->
targetEntityName
][
$assoc
->
mappedByFieldName
]
=
true
;
...
...
@@ -148,9 +149,9 @@ class ObjectHydrator extends AbstractHydrator
end
(
$coll
);
$this
->
_resultPointers
[
$dqlAlias
]
=&
$coll
[
key
(
$coll
)];
}
else
if
(
$coll
instanceof
Collection
)
{
if
(
count
(
$coll
)
>
0
)
{
//if ( ! $coll->isEmpty()
) {
$this
->
_resultPointers
[
$dqlAlias
]
=
$coll
->
last
();
}
//
}
}
else
{
$this
->
_resultPointers
[
$dqlAlias
]
=
$coll
;
}
...
...
@@ -301,8 +302,6 @@ class ObjectHydrator extends AbstractHydrator
// It's a joined result
$parent
=
$this
->
_rsm
->
parentAliasMap
[
$dqlAlias
];
$relation
=
$this
->
_rsm
->
relationMap
[
$dqlAlias
];
$relationField
=
$relation
->
sourceFieldName
;
// Get a reference to the right element in the result tree.
// This element will get the associated element attached.
...
...
@@ -319,9 +318,13 @@ class ObjectHydrator extends AbstractHydrator
$parentClass
=
get_class
(
$baseElement
);
$oid
=
spl_object_hash
(
$baseElement
);
$relation
=
$this
->
_rsm
->
relationMap
[
$dqlAlias
];
//$relationField = $this->_rsm->relationMap[$dqlAlias];
//$relation = $this->_ce[$parentClass]->associationMappings[$relationField];
$relationField
=
$relation
->
sourceFieldName
;
$reflField
=
$this
->
_ce
[
$parentClass
]
->
reflFields
[
$relationField
];
$reflFieldValue
=
$reflField
->
getValue
(
$baseElement
);
// Check the type of the relation (many or single-valued)
if
(
!
$relation
->
isOneToOne
())
{
// Collection-valued association
...
...
@@ -406,7 +409,6 @@ class ObjectHydrator extends AbstractHydrator
}
}
else
{
// Its a root result element
$this
->
_rootAliases
[
$dqlAlias
]
=
true
;
// Mark as root alias
if
(
$this
->
_isSimpleQuery
||
!
isset
(
$this
->
_identifierMap
[
$dqlAlias
][
$id
[
$dqlAlias
]]))
{
...
...
lib/Doctrine/ORM/Mapping/ClassMetadata.php
View file @
e1f2b8ab
...
...
@@ -24,8 +24,8 @@ namespace Doctrine\ORM\Mapping;
use
Doctrine\Common\DoctrineException
;
/**
* A <tt>ClassMetadata</tt> instance holds all the
ORM metadata of an entity and
*
it's associations. It is the backbone of Doctrine's metadata mapping
.
* A <tt>ClassMetadata</tt> instance holds all the
object-relational mapping metadata
*
of an entity and it's associations
.
*
* Once populated, ClassMetadata instances are usually cached in a serialized form.
*
...
...
@@ -142,6 +142,13 @@ final class ClassMetadata
* @var string
*/
public
$customRepositoryClassName
;
/**
* Whether this class describes the mapping of a mapped superclass.
*
* @var boolean
*/
public
$isMappedSuperclass
=
false
;
/**
* The names of the parent classes (ancestors).
...
...
@@ -1352,14 +1359,16 @@ final class ClassMetadata
* @param string $owningClassName The name of the class that defined this mapping.
* @todo Rename: addInheritedAssociationMapping
*/
public
function
addAssociationMapping
(
AssociationMapping
$mapping
,
$owningClassName
)
public
function
addAssociationMapping
(
AssociationMapping
$mapping
,
$owningClassName
=
null
)
{
$sourceFieldName
=
$mapping
->
sourceFieldName
;
if
(
isset
(
$this
->
associationMappings
[
$sourceFieldName
]))
{
throw
MappingException
::
duplicateFieldMapping
();
}
$this
->
associationMappings
[
$sourceFieldName
]
=
$mapping
;
$this
->
inheritedAssociationFields
[
$sourceFieldName
]
=
$owningClassName
;
if
(
$owningClassName
!==
null
)
{
$this
->
inheritedAssociationFields
[
$sourceFieldName
]
=
$owningClassName
;
}
$this
->
_registerMappingIfInverse
(
$mapping
);
}
...
...
lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php
View file @
e1f2b8ab
...
...
@@ -21,9 +21,9 @@
namespace
Doctrine\ORM\Mapping
;
use
Doctrine\Common\DoctrineException
;
use
Doctrine\DBAL\Platforms\AbstractPlatform
;
use
Doctrine\ORM\Events
;
use
Doctrine\Common\DoctrineException
,
Doctrine\DBAL\Platforms\AbstractPlatform
,
Doctrine\ORM\Events
;
/**
* The ClassMetadataFactory is used to create ClassMetadata objects that contain all the
...
...
@@ -89,7 +89,7 @@ class ClassMetadataFactory
}
/**
*
Returns the metadata object
for a class.
*
Gets the class metadata descriptor
for a class.
*
* @param string $className The name of the class.
* @return Doctrine\ORM\Mapping\ClassMetadata
...
...
@@ -112,6 +112,11 @@ class ClassMetadataFactory
return
$this
->
_loadedMetadata
[
$className
];
}
/**
*
* @param $className
* @return boolean
*/
public
function
hasMetadataFor
(
$className
)
{
return
isset
(
$this
->
_loadedMetadata
[
$className
]);
...
...
@@ -156,11 +161,14 @@ class ClassMetadataFactory
foreach
(
$parentClasses
as
$className
)
{
if
(
isset
(
$this
->
_loadedMetadata
[
$className
]))
{
$parent
=
$this
->
_loadedMetadata
[
$className
];
array_unshift
(
$visited
,
$className
);
if
(
!
$parent
->
isMappedSuperclass
)
{
array_unshift
(
$visited
,
$className
);
}
continue
;
}
$class
=
$this
->
_newClassMetadataInstance
(
$className
);
if
(
$parent
)
{
$class
->
setInheritanceType
(
$parent
->
inheritanceType
);
$class
->
setDiscriminatorColumn
(
$parent
->
discriminatorColumn
);
...
...
@@ -176,7 +184,7 @@ class ClassMetadataFactory
$this
->
_driver
->
loadMetadataForClass
(
$className
,
$class
);
// Verify & complete identifier mapping
if
(
!
$class
->
identifier
)
{
if
(
!
$class
->
identifier
&&
!
$class
->
isMappedSuperclass
)
{
throw
MappingException
::
identifierRequired
(
$className
);
}
if
(
$parent
)
{
...
...
@@ -207,7 +215,10 @@ class ClassMetadataFactory
$this
->
_loadedMetadata
[
$className
]
=
$class
;
$parent
=
$class
;
array_unshift
(
$visited
,
$className
);
if
(
!
$class
->
isMappedSuperclass
)
{
array_unshift
(
$visited
,
$className
);
}
}
}
...
...
@@ -231,7 +242,7 @@ class ClassMetadataFactory
private
function
_addInheritedFields
(
ClassMetadata
$subClass
,
ClassMetadata
$parentClass
)
{
foreach
(
$parentClass
->
fieldMappings
as
$fieldName
=>
$mapping
)
{
if
(
!
isset
(
$mapping
[
'inherited'
]))
{
if
(
!
isset
(
$mapping
[
'inherited'
])
&&
!
$parentClass
->
isMappedSuperclass
)
{
$mapping
[
'inherited'
]
=
$parentClass
->
name
;
}
$subClass
->
addFieldMapping
(
$mapping
);
...
...
@@ -253,9 +264,11 @@ class ClassMetadataFactory
if
(
isset
(
$parentClass
->
inheritedAssociationFields
[
$mapping
->
sourceFieldName
]))
{
// parent class also inherited that one
$subClass
->
addAssociationMapping
(
$mapping
,
$parentClass
->
inheritedAssociationFields
[
$mapping
->
sourceFieldName
]);
}
else
{
}
else
if
(
!
$parentClass
->
isMappedSuperclass
)
{
// parent class defined that one
$subClass
->
addAssociationMapping
(
$mapping
,
$parentClass
->
name
);
}
else
{
$subClass
->
addAssociationMapping
(
$mapping
);
}
}
}
...
...
lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php
View file @
e1f2b8ab
...
...
@@ -21,11 +21,11 @@
namespace
Doctrine\ORM\Mapping\Driver
;
use
Doctrine\Common\DoctrineException
;
use
Doctrine\Common\Cache\ArrayCache
;
use
Doctrine\Common\Annotations\AnnotationReader
;
use
Doctrine\ORM\Mapping\ClassMetadata
;
use
Doctrine\ORM\Mapping\MappingException
;
use
Doctrine\Common\DoctrineException
,
Doctrine\Common\Cache\ArrayCache
,
Doctrine\Common\Annotations\AnnotationReader
,
Doctrine\ORM\Mapping\ClassMetadata
,
Doctrine\ORM\Mapping\MappingException
;
require
__DIR__
.
'/DoctrineAnnotations.php'
;
...
...
@@ -60,13 +60,15 @@ class AnnotationDriver implements Driver
$classAnnotations
=
$this
->
_reader
->
getClassAnnotations
(
$class
);
// Evaluate DoctrineEntity annotation
if
(
!
isset
(
$classAnnotations
[
'Doctrine\ORM\Mapping\Entity'
]))
{
throw
DoctrineException
::
updateMe
(
"
$className
is no entity."
);
// Evaluate Entity annotation
if
(
isset
(
$classAnnotations
[
'Doctrine\ORM\Mapping\Entity'
]))
{
$entityAnnot
=
$classAnnotations
[
'Doctrine\ORM\Mapping\Entity'
];
$metadata
->
setCustomRepositoryClass
(
$entityAnnot
->
repositoryClass
);
}
else
if
(
isset
(
$classAnnotations
[
'Doctrine\ORM\Mapping\MappedSuperclass'
]))
{
$metadata
->
isMappedSuperclass
=
true
;
}
else
{
throw
DoctrineException
::
updateMe
(
"
$className
is no entity or mapped superclass."
);
}
$entityAnnot
=
$classAnnotations
[
'Doctrine\ORM\Mapping\Entity'
];
$metadata
->
setCustomRepositoryClass
(
$entityAnnot
->
repositoryClass
);
// Evaluate DoctrineTable annotation
if
(
isset
(
$classAnnotations
[
'Doctrine\ORM\Mapping\Table'
]))
{
...
...
lib/Doctrine/ORM/Mapping/Driver/DoctrineAnnotations.php
View file @
e1f2b8ab
...
...
@@ -21,11 +21,14 @@
namespace
Doctrine\ORM\Mapping
;
use
\Doctrine\Common\Annotations\Annotation
;
/* Annotations */
final
class
Entity
extends
\Doctrine\Common\Annotations\Annotation
{
public
$repositoryClass
;
}
final
class
MappedSuperclass
extends
Annotation
{}
final
class
InheritanceType
extends
\Doctrine\Common\Annotations\Annotation
{}
final
class
DiscriminatorColumn
extends
\Doctrine\Common\Annotations\Annotation
{
public
$name
;
...
...
lib/Doctrine/ORM/NativeQuery.php
View file @
e1f2b8ab
...
...
@@ -35,7 +35,7 @@ final class NativeQuery extends AbstractQuery
* Initializes a new instance of the <tt>NativeQuery</tt> class that is bound
* to the given EntityManager.
*
* @param EntityManager $em
* @param EntityManager $em
The EntityManager to use.
*/
public
function
__construct
(
EntityManager
$em
)
{
...
...
lib/Doctrine/ORM/OptimisticLockException.php
View file @
e1f2b8ab
...
...
@@ -22,9 +22,8 @@
namespace
Doctrine\ORM
;
/**
*
EntityManager
Exception
*
OptimisticLock
Exception
*
* @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/ORM/Query/ResultSetMapping.php
View file @
e1f2b8ab
...
...
@@ -25,11 +25,16 @@ namespace Doctrine\ORM\Query;
* A ResultSetMapping describes how a result set of an SQL query maps to a Doctrine result.
*
* IMPORTANT NOTE:
* The properties of this class are only public for fast internal READ access.
* The properties of this class are only public for fast internal READ access and to (drastically)
* reduce the size of serialized instances for more effective caching due to better (un-)serialization
* performance.
*
* Users should use the public methods.
*
* @author Roman Borschel <roman@code-factory.org>
* @since 2.0
* @todo Do not store AssociationMappings in $relationMap. These bloat serialized instances
* and in turn unserialize performance suffers which is important for most effective caching.
*/
class
ResultSetMapping
{
...
...
@@ -54,7 +59,7 @@ class ResultSetMapping
/** Maps alias names to field names that should be used for indexing. */
public
$indexByMap
=
array
();
/** A list of columns that should be ignored/skipped during hydration. */
public
$ignoredColumns
=
array
();
//
public $ignoredColumns = array();
/**
*
...
...
@@ -318,19 +323,19 @@ class ResultSetMapping
*
* @param string $columnName
*/
public
function
addIgnoredColumn
(
$columnName
)
/*
public function addIgnoredColumn($columnName)
{
$this->ignoredColumns[$columnName] = true;
}
}
*/
/**
*
* @param string $columnName
* @return boolean
*/
public
function
isIgnoredColumn
(
$columnName
)
/*
public function isIgnoredColumn($columnName)
{
return isset($this->ignoredColumns[$columnName]);
}
}
*/
}
lib/Doctrine/ORM/QueryBuilder.php
View file @
e1f2b8ab
...
...
@@ -47,12 +47,12 @@ class QueryBuilder
const
STATE_CLEAN
=
1
;
/**
* @var EntityManager $em Instance of an EntityManager to use for query
* @var EntityManager $em Instance of an EntityManager to use for query
.
*/
private
$_em
;
/**
* @var array $dqlParts The array of DQL parts collected
* @var array $dqlParts The array of DQL parts collected
.
*/
private
$_dqlParts
=
array
(
'select'
=>
array
(),
...
...
@@ -64,25 +64,30 @@ class QueryBuilder
);
/**
* @var integer
$type The type of query this is. Can be select, update or delete
* @var integer
The type of query this is. Can be select, update or delete.
*/
private
$_type
=
self
::
SELECT
;
/**
* @var integer
$state
The state of the query object. Can be dirty or clean.
* @var integer The state of the query object. Can be dirty or clean.
*/
private
$_state
=
self
::
STATE_CLEAN
;
/**
* @var string
$dql The complete DQL string for this query
* @var string
The complete DQL string for this query.
*/
private
$_dql
;
/**
* @var Query
$q The Query instance used for this QueryBuilder
* @var Query
The Query instance used for this QueryBuilder.
*/
private
$_q
;
/**
* Initializes a new <tt>QueryBuilder</tt> that uses the given <tt>EntityManager</tt>.
*
* @param EntityManager $entityManager The EntityManager to use.
*/
public
function
__construct
(
EntityManager
$entityManager
)
{
$this
->
_em
=
$entityManager
;
...
...
@@ -399,12 +404,10 @@ class QueryBuilder
*
* BNF:
*
* UpdateStatement = UpdateClause [WhereClause] [OrderByClause]
[LimitClause] [OffsetClause]
* UpdateStatement = UpdateClause [WhereClause] [OrderByClause]
* UpdateClause = "UPDATE" RangeVariableDeclaration "SET" UpdateItem {"," UpdateItem}
* WhereClause = "WHERE" ConditionalExpression
* OrderByClause = "ORDER" "BY" OrderByItem {"," OrderByItem}
* LimitClause = "LIMIT" integer
* OffsetClause = "OFFSET" integer
*
* @return string $dql
*/
...
...
@@ -422,15 +425,13 @@ class QueryBuilder
*
* BNF:
*
* SelectStatement = [SelectClause] FromClause [WhereClause] [GroupByClause] [HavingClause] [OrderByClause]
[LimitClause] [OffsetClause]
* SelectStatement = [SelectClause] FromClause [WhereClause] [GroupByClause] [HavingClause] [OrderByClause]
* SelectClause = "SELECT" ["ALL" | "DISTINCT"] SelectExpression {"," SelectExpression}
* FromClause = "FROM" IdentificationVariableDeclaration {"," IdentificationVariableDeclaration}
* WhereClause = "WHERE" ConditionalExpression
* GroupByClause = "GROUP" "BY" GroupByItem {"," GroupByItem}
* HavingClause = "HAVING" ConditionalExpression
* OrderByClause = "ORDER" "BY" OrderByItem {"," OrderByItem}
* LimitClause = "LIMIT" integer
* OffsetClause = "OFFSET" integer
*
* @return string $dql
*/
...
...
lib/Doctrine/ORM/Tools/SchemaTool.php
View file @
e1f2b8ab
...
...
@@ -252,11 +252,12 @@ class SchemaTool
$joinTableColumns
=
array
();
$joinTableOptions
=
array
();
$joinTable
=
$mapping
->
getJoinTable
();
$constraint1
=
array
();
$constraint1
[
'tableName'
]
=
$joinTable
[
'name'
];
$constraint1
[
'foreignTable'
]
=
$class
->
getTableName
();
$constraint1
[
'local'
]
=
array
();
$constraint1
[
'foreign'
]
=
array
();
$constraint1
=
array
(
'tableName'
=>
$joinTable
[
'name'
],
'foreignTable'
=>
$class
->
getTableName
(),
'local'
=>
array
(),
'foreign'
=>
array
()
);
foreach
(
$joinTable
[
'joinColumns'
]
as
$joinColumn
)
{
$column
=
array
();
$column
[
'primary'
]
=
true
;
...
...
lib/Doctrine/ORM/UnitOfWork.php
View file @
e1f2b8ab
...
...
@@ -1552,8 +1552,7 @@ class UnitOfWork implements PropertyChangedListener
if
(
!
$assocMapping
->
isCascadeRemove
)
{
continue
;
}
$relatedEntities
=
$class
->
reflFields
[
$assocMapping
->
sourceFieldName
]
->
getValue
(
$entity
);
$relatedEntities
=
$class
->
reflFields
[
$assocMapping
->
sourceFieldName
]
->
getValue
(
$entity
);
if
(
$relatedEntities
instanceof
Collection
||
is_array
(
$relatedEntities
))
{
foreach
(
$relatedEntities
as
$relatedEntity
)
{
$this
->
_doRemove
(
$relatedEntity
,
$visited
);
...
...
@@ -1607,16 +1606,6 @@ class UnitOfWork implements PropertyChangedListener
{
$this
->
_orphanRemovals
[
spl_object_hash
(
$entity
)]
=
$entity
;
}
/*public function scheduleCollectionUpdate(PersistentCollection $coll)
{
$this->_collectionUpdates[] = $coll;
}*/
/*public function isCollectionScheduledForUpdate(PersistentCollection $coll)
{
//...
}*/
/**
* INTERNAL:
...
...
tests/Doctrine/Tests/ORM/Functional/AllTests.php
View file @
e1f2b8ab
...
...
@@ -38,6 +38,7 @@ class AllTests
$suite
->
addTestSuite
(
'Doctrine\Tests\ORM\Functional\ReferenceProxyTest'
);
$suite
->
addTestSuite
(
'Doctrine\Tests\ORM\Functional\LifecycleCallbackTest'
);
$suite
->
addTestSuite
(
'Doctrine\Tests\ORM\Functional\StandardEntityPersisterTest'
);
$suite
->
addTestSuite
(
'Doctrine\Tests\ORM\Functional\MappedSuperclassTest'
);
$suite
->
addTest
(
Locking\AllTests
::
suite
());
...
...
tests/Doctrine/Tests/ORM/Functional/MappedSuperclassTest.php
0 → 100644
View file @
e1f2b8ab
<?php
namespace
Doctrine\Tests\ORM\Functional
;
require_once
__DIR__
.
'/../../TestInit.php'
;
/**
* MappedSuperclassTest
*
* @author robo
*/
class
MappedSuperclassTest
extends
\Doctrine\Tests\OrmFunctionalTestCase
{
protected
function
setUp
()
{
parent
::
setUp
();
try
{
$this
->
_schemaTool
->
createSchema
(
array
(
$this
->
_em
->
getClassMetadata
(
'Doctrine\Tests\ORM\Functional\EntitySubClass'
),
));
}
catch
(
\Exception
$e
)
{
// Swallow all exceptions. We do not test the schema tool here.
}
}
public
function
testCRUD
()
{
$e
=
new
EntitySubClass
;
$e
->
setId
(
1
);
$e
->
setName
(
'Roman'
);
$e
->
setMapped1
(
42
);
$e
->
setMapped2
(
'bar'
);
$this
->
_em
->
persist
(
$e
);
$this
->
_em
->
flush
();
$this
->
_em
->
clear
();
$e2
=
$this
->
_em
->
find
(
'Doctrine\Tests\ORM\Functional\EntitySubClass'
,
1
);
$this
->
assertEquals
(
1
,
$e2
->
getId
());
$this
->
assertEquals
(
'Roman'
,
$e2
->
getName
());
$this
->
assertNull
(
$e2
->
getMappedRelated1
());
$this
->
assertEquals
(
42
,
$e2
->
getMapped1
());
$this
->
assertEquals
(
'bar'
,
$e2
->
getMapped2
());
}
}
/** @MappedSuperclass */
class
MappedSuperclassBase
{
/** @Column(type="integer") */
private
$mapped1
;
/** @Column(type="string") */
private
$mapped2
;
/**
* @OneToOne(targetEntity="MappedSuperclassRelated1")
* @JoinColumn(name="related1_id", referencedColumnName="id")
*/
private
$mappedRelated1
;
private
$transient
;
public
function
setMapped1
(
$val
)
{
$this
->
mapped1
=
$val
;
}
public
function
getMapped1
()
{
return
$this
->
mapped1
;
}
public
function
setMapped2
(
$val
)
{
$this
->
mapped2
=
$val
;
}
public
function
getMapped2
()
{
return
$this
->
mapped2
;
}
public
function
getMappedRelated1
()
{
return
$this
->
mappedRelated1
;
}
}
/** @Entity */
class
MappedSuperclassRelated1
{
/** @Id @Column(type="integer") */
private
$id
;
/** @Column(type="string") */
private
$name
;
}
/** @Entity */
class
EntitySubClass
extends
MappedSuperclassBase
{
/** @Id @Column(type="integer") */
private
$id
;
/** @Column(type="string") */
private
$name
;
public
function
setName
(
$name
)
{
$this
->
name
=
$name
;
}
public
function
getName
()
{
return
$this
->
name
;
}
public
function
setId
(
$id
)
{
$this
->
id
=
$id
;
}
public
function
getId
()
{
return
$this
->
id
;
}
}
tests/Doctrine/Tests/ORM/Mapping/AllTests.php
View file @
e1f2b8ab
...
...
@@ -24,6 +24,7 @@ class AllTests
$suite
->
addTestSuite
(
'Doctrine\Tests\ORM\Mapping\YamlDriverTest'
);
$suite
->
addTestSuite
(
'Doctrine\Tests\ORM\Mapping\ClassMetadataFactoryTest'
);
$suite
->
addTestSuite
(
'Doctrine\Tests\ORM\Mapping\ClassMetadataLoadEventTest'
);
$suite
->
addTestSuite
(
'Doctrine\Tests\ORM\Mapping\BasicInheritanceMappingTest'
);
return
$suite
;
}
...
...
tests/Doctrine/Tests/ORM/Mapping/BasicInheritanceMappingTest.php
0 → 100644
View file @
e1f2b8ab
<?php
namespace
Doctrine\Tests\ORM\Mapping
;
use
Doctrine\ORM\Mapping\ClassMetadataFactory
;
require_once
__DIR__
.
'/../../TestInit.php'
;
class
BasicInheritanceMappingTest
extends
\Doctrine\Tests\OrmTestCase
{
private
$_factory
;
protected
function
setUp
()
{
$this
->
_factory
=
new
ClassMetadataFactory
(
$this
->
_getTestEntityManager
());
}
/**
* @expectedException Doctrine\Common\DoctrineException
*/
public
function
testGetMetadataForTransientClassThrowsException
()
{
$this
->
_factory
->
getMetadataFor
(
'Doctrine\Tests\ORM\Mapping\TransientBaseClass'
);
}
public
function
testGetMetadataForSubclassWithTransientBaseClass
()
{
$class
=
$this
->
_factory
->
getMetadataFor
(
'Doctrine\Tests\ORM\Mapping\EntitySubClass'
);
$this
->
assertTrue
(
empty
(
$class
->
subClasses
));
$this
->
assertTrue
(
empty
(
$class
->
parentClasses
));
$this
->
assertTrue
(
isset
(
$class
->
fieldMappings
[
'id'
]));
$this
->
assertTrue
(
isset
(
$class
->
fieldMappings
[
'name'
]));
}
public
function
testGetMetadataForSubclassWithMappedSuperclass
()
{
$class
=
$this
->
_factory
->
getMetadataFor
(
'Doctrine\Tests\ORM\Mapping\EntitySubClass2'
);
$this
->
assertTrue
(
empty
(
$class
->
subClasses
));
$this
->
assertTrue
(
empty
(
$class
->
parentClasses
));
$this
->
assertTrue
(
isset
(
$class
->
fieldMappings
[
'mapped1'
]));
$this
->
assertTrue
(
isset
(
$class
->
fieldMappings
[
'mapped2'
]));
$this
->
assertTrue
(
isset
(
$class
->
fieldMappings
[
'id'
]));
$this
->
assertTrue
(
isset
(
$class
->
fieldMappings
[
'name'
]));
$this
->
assertFalse
(
isset
(
$class
->
fieldMappings
[
'mapped1'
][
'inherited'
]));
$this
->
assertFalse
(
isset
(
$class
->
fieldMappings
[
'mapped2'
][
'inherited'
]));
$this
->
assertFalse
(
isset
(
$class
->
fieldMappings
[
'transient'
]));
$this
->
assertTrue
(
empty
(
$class
->
inheritedAssociationFields
));
$this
->
assertTrue
(
isset
(
$class
->
associationMappings
[
'mappedRelated1'
]));
}
}
class
TransientBaseClass
{
private
$transient1
;
private
$transient2
;
}
/** @Entity */
class
EntitySubClass
extends
TransientBaseClass
{
/** @Id @Column(type="integer") */
private
$id
;
/** @Column(type="string") */
private
$name
;
}
/** @MappedSuperclass */
class
MappedSuperclassBase
{
/** @Column(type="integer") */
private
$mapped1
;
/** @Column(type="string") */
private
$mapped2
;
/**
* @OneToOne(targetEntity="MappedSuperclassRelated1")
* @JoinColumn(name="related1_id", referencedColumnName="id")
*/
private
$mappedRelated1
;
private
$transient
;
}
/** @Entity */
class
EntitySubClass2
extends
MappedSuperclassBase
{
/** @Id @Column(type="integer") */
private
$id
;
/** @Column(type="string") */
private
$name
;
}
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