annotation driver and basic support
This commit is contained in:
parent
2b996128af
commit
bfc7986b20
@ -89,6 +89,22 @@ class EntityRepository implements ObjectRepository
|
||||
return $this->_em->createQuery($this->_class->getNamedQuery($queryName));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a native SQL query.
|
||||
*
|
||||
* @param string $queryName
|
||||
* @return NativeQuery
|
||||
*/
|
||||
public function createNativeNamedQuery($queryName)
|
||||
{
|
||||
$queryMapping = $this->_class->getNamedNativeQuery($queryName);
|
||||
$resultMapping = $this->_class->getSqlResultSetMapping($queryMapping['resultSetMapping']);
|
||||
$rsm = new Query\ResultSetMappingBuilder($this->_em);
|
||||
$rsm->addSqlResultSetMapping($resultMapping);
|
||||
|
||||
return $this->_em->createNativeQuery($queryMapping['query'], $rsm);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the repository, causing all managed entities to become detached.
|
||||
*/
|
||||
|
@ -1983,8 +1983,15 @@ class ClassMetadataInfo implements ClassMetadata
|
||||
throw MappingException::missingQueryMapping($this->name, $queryMapping['name']);
|
||||
}
|
||||
|
||||
if (isset($queryMapping['resultClass']) && $queryMapping['resultClass'] === '__CLASS__') {
|
||||
if (isset($queryMapping['resultClass'])) {
|
||||
|
||||
if($queryMapping['resultClass'] === '__CLASS__') {
|
||||
$queryMapping['resultClass'] = $this->name;
|
||||
} else if (strlen($this->namespace) > 0 && strpos($queryMapping['resultClass'], '\\') === false) {
|
||||
$queryMapping['resultClass'] = $this->namespace . '\\' . $queryMapping['resultClass'];
|
||||
}
|
||||
|
||||
$mapping['targetEntity'] = ltrim($queryMapping['resultClass'], '\\');
|
||||
}
|
||||
|
||||
$this->namedNativeQueries[$queryMapping['name']] = $queryMapping;
|
||||
@ -2013,9 +2020,13 @@ class ClassMetadataInfo implements ClassMetadata
|
||||
throw MappingException::missingResultSetMappingEntity($this->name, $resultMapping['name']);
|
||||
}
|
||||
|
||||
if ($entityResult['entityClass'] === '__CLASS__') {
|
||||
$resultMapping['entities'][$key]['entityClass'] = $this->name;
|
||||
if($entityResult['entityClass'] === '__CLASS__') {
|
||||
$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'], '\\');
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -204,15 +204,67 @@ class AnnotationDriver implements Driver
|
||||
$metadata->setPrimaryTable($primaryTable);
|
||||
}
|
||||
|
||||
// Evaluate NamedNativeQueries annotation
|
||||
if (isset($classAnnotations['Doctrine\ORM\Mapping\NamedNativeQueries'])) {
|
||||
$namedNativeQueriesAnnot = $classAnnotations['Doctrine\ORM\Mapping\NamedNativeQueries'];
|
||||
|
||||
foreach ($namedNativeQueriesAnnot->value as $namedNativeQuery) {
|
||||
$metadata->addNamedNativeQuery(array(
|
||||
'name' => $namedNativeQuery->name,
|
||||
'query' => $namedNativeQuery->query,
|
||||
'resultClass' => $namedNativeQuery->resultClass,
|
||||
'resultSetMapping' => $namedNativeQuery->resultSetMapping,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
// Evaluate SqlResultSetMappings annotation
|
||||
if (isset($classAnnotations['Doctrine\ORM\Mapping\SqlResultSetMappings'])) {
|
||||
$sqlResultSetMappingsAnnot = $classAnnotations['Doctrine\ORM\Mapping\SqlResultSetMappings'];
|
||||
|
||||
foreach ($sqlResultSetMappingsAnnot->value as $resultSetMapping) {
|
||||
$entities = array();
|
||||
foreach ($resultSetMapping->entities as $entityResultAnnot) {
|
||||
$entityResult = array(
|
||||
'fields' => array(),
|
||||
'entityClass' => $entityResultAnnot->entityClass,
|
||||
'discriminatorColumn' => $entityResultAnnot->discriminatorColumn,
|
||||
);
|
||||
|
||||
foreach ($entityResultAnnot->fields as $fieldResultAnnot) {
|
||||
$entityResult['fields'][] = array(
|
||||
'name' => $fieldResultAnnot->name,
|
||||
'column' => $fieldResultAnnot->column
|
||||
);
|
||||
}
|
||||
|
||||
$entities[] = $entityResult;
|
||||
}
|
||||
|
||||
$columns = array();
|
||||
foreach ($resultSetMapping->columns as $columnResultAnnot) {
|
||||
$columns[] = array(
|
||||
'name' => $resultSetMapping->name,
|
||||
);
|
||||
}
|
||||
|
||||
$metadata->addSqlResultSetMapping(array(
|
||||
'name' => $resultSetMapping->name,
|
||||
'entities' => $entities,
|
||||
'columns' => $columns
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
// Evaluate NamedQueries annotation
|
||||
if (isset($classAnnotations['Doctrine\ORM\Mapping\NamedQueries'])) {
|
||||
$namedQueriesAnnot = $classAnnotations['Doctrine\ORM\Mapping\NamedQueries'];
|
||||
$namedNativeQueriesAnnot = $classAnnotations['Doctrine\ORM\Mapping\NamedQueries'];
|
||||
|
||||
if (!is_array($namedQueriesAnnot->value)) {
|
||||
if (!is_array($namedNativeQueriesAnnot->value)) {
|
||||
throw new \UnexpectedValueException("@NamedQueries should contain an array of @NamedQuery annotations.");
|
||||
}
|
||||
|
||||
foreach ($namedQueriesAnnot->value as $namedQuery) {
|
||||
foreach ($namedNativeQueriesAnnot->value as $namedQuery) {
|
||||
if (!($namedQuery instanceof \Doctrine\ORM\Mapping\NamedQuery)) {
|
||||
throw new \UnexpectedValueException("@NamedQueries should contain an array of @NamedQuery annotations.");
|
||||
}
|
||||
|
@ -53,3 +53,10 @@ require_once __DIR__.'/../PreRemove.php';
|
||||
require_once __DIR__.'/../PostRemove.php';
|
||||
require_once __DIR__.'/../PostLoad.php';
|
||||
require_once __DIR__.'/../PreFlush.php';
|
||||
require_once __DIR__.'/../FieldResult.php';
|
||||
require_once __DIR__.'/../ColumnResult.php';
|
||||
require_once __DIR__.'/../EntityResult.php';
|
||||
require_once __DIR__.'/../NamedNativeQuery.php';
|
||||
require_once __DIR__.'/../NamedNativeQueries.php';
|
||||
require_once __DIR__.'/../SqlResultSetMapping.php';
|
||||
require_once __DIR__.'/../SqlResultSetMappings.php';
|
@ -46,7 +46,7 @@ final class EntityResult implements Annotation
|
||||
*
|
||||
* @var array<\Doctrine\ORM\Mapping\FieldResult>
|
||||
*/
|
||||
public $fields;
|
||||
public $fields = array();
|
||||
|
||||
/**
|
||||
* Specifies the column name of the column in the SELECT list that is used to determine the type of the entity instance.
|
||||
|
@ -36,5 +36,5 @@ final class NamedNativeQueries implements Annotation
|
||||
*
|
||||
* @var array<\Doctrine\ORM\Mapping\NamedNativeQuery>
|
||||
*/
|
||||
public $value;
|
||||
public $value = array();
|
||||
}
|
@ -27,7 +27,7 @@ namespace Doctrine\ORM\Mapping;
|
||||
* @since 2.3
|
||||
*
|
||||
* @Annotation
|
||||
* @Target("CLASS")
|
||||
* @Target("ANNOTATION")
|
||||
*/
|
||||
final class NamedNativeQuery implements Annotation
|
||||
{
|
||||
|
@ -27,7 +27,7 @@ namespace Doctrine\ORM\Mapping;
|
||||
* @since 2.3
|
||||
*
|
||||
* @Annotation
|
||||
* @Target("CLASS")
|
||||
* @Target("ANNOTATION")
|
||||
*/
|
||||
final class SqlResultSetMapping implements Annotation
|
||||
{
|
||||
@ -44,13 +44,13 @@ final class SqlResultSetMapping implements Annotation
|
||||
*
|
||||
* @var array<\Doctrine\ORM\Mapping\EntityResult>
|
||||
*/
|
||||
public $entities;
|
||||
public $entities = array();
|
||||
|
||||
/**
|
||||
* Specifies the result set mapping to scalar values.
|
||||
*
|
||||
* @var array<\Doctrine\ORM\Mapping\ColumnResult>
|
||||
*/
|
||||
public $columns;
|
||||
public $columns = array();
|
||||
|
||||
}
|
@ -36,5 +36,5 @@ final class SqlResultSetMappings implements Annotation
|
||||
*
|
||||
* @var array<\Doctrine\ORM\Mapping\SqlResultSetMapping>
|
||||
*/
|
||||
public $value;
|
||||
public $value = array();
|
||||
}
|
@ -106,4 +106,37 @@ class ResultSetMappingBuilder extends ResultSetMapping
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param array $mapping
|
||||
*/
|
||||
public function addSqlResultSetMapping(array $mapping)
|
||||
{
|
||||
if (isset($mapping['entities'])) {
|
||||
foreach ($mapping['entities'] as $key => $map) {
|
||||
$simpleName = $map['entityClass'];
|
||||
if (strpos($simpleName, '\\') !== false) {
|
||||
$simpleName = substr($simpleName, strrpos($simpleName, '\\') + 1);
|
||||
}
|
||||
|
||||
$className = $map['entityClass'];
|
||||
$alias = strtolower($simpleName[0]) . $key;
|
||||
|
||||
$this->addEntityResult($className, $alias);
|
||||
|
||||
if (isset($map['fields'])) {
|
||||
foreach ($map['fields'] as $field) {
|
||||
$this->addFieldResult($alias, $field['column'], $field['name'], $className);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($mapping['columns'])) {
|
||||
foreach ($mapping['columns'] as $map) {
|
||||
$this->addScalarResult($map['name'], $map['name']);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -8,6 +8,31 @@ namespace Doctrine\Tests\Models\CMS;
|
||||
* @author Roman S. Borschel
|
||||
* @Entity
|
||||
* @Table(name="cms_addresses")
|
||||
*
|
||||
* @NamedNativeQueries({
|
||||
* @NamedNativeQuery(
|
||||
* name = "find-all",
|
||||
* resultSetMapping = "mapping-find-all",
|
||||
* query = "SELECT id, country, city FROM cms_addresses"
|
||||
* )
|
||||
* })
|
||||
*
|
||||
* @SqlResultSetMappings({
|
||||
* @SqlResultSetMapping(
|
||||
* name = "mapping-find-all",
|
||||
* entities= {
|
||||
* @EntityResult(
|
||||
* entityClass = "CmsAddress",
|
||||
* fields = {
|
||||
* @FieldResult(name = "id", column="id"),
|
||||
* @FieldResult(name = "city", column="city"),
|
||||
* @FieldResult(name = "country", column="country")
|
||||
* }
|
||||
* )
|
||||
* }
|
||||
* )
|
||||
* })
|
||||
*
|
||||
*/
|
||||
class CmsAddress
|
||||
{
|
||||
|
@ -329,5 +329,41 @@ class NativeQueryTest extends \Doctrine\Tests\OrmFunctionalTestCase
|
||||
);
|
||||
$users = $query->getResult();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @group DDC-1663
|
||||
*/
|
||||
public function testBasicNativeNamedQuery()
|
||||
{
|
||||
$user = new CmsUser;
|
||||
$user->name = 'Fabio B. Silva';
|
||||
$user->username = 'FabioBatSilva';
|
||||
$user->status = 'dev';
|
||||
|
||||
$addr = new CmsAddress;
|
||||
$addr->country = 'Brazil';
|
||||
$addr->zip = 10827;
|
||||
$addr->city = 'São Paulo';
|
||||
|
||||
$user->setAddress($addr);
|
||||
|
||||
$this->_em->clear();
|
||||
$this->_em->persist($user);
|
||||
$this->_em->flush();
|
||||
|
||||
$this->_em->clear();
|
||||
|
||||
|
||||
$repository = $this->_em->getRepository('Doctrine\Tests\Models\CMS\CmsAddress');
|
||||
$query = $repository->createNativeNamedQuery('find-all');
|
||||
$result = $query->getResult();
|
||||
|
||||
$this->assertCount(1, $result);
|
||||
$this->assertInstanceOf('Doctrine\Tests\Models\CMS\CmsAddress', $result[0]);
|
||||
$this->assertEquals($addr->id, $result[0]->id);
|
||||
$this->assertEquals($addr->city, $result[0]->city);
|
||||
$this->assertEquals($addr->country, $result[0]->country);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -93,5 +93,70 @@ class ResultSetMappingTest extends \Doctrine\Tests\OrmTestCase
|
||||
$this->assertTrue($rms->hasParentAlias('p'));
|
||||
$this->assertTrue($rms->isMixedResult());
|
||||
}
|
||||
|
||||
/**
|
||||
* @group DDC-1663
|
||||
*/
|
||||
public function testAddSqlResultSetMapping()
|
||||
{
|
||||
$cm = new ClassMetadata('Doctrine\Tests\Models\CMS\CmsUser');
|
||||
$cm->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
|
||||
|
||||
$cm->addSqlResultSetMapping(array(
|
||||
'name' => 'find-all',
|
||||
'entities' => array(
|
||||
array(
|
||||
'entityClass' => '__CLASS__',
|
||||
'fields' => array(
|
||||
array(
|
||||
'name' => 'id',
|
||||
'column'=> 'user_id'
|
||||
),
|
||||
array(
|
||||
'name' => 'name',
|
||||
'column'=> 'user_name'
|
||||
)
|
||||
)
|
||||
),
|
||||
array(
|
||||
'entityClass' => 'CmsEmail',
|
||||
'fields' => array(
|
||||
array(
|
||||
'name' => 'id',
|
||||
'column'=> 'email_id'
|
||||
),
|
||||
array(
|
||||
'name' => 'email',
|
||||
'column'=> 'email_email'
|
||||
)
|
||||
)
|
||||
)
|
||||
),
|
||||
'columns' => array(
|
||||
array(
|
||||
'name' => 'scalarColumn'
|
||||
)
|
||||
)
|
||||
));
|
||||
|
||||
|
||||
$rsm = new \Doctrine\ORM\Query\ResultSetMappingBuilder($this->_em);
|
||||
$rsm->addSqlResultSetMapping($cm->getSqlResultSetMapping('find-all'));
|
||||
|
||||
$this->assertEquals('scalarColumn', $rsm->getScalarAlias('scalarColumn'));
|
||||
|
||||
$this->assertEquals('c0', $rsm->getEntityAlias('user_id'));
|
||||
$this->assertEquals('c0', $rsm->getEntityAlias('user_name'));
|
||||
$this->assertEquals('Doctrine\Tests\Models\CMS\CmsUser', $rsm->getClassName('c0'));
|
||||
$this->assertEquals('Doctrine\Tests\Models\CMS\CmsUser', $rsm->getDeclaringClass('user_id'));
|
||||
$this->assertEquals('Doctrine\Tests\Models\CMS\CmsUser', $rsm->getDeclaringClass('user_name'));
|
||||
|
||||
|
||||
$this->assertEquals('c1', $rsm->getEntityAlias('email_id'));
|
||||
$this->assertEquals('c1', $rsm->getEntityAlias('email_email'));
|
||||
$this->assertEquals('Doctrine\Tests\Models\CMS\CmsEmail', $rsm->getClassName('c1'));
|
||||
$this->assertEquals('Doctrine\Tests\Models\CMS\CmsEmail', $rsm->getDeclaringClass('email_id'));
|
||||
$this->assertEquals('Doctrine\Tests\Models\CMS\CmsEmail', $rsm->getDeclaringClass('email_email'));
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user