1
0
mirror of synced 2025-01-18 22:41:43 +03:00

Identity function support composite primary key

This commit is contained in:
Fabio B. Silva 2012-12-16 20:48:43 -02:00
parent 6f5948746e
commit 2e90cd9924
3 changed files with 96 additions and 12 deletions

View File

@ -20,9 +20,12 @@
namespace Doctrine\ORM\Query\AST\Functions;
use Doctrine\ORM\Query\Lexer;
use Doctrine\ORM\Query\Parser;
use Doctrine\ORM\Query\SqlWalker;
use Doctrine\ORM\Query\QueryException;
/**
* "IDENTITY" "(" SingleValuedAssociationPathExpression ")"
* "IDENTITY" "(" SingleValuedAssociationPathExpression {"," string} ")"
*
*
* @link www.doctrine-project.org
@ -32,35 +35,75 @@ use Doctrine\ORM\Query\Lexer;
*/
class IdentityFunction extends FunctionNode
{
/**
* @var \Doctrine\ORM\Query\AST\PathExpression
*/
public $pathExpression;
/**
* @override
* @var integer
*/
public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker)
{
$dqlAlias = $this->pathExpression->identificationVariable;
$assocField = $this->pathExpression->field;
public $fieldMapping;
$qComp = $sqlWalker->getQueryComponent($dqlAlias);
$class = $qComp['metadata'];
$assoc = $class->associationMappings[$assocField];
/**
* {@inheritdoc}
*/
public function getSql(SqlWalker $sqlWalker)
{
$platform = $sqlWalker->getEntityManager()->getConnection()->getDatabasePlatform();
$quoteStrategy = $sqlWalker->getEntityManager()->getConfiguration()->getQuoteStrategy();
$dqlAlias = $this->pathExpression->identificationVariable;
$assocField = $this->pathExpression->field;
$qComp = $sqlWalker->getQueryComponent($dqlAlias);
$class = $qComp['metadata'];
$assoc = $class->associationMappings[$assocField];
$targetEntity = $sqlWalker->getEntityManager()->getClassMetadata($assoc['targetEntity']);
$joinColumn = reset($assoc['joinColumns']);
if ($this->fieldMapping !== null) {
if ( ! isset($targetEntity->fieldMappings[$this->fieldMapping])) {
throw new QueryException(sprintf('Undefined reference field mapping "%s"', $this->fieldMapping));
}
$field = $targetEntity->fieldMappings[$this->fieldMapping];
$joinColumn = null;
foreach ($assoc['joinColumns'] as $mapping) {
if($mapping['referencedColumnName'] === $field['columnName']) {
$joinColumn = $mapping;
break;
}
}
if ($joinColumn === null) {
throw new QueryException(sprintf('Unable to resolve the reference field mapping "%s"', $this->fieldMapping));
}
}
$tableAlias = $sqlWalker->getSQLTableAlias($class->getTableName(), $dqlAlias);
$columName = $quoteStrategy->getJoinColumnName($joinColumn, $targetEntity, $platform);
return $tableAlias . '.' . reset($assoc['targetToSourceKeyColumns']);
return $tableAlias . '.' . $columName;
}
/**
* @override
* {@inheritdoc}
*/
public function parse(\Doctrine\ORM\Query\Parser $parser)
public function parse(Parser $parser)
{
$parser->match(Lexer::T_IDENTIFIER);
$parser->match(Lexer::T_OPEN_PARENTHESIS);
$this->pathExpression = $parser->SingleValuedAssociationPathExpression();
if ($parser->getLexer()->lookahead['type'] == Lexer::T_COMMA) {
$parser->match(Lexer::T_COMMA);
$parser->match(Lexer::T_STRING);
$this->fieldMapping = $parser->getLexer()->token['value'];
}
$parser->match(Lexer::T_CLOSE_PARENTHESIS);
}
}

View File

@ -72,6 +72,24 @@ class CompositePrimaryKeyTest extends \Doctrine\Tests\OrmFunctionalTestCase
$sql = $this->_em->createQuery($dql)->getSQL();
}
public function testIdentityFunctionWithCompositePrimaryKey()
{
$this->putGermanysBrandenburderTor();
$poi = $this->_em->find('Doctrine\Tests\Models\Navigation\NavPointOfInterest', array('lat' => 100, 'long' => 200));
$photo = new NavPhotos($poi, "asdf");
$this->_em->persist($photo);
$this->_em->flush();
$this->_em->clear();
$dql = "SELECT IDENTITY(p.poi, 'long') AS long, IDENTITY(p.poi, 'lat') AS lat FROM Doctrine\Tests\Models\Navigation\NavPhotos p";
$result = $this->_em->createQuery($dql)->getResult();
$this->assertCount(1, $result);
$this->assertEquals(200, $result[0]['long']);
$this->assertEquals(100, $result[0]['lat']);
}
public function testManyToManyCompositeRelation()
{
$this->putGermanysBrandenburderTor();

View File

@ -1261,6 +1261,29 @@ class SelectSqlGenerationTest extends \Doctrine\Tests\OrmTestCase
);
}
public function testIdentityFunctionWithCompositePrimaryKey()
{
$this->assertSqlGeneration(
"SELECT IDENTITY(p.poi, 'long') AS long FROM Doctrine\Tests\Models\Navigation\NavPhotos p",
"SELECT n0_.poi_long AS sclr0 FROM navigation_photos n0_"
);
$this->assertSqlGeneration(
"SELECT IDENTITY(p.poi, 'lat') AS lat FROM Doctrine\Tests\Models\Navigation\NavPhotos p",
"SELECT n0_.poi_lat AS sclr0 FROM navigation_photos n0_"
);
$this->assertSqlGeneration(
"SELECT IDENTITY(p.poi, 'long') AS long, IDENTITY(p.poi, 'lat') AS lat FROM Doctrine\Tests\Models\Navigation\NavPhotos p",
"SELECT n0_.poi_long AS sclr0, n0_.poi_lat AS sclr1 FROM navigation_photos n0_"
);
$this->assertInvalidSqlGeneration(
"SELECT IDENTITY(p.poi, 'invalid') AS invalid FROM Doctrine\Tests\Models\Navigation\NavPhotos p",
"Doctrine\ORM\Query\QueryException"
);
}
/**
* @group DDC-1339
*/