1
0
mirror of synced 2025-01-18 06:21:40 +03:00

named native query inheritance

This commit is contained in:
Fabio B. Silva 2012-03-11 21:46:31 -03:00
parent 52c49b444e
commit f8b1915efd
5 changed files with 206 additions and 0 deletions

View File

@ -326,6 +326,14 @@ class ClassMetadataFactory implements ClassMetadataFactoryInterface
$this->addInheritedNamedQueries($class, $parent);
}
if ($parent && !empty ($parent->namedNativeQueries)) {
$this->addInheritedNamedNativeQueries($class, $parent);
}
if ($parent && !empty ($parent->sqlResultSetMappings)) {
$this->addInheritedSqlResultSetMappings($class, $parent);
}
$class->setParentClasses($visited);
if ($this->evm->hasListeners(Events::loadClassMetadata)) {
@ -466,6 +474,58 @@ class ClassMetadataFactory implements ClassMetadataFactoryInterface
}
}
/**
* Adds inherited named native queries to the subclass mapping.
*
* @since 2.3
* @param \Doctrine\ORM\Mapping\ClassMetadata $subClass
* @param \Doctrine\ORM\Mapping\ClassMetadata $parentClass
*/
private function addInheritedNamedNativeQueries(ClassMetadata $subClass, ClassMetadata $parentClass)
{
foreach ($parentClass->namedNativeQueries as $name => $query) {
if (!isset ($subClass->namedNativeQueries[$name])) {
$subClass->addNamedNativeQuery(array(
'name' => $query['name'],
'query' => $query['query'],
'isSelfClass' => $query['isSelfClass'],
'resultSetMapping' => $query['resultSetMapping'],
'resultClass' => $query['isSelfClass'] ? $subClass->name : $query['resultClass'],
));
}
}
}
/**
* Adds inherited sql result set mappings to the subclass mapping.
*
* @since 2.3
* @param \Doctrine\ORM\Mapping\ClassMetadata $subClass
* @param \Doctrine\ORM\Mapping\ClassMetadata $parentClass
*/
private function addInheritedSqlResultSetMappings(ClassMetadata $subClass, ClassMetadata $parentClass)
{
foreach ($parentClass->sqlResultSetMappings as $name => $mapping) {
if (!isset ($subClass->sqlResultSetMappings[$name])) {
$entities = array();
foreach ($mapping['entities'] as $entity) {
$entities[] = array(
'fields' => $entity['fields'],
'isSelfClass' => $entity['isSelfClass'],
'discriminatorColumn' => $entity['discriminatorColumn'],
'entityClass' => $entity['isSelfClass'] ? $subClass->name : $entity['entityClass'],
);
}
$subClass->addSqlResultSetMapping(array(
'name' => $mapping['name'],
'columns' => $mapping['columns'],
'entities' => $entities,
));
}
}
}
/**
* Completes the ID generator mapping. If "auto" is specified we choose the generator
* most appropriate for the targeted database platform.

View File

@ -1983,10 +1983,14 @@ class ClassMetadataInfo implements ClassMetadata
throw MappingException::missingQueryMapping($this->name, $queryMapping['name']);
}
$queryMapping['isSelfClass'] = false;
if (isset($queryMapping['resultClass'])) {
if($queryMapping['resultClass'] === '__CLASS__') {
$queryMapping['isSelfClass'] = true;
$queryMapping['resultClass'] = $this->name;
} else if (strlen($this->namespace) > 0 && strpos($queryMapping['resultClass'], '\\') === false) {
$queryMapping['resultClass'] = $this->namespace . '\\' . $queryMapping['resultClass'];
}
@ -2020,13 +2024,18 @@ class ClassMetadataInfo implements ClassMetadata
throw MappingException::missingResultSetMappingEntity($this->name, $resultMapping['name']);
}
$entityResult['isSelfClass'] = false;
if($entityResult['entityClass'] === '__CLASS__') {
$entityResult['isSelfClass'] = true;
$entityResult['entityClass'] = $this->name;
} else if (strlen($this->namespace) > 0 && strpos($entityResult['entityClass'], '\\') === false) {
$entityResult['entityClass'] = $this->namespace . '\\' . $entityResult['entityClass'];
}
$resultMapping['entities'][$key]['entityClass'] = ltrim($entityResult['entityClass'], '\\');
$resultMapping['entities'][$key]['isSelfClass'] = $entityResult['isSelfClass'];
if (isset($entityResult['fields'])) {
foreach ($entityResult['fields'] as $k => $field) {

View File

@ -12,6 +12,48 @@ namespace Doctrine\Tests\Models\Company;
* "flexible" = "CompanyFlexContract",
* "flexultra" = "CompanyFlexUltraContract"
* })
*
* @NamedNativeQueries({
* @NamedNativeQuery(
* name = "all-contracts",
* resultClass = "__CLASS__",
* query = "SELECT id, completed, discr FROM company_contracts"
* ),
* @NamedNativeQuery(
* name = "all",
* resultClass = "__CLASS__",
* query = "SELECT id, completed, discr FROM company_contracts"
* ),
* })
*
* @SqlResultSetMappings({
* @SqlResultSetMapping(
* name = "mapping-all-contracts",
* entities= {
* @EntityResult(
* entityClass = "__CLASS__",
* discriminatorColumn = "discr",
* fields = {
* @FieldResult("id"),
* @FieldResult("completed"),
* }
* )
* }
* ),
* @SqlResultSetMapping(
* name = "mapping-all",
* entities= {
* @EntityResult(
* entityClass = "__CLASS__",
* discriminatorColumn = "discr",
* fields = {
* @FieldResult("id"),
* @FieldResult("completed"),
* }
* )
* }
* ),
* })
*/
abstract class CompanyContract
{

View File

@ -3,6 +3,48 @@ namespace Doctrine\Tests\Models\Company;
/**
* @Entity
*
* @NamedNativeQueries({
* @NamedNativeQuery(
* name = "all",
* resultClass = "__CLASS__",
* query = "SELECT id, hoursWorked, discr FROM company_contracts"
* ),
* @NamedNativeQuery(
* name = "all-flex",
* resultClass = "CompanyFlexContract",
* query = "SELECT id, hoursWorked, discr FROM company_contracts"
* ),
* })
*
* @SqlResultSetMappings({
* @SqlResultSetMapping(
* name = "mapping-all-flex",
* entities= {
* @EntityResult(
* entityClass = "__CLASS__",
* discriminatorColumn = "discr",
* fields = {
* @FieldResult("id"),
* @FieldResult("hoursWorked"),
* }
* )
* }
* ),
* @SqlResultSetMapping(
* name = "mapping-all",
* entities= {
* @EntityResult(
* entityClass = "CompanyFlexContract",
* discriminatorColumn = "discr",
* fields = {
* @FieldResult("id"),
* @FieldResult("hoursWorked"),
* }
* )
* }
* ),
* })
*/
class CompanyFlexContract extends CompanyContract
{

View File

@ -648,4 +648,57 @@ class NativeQueryTest extends \Doctrine\Tests\OrmFunctionalTestCase
}
/**
* @group DDC-1663
*/
public function testNamedNativeQueryInheritance()
{
$contractMetadata = $this->_em->getClassMetadata('Doctrine\Tests\Models\Company\CompanyContract');
$flexMetadata = $this->_em->getClassMetadata('Doctrine\Tests\Models\Company\CompanyFlexContract');
$contractQueries = $contractMetadata->getNamedNativeQueries();
$flexQueries = $flexMetadata->getNamedNativeQueries();
$contractMappings = $contractMetadata->getSqlResultSetMappings();
$flexMappings = $flexMetadata->getSqlResultSetMappings();
// contract queries
$this->assertEquals('all-contracts', $contractQueries['all-contracts']['name']);
$this->assertEquals('Doctrine\Tests\Models\Company\CompanyContract', $contractQueries['all-contracts']['resultClass']);
$this->assertEquals('all', $contractQueries['all']['name']);
$this->assertEquals('Doctrine\Tests\Models\Company\CompanyContract', $contractQueries['all']['resultClass']);
// flex contract queries
$this->assertEquals('all-contracts', $flexQueries['all-contracts']['name']);
$this->assertEquals('Doctrine\Tests\Models\Company\CompanyFlexContract', $flexQueries['all-contracts']['resultClass']);
$this->assertEquals('all-flex', $flexQueries['all-flex']['name']);
$this->assertEquals('Doctrine\Tests\Models\Company\CompanyFlexContract', $flexQueries['all-flex']['resultClass']);
$this->assertEquals('all', $flexQueries['all']['name']);
$this->assertEquals('Doctrine\Tests\Models\Company\CompanyFlexContract', $flexQueries['all']['resultClass']);
// contract result mapping
$this->assertEquals('mapping-all-contracts', $contractMappings['mapping-all-contracts']['name']);
$this->assertEquals('Doctrine\Tests\Models\Company\CompanyContract', $contractMappings['mapping-all-contracts']['entities'][0]['entityClass']);
$this->assertEquals('mapping-all', $contractMappings['mapping-all']['name']);
$this->assertEquals('Doctrine\Tests\Models\Company\CompanyContract', $contractMappings['mapping-all-contracts']['entities'][0]['entityClass']);
// flex contract result mapping
$this->assertEquals('mapping-all-contracts', $flexMappings['mapping-all-contracts']['name']);
$this->assertEquals('Doctrine\Tests\Models\Company\CompanyFlexContract', $flexMappings['mapping-all-contracts']['entities'][0]['entityClass']);
$this->assertEquals('mapping-all', $flexMappings['mapping-all']['name']);
$this->assertEquals('Doctrine\Tests\Models\Company\CompanyFlexContract', $flexMappings['mapping-all']['entities'][0]['entityClass']);
$this->assertEquals('mapping-all-flex', $flexMappings['mapping-all-flex']['name']);
$this->assertEquals('Doctrine\Tests\Models\Company\CompanyFlexContract', $flexMappings['mapping-all-flex']['entities'][0]['entityClass']);
}
}