-
-
Save doctrinebot/bb26bf1d944b4e23b1d6 to your computer and use it in GitHub Desktop.
Attachments to Doctrine Jira Issue DDC-132 - https://github.com/doctrine/doctrine2/issues/1934
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Index: lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php | |
=================================================================== | |
--- lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php (revision 6700) | |
+++ lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php (working copy) | |
@@ -108,11 +108,14 @@ | |
if (($cached = $this->_cacheDriver->fetch($cacheKey)) !== false) { | |
$this->_loadedMetadata[$className] = $cached; | |
} else { | |
- $this->_loadMetadata($className); | |
- $this->_cacheDriver->save($cacheKey, $this->_loadedMetadata[$className], null); | |
+ $classes = $this->_loadMetadataHierarchy($className); | |
+ foreach ($classes as $class) { | |
+ $cacheKey = "$class\$CLASSMETADATA"; | |
+ $this->_cacheDriver->save($cacheKey, $this->_loadedMetadata[$class], null); | |
+ } | |
} | |
} else { | |
- $this->_loadMetadata($className); | |
+ $this->_loadMetadataHierarchy($className); | |
} | |
} | |
@@ -141,18 +144,85 @@ | |
{ | |
$this->_loadedMetadata[$className] = $class; | |
} | |
- | |
+ | |
+ protected function _loadMetadata($className, ClassMetadata $parent = null, $parentClasses = array()) | |
+ { | |
+ $class = $this->_newClassMetadataInstance($className); | |
+ | |
+ if ($parent) { | |
+ $class->setInheritanceType($parent->inheritanceType); | |
+ $class->setDiscriminatorColumn($parent->discriminatorColumn); | |
+ $class->setIdGeneratorType($parent->generatorType); | |
+ $this->_addInheritedFields($class, $parent); | |
+ $this->_addInheritedRelations($class, $parent); | |
+ $class->setIdentifier($parent->identifier); | |
+ $class->setVersioned($parent->isVersioned); | |
+ $class->setVersionField($parent->versionField); | |
+ $class->setDiscriminatorMap($parent->discriminatorMap); | |
+ $class->setResultColumnNames($parent->resultColumnNames); | |
+ } | |
+ | |
+ // Invoke driver | |
+ $this->_driver->loadMetadataForClass($className, $class); | |
+ | |
+ // Verify & complete identifier mapping | |
+ if ( ! $class->identifier && ! $class->isMappedSuperclass) { | |
+ throw MappingException::identifierRequired($className); | |
+ } | |
+ if ($parent && ! $parent->isMappedSuperclass) { | |
+ if ($parent->isIdGeneratorSequence()) { | |
+ $class->setSequenceGeneratorDefinition($parent->getSequenceGeneratorDefinition()); | |
+ } else if ($parent->isIdGeneratorTable()) { | |
+ $class->getTableGeneratorDefinition($parent->getTableGeneratorDefinition()); | |
+ } | |
+ if ($generatorType = $parent->generatorType) { | |
+ $class->setIdGeneratorType($generatorType); | |
+ } | |
+ if ($idGenerator = $parent->getIdGenerator()) { | |
+ $class->setIdGenerator($idGenerator); | |
+ } | |
+ } else { | |
+ $this->_completeIdGeneratorMapping($class); | |
+ } | |
+ | |
+ if ($parent && $parent->isInheritanceTypeSingleTable()) { | |
+ $class->setTableName($parent->getTableName()); | |
+ } | |
+ | |
+ $class->setParentClasses($parentClasses); | |
+ | |
+ if ($this->_evm->hasListeners(Events::loadClassMetadata)) { | |
+ $eventArgs = new \Doctrine\ORM\Event\LoadClassMetadataEventArgs($class); | |
+ $this->_evm->dispatchEvent(Events::loadClassMetadata, $eventArgs); | |
+ } | |
+ | |
+ if ( ! $class->isMappedSuperclass) { | |
+ $this->_generateStaticSql($class); | |
+ } | |
+ | |
+ if ($parent) { | |
+ foreach ($parentClasses as $parentClassName) { | |
+ $parentClass = $this->_loadedMetadata[$parentClassName]; | |
+ $parentClass->setResultColumnNames(array_merge($parentClass->resultColumnNames, $class->resultColumnNames)); | |
+ } | |
+ } | |
+ | |
+ $this->_loadedMetadata[$className] = $class; | |
+ | |
+ return $class; | |
+ } | |
+ | |
/** | |
- * Loads the metadata of the class in question and all it's ancestors whose metadata | |
- * is still not loaded. | |
+ * Loads the metadata of the class in question and all it's ancestors and children | |
+ * whose metadata is still not loaded. | |
* | |
- * @param string $name The name of the class for which the metadata should get loaded. | |
+ * @param string $className The name of the class for which the metadata should get loaded. | |
* @param array $tables The metadata collection to which the loaded metadata is added. | |
*/ | |
- protected function _loadMetadata($name) | |
+ protected function _loadMetadataHierarchy($className) | |
{ | |
// Collect parent classes, ignoring transient (not-mapped) classes. | |
- $parentClass = $name; | |
+ $parentClass = $className; | |
$parentClasses = array(); | |
while ($parentClass = get_parent_class($parentClass)) { | |
if ( ! $this->_driver->isTransient($parentClass)) { | |
@@ -160,88 +230,34 @@ | |
} | |
} | |
$parentClasses = array_reverse($parentClasses); | |
- $parentClasses[] = $name; | |
+ $parentClasses[] = $className; | |
// Move down the hierarchy of parent classes, starting from the topmost class | |
$parent = null; | |
$visited = array(); | |
- foreach ($parentClasses as $className) { | |
- if (isset($this->_loadedMetadata[$className])) { | |
- $parent = $this->_loadedMetadata[$className]; | |
+ foreach ($parentClasses as $parentClass) { | |
+ if (isset($this->_loadedMetadata[$parentClass])) { | |
+ $parent = $this->_loadedMetadata[$parentClass]; | |
if ( ! $parent->isMappedSuperclass) { | |
- array_unshift($visited, $className); | |
+ array_unshift($visited, $parentClass); | |
} | |
continue; | |
} | |
- | |
- $class = $this->_newClassMetadataInstance($className); | |
- if ($parent) { | |
- $class->setInheritanceType($parent->inheritanceType); | |
- $class->setDiscriminatorColumn($parent->discriminatorColumn); | |
- $class->setIdGeneratorType($parent->generatorType); | |
- $this->_addInheritedFields($class, $parent); | |
- $this->_addInheritedRelations($class, $parent); | |
- $class->setIdentifier($parent->identifier); | |
- $class->setVersioned($parent->isVersioned); | |
- $class->setVersionField($parent->versionField); | |
- $class->setDiscriminatorMap($parent->discriminatorMap); | |
- $class->setResultColumnNames($parent->resultColumnNames); | |
- } | |
+ $class = $this->_loadMetadata($parentClass, $parent, $visited); | |
- // Invoke driver | |
- $this->_driver->loadMetadataForClass($className, $class); | |
- | |
- // Verify & complete identifier mapping | |
- if ( ! $class->identifier && ! $class->isMappedSuperclass) { | |
- throw MappingException::identifierRequired($className); | |
+ foreach ($class->subClasses as $subClass) { | |
+ $this->_loadMetadataHierarchy($subClass); | |
} | |
- if ($parent && ! $parent->isMappedSuperclass) { | |
- if ($parent->isIdGeneratorSequence()) { | |
- $class->setSequenceGeneratorDefinition($parent->getSequenceGeneratorDefinition()); | |
- } else if ($parent->isIdGeneratorTable()) { | |
- $class->getTableGeneratorDefinition($parent->getTableGeneratorDefinition()); | |
- } | |
- if ($generatorType = $parent->generatorType) { | |
- $class->setIdGeneratorType($generatorType); | |
- } | |
- if ($idGenerator = $parent->getIdGenerator()) { | |
- $class->setIdGenerator($idGenerator); | |
- } | |
- } else { | |
- $this->_completeIdGeneratorMapping($class); | |
- } | |
- | |
- if ($parent && $parent->isInheritanceTypeSingleTable()) { | |
- $class->setTableName($parent->getTableName()); | |
- } | |
- $class->setParentClasses($visited); | |
+ $parent = $class; | |
- if ($this->_evm->hasListeners(Events::loadClassMetadata)) { | |
- $eventArgs = new \Doctrine\ORM\Event\LoadClassMetadataEventArgs($class); | |
- $this->_evm->dispatchEvent(Events::loadClassMetadata, $eventArgs); | |
- } | |
- | |
if ( ! $class->isMappedSuperclass) { | |
- $this->_generateStaticSql($class); | |
+ array_unshift($visited, $parentClass); | |
} | |
- | |
- if ($parent) { | |
- foreach ($visited as $parentClassName) { | |
- $parentClass = $this->_loadedMetadata[$parentClassName]; | |
- $parentClass->setResultColumnNames(array_merge($parentClass->resultColumnNames, $class->resultColumnNames)); | |
- } | |
- } | |
- | |
- $this->_loadedMetadata[$className] = $class; | |
- | |
- $parent = $class; | |
- | |
- if ( ! $class->isMappedSuperclass) { | |
- array_unshift($visited, $className); | |
- } | |
} | |
+ | |
+ return $visited; | |
} | |
/** | |
Index: tests/Doctrine/Tests/ORM/Mapping/ClassMetadataFactoryTest.php | |
=================================================================== | |
--- tests/Doctrine/Tests/ORM/Mapping/ClassMetadataFactoryTest.php (revision 6700) | |
+++ tests/Doctrine/Tests/ORM/Mapping/ClassMetadataFactoryTest.php (working copy) | |
@@ -14,6 +14,50 @@ | |
class ClassMetadataFactoryTest extends \Doctrine\Tests\OrmTestCase | |
{ | |
+ public function testClassHierarchyLoaded() | |
+ { | |
+ $reader = new \Doctrine\Common\Annotations\AnnotationReader(new \Doctrine\Common\Cache\ArrayCache); | |
+ $reader->setDefaultAnnotationNamespace('Doctrine\ORM\Mapping\\'); | |
+ $driver = new \Doctrine\ORM\Mapping\Driver\AnnotationDriver($reader); | |
+ $em = $this->_createEntityManager($driver); | |
+ $cmf = new \Doctrine\ORM\Mapping\ClassMetadataFactory($em); | |
+ | |
+ $classA = $cmf->getMetadataFor('Doctrine\Tests\ORM\Mapping\HierarchyTestClassA'); | |
+ $this->assertTrue($cmf->hasMetadataFor('Doctrine\Tests\ORM\Mapping\HierarchyTestClassA')); | |
+ $this->assertTrue($cmf->hasMetadataFor('Doctrine\Tests\ORM\Mapping\HierarchyTestClassB')); | |
+ $this->assertTrue($cmf->hasMetadataFor('Doctrine\Tests\ORM\Mapping\HierarchyTestClassC')); | |
+ $this->assertTrue($cmf->hasMetadataFor('Doctrine\Tests\ORM\Mapping\HierarchyTestClassD')); | |
+ | |
+ $classA = $cmf->getMetadataFor('Doctrine\Tests\ORM\Mapping\HierarchyTestClassA'); | |
+ $classB = $cmf->getMetadataFor('Doctrine\Tests\ORM\Mapping\HierarchyTestClassB'); | |
+ $classC = $cmf->getMetadataFor('Doctrine\Tests\ORM\Mapping\HierarchyTestClassC'); | |
+ $classD = $cmf->getMetadataFor('Doctrine\Tests\ORM\Mapping\HierarchyTestClassD'); | |
+ | |
+ /** | |
+ * The resultColumNames are not correct currently. | |
+ * It does not cause problems yet but they are for sure wrong | |
+ */ | |
+ | |
+ /* | |
+ $aResultColumnNames = array( | |
+ 'id' => 'id', | |
+ 'a' => 'a', | |
+ 'b' => 'b', | |
+ 'c' => 'c' | |
+ ); | |
+ $this->assertEquals($aResultColumnNames, $classA->resultColumnNames); | |
+ | |
+ $bResultColumnNames = array(); | |
+ $this->assertEquals($bResultColumnNames, $classB->resultColumnNames); | |
+ | |
+ $cResultColumnNames = array(); | |
+ $this->assertEquals($cResultColumnNames, $classC->resultColumnNames); | |
+ | |
+ $dResultColumnNames = array(); | |
+ $this->assertEquals($dResultColumnNames, $classD->resultColumnNames); | |
+ */ | |
+ } | |
+ | |
public function testGetMetadataForSingleClass() | |
{ | |
$mockDriver = new MetadataDriverMock(); | |
@@ -130,3 +174,77 @@ | |
private $other; | |
private $association; | |
} | |
+ | |
+/** | |
+ * @Entity | |
+ * @InheritanceType("JOINED") | |
+ * @DiscriminatorColumn(name="discr", type="string") | |
+ * @DiscriminatorMap({"b" = "HierarchyTestClassB", "c" = "HierarchyTestClassC"}) | |
+ */ | |
+class HierarchyTestClassA | |
+{ | |
+ /** | |
+ * @Id @Column(type="integer") | |
+ * @GeneratedValue(strategy="AUTO") | |
+ */ | |
+ private $id; | |
+ | |
+ /** | |
+ * @Column(type="string", length=50) | |
+ */ | |
+ private $a; | |
+} | |
+ | |
+/** | |
+ * @Entity | |
+ */ | |
+class HierarchyTestClassB extends HierarchyTestClassA | |
+{ | |
+ /** | |
+ * @Id @Column(type="integer") | |
+ * @GeneratedValue(strategy="AUTO") | |
+ */ | |
+ private $id; | |
+ | |
+ /** | |
+ * @Column(type="string", length=50) | |
+ */ | |
+ private $b; | |
+} | |
+ | |
+/** | |
+ * @Entity | |
+ * @InheritanceType("JOINED") | |
+ * @DiscriminatorColumn(name="discr", type="string") | |
+ * @DiscriminatorMap({"d" = "HierarchyTestClassD"}) | |
+ */ | |
+class HierarchyTestClassC extends HierarchyTestClassA | |
+{ | |
+ /** | |
+ * @Id @Column(type="integer") | |
+ * @GeneratedValue(strategy="AUTO") | |
+ */ | |
+ private $id; | |
+ | |
+ /** | |
+ * @Column(type="string", length=50) | |
+ */ | |
+ private $c; | |
+} | |
+ | |
+/** | |
+ * @Entity | |
+ */ | |
+class HierarchyTestClassD extends HierarchyTestClassC | |
+{ | |
+ /** | |
+ * @Id @Column(type="integer") | |
+ * @GeneratedValue(strategy="AUTO") | |
+ */ | |
+ private $id; | |
+ | |
+ /** | |
+ * @Column(type="string", length=50) | |
+ */ | |
+ private $d; | |
+} | |
\ No newline at end of file | |
Index: tests/Doctrine/Tests/TestUtil.php | |
=================================================================== | |
--- tests/Doctrine/Tests/TestUtil.php (revision 6700) | |
+++ tests/Doctrine/Tests/TestUtil.php (working copy) | |
@@ -56,7 +56,7 @@ | |
// Connect to tmpdb in order to drop and create the real test db. | |
$tmpConn = \Doctrine\DBAL\DriverManager::getConnection($tmpDbParams); | |
$realConn = \Doctrine\DBAL\DriverManager::getConnection($realDbParams); | |
- | |
+ | |
$dbname = $realConn->getDatabase(); | |
$realConn->close(); | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment