Merge pull request #890 from deeky666/DBAL-563
[DBAL-563] Add general IDENTITY generator type support for sequence emulating platforms
This commit is contained in:
commit
a7b9140d2f
@ -448,17 +448,15 @@ class ClassMetadataFactory extends AbstractClassMetadataFactory
|
||||
// Create & assign an appropriate ID generator instance
|
||||
switch ($class->generatorType) {
|
||||
case ClassMetadata::GENERATOR_TYPE_IDENTITY:
|
||||
// For PostgreSQL IDENTITY (SERIAL) we need a sequence name. It defaults to
|
||||
// <table>_<column>_seq in PostgreSQL for SERIAL columns.
|
||||
// Not pretty but necessary and the simplest solution that currently works.
|
||||
$sequenceName = null;
|
||||
$fieldName = $class->identifier ? $class->getSingleIdentifierFieldName() : null;
|
||||
|
||||
if ($this->targetPlatform instanceof Platforms\PostgreSqlPlatform) {
|
||||
$columnName = $class->getSingleIdentifierColumnName();
|
||||
$quoted = isset($class->fieldMappings[$fieldName]['quoted']) || isset($class->table['quoted']);
|
||||
$sequenceName = $class->getTableName() . '_' . $columnName . '_seq';
|
||||
$definition = array(
|
||||
// Platforms that do not have native IDENTITY support need a sequence to emulate this behaviour.
|
||||
if ($this->targetPlatform->usesSequenceEmulatedIdentityColumns()) {
|
||||
$columnName = $class->getSingleIdentifierColumnName();
|
||||
$quoted = isset($class->fieldMappings[$fieldName]['quoted']) || isset($class->table['quoted']);
|
||||
$sequenceName = $this->targetPlatform->getIdentitySequenceName($class->getTableName(), $columnName);
|
||||
$definition = array(
|
||||
'sequenceName' => $this->targetPlatform->fixSchemaElementName($sequenceName)
|
||||
);
|
||||
|
||||
@ -466,7 +464,11 @@ class ClassMetadataFactory extends AbstractClassMetadataFactory
|
||||
$definition['quoted'] = true;
|
||||
}
|
||||
|
||||
$sequenceName = $this->em->getConfiguration()->getQuoteStrategy()->getSequenceName($definition, $class, $this->targetPlatform);
|
||||
$sequenceName = $this
|
||||
->em
|
||||
->getConfiguration()
|
||||
->getQuoteStrategy()
|
||||
->getSequenceName($definition, $class, $this->targetPlatform);
|
||||
}
|
||||
|
||||
$generator = ($fieldName && $class->fieldMappings[$fieldName]['type'] === 'bigint')
|
||||
|
@ -1,53 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\ORM\Functional;
|
||||
|
||||
use Doctrine\ORM\Event\PreUpdateEventArgs;
|
||||
|
||||
require_once __DIR__ . '/../../TestInit.php';
|
||||
|
||||
class PostgreSQLIdentityStrategyTest extends \Doctrine\Tests\OrmFunctionalTestCase
|
||||
{
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
if ($this->_em->getConnection()->getDatabasePlatform()->getName() != 'postgresql') {
|
||||
$this->markTestSkipped('This test is special to the PostgreSQL IDENTITY key generation strategy.');
|
||||
} else {
|
||||
try {
|
||||
$this->_schemaTool->createSchema(array(
|
||||
$this->_em->getClassMetadata('Doctrine\Tests\ORM\Functional\PostgreSQLIdentityEntity'),
|
||||
));
|
||||
} catch (\Exception $e) {
|
||||
// Swallow all exceptions. We do not test the schema tool here.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected function tearDown() {
|
||||
parent::tearDown();
|
||||
// drop sequence manually due to dependency
|
||||
$this->_em->getConnection()->exec('DROP SEQUENCE postgresqlidentityentity_id_seq CASCADE');
|
||||
}
|
||||
|
||||
public function testPreSavePostSaveCallbacksAreInvoked()
|
||||
{
|
||||
$entity = new PostgreSQLIdentityEntity();
|
||||
$entity->setValue('hello');
|
||||
$this->_em->persist($entity);
|
||||
$this->_em->flush();
|
||||
$this->assertTrue(is_numeric($entity->getId()));
|
||||
$this->assertTrue($entity->getId() > 0);
|
||||
$this->assertTrue($this->_em->contains($entity));
|
||||
}
|
||||
}
|
||||
|
||||
/** @Entity */
|
||||
class PostgreSQLIdentityEntity {
|
||||
/** @Id @Column(type="integer") @GeneratedValue(strategy="IDENTITY") */
|
||||
private $id;
|
||||
/** @Column(type="string") */
|
||||
private $value;
|
||||
public function getId() {return $this->id;}
|
||||
public function getValue() {return $this->value;}
|
||||
public function setValue($value) {$this->value = $value;}
|
||||
}
|
@ -0,0 +1,86 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\ORM\Functional;
|
||||
|
||||
use Doctrine\DBAL\Schema\Sequence;
|
||||
|
||||
require_once __DIR__ . '/../../TestInit.php';
|
||||
|
||||
class SequenceEmulatedIdentityStrategyTest extends \Doctrine\Tests\OrmFunctionalTestCase
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp()
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
if ( ! $this->_em->getConnection()->getDatabasePlatform()->usesSequenceEmulatedIdentityColumns()) {
|
||||
$this->markTestSkipped(
|
||||
'This test is special to platforms emulating IDENTITY key generation strategy through sequences.'
|
||||
);
|
||||
} else {
|
||||
try {
|
||||
$this->_schemaTool->createSchema(
|
||||
array($this->_em->getClassMetadata('Doctrine\Tests\ORM\Functional\SequenceEmulatedIdentityEntity'))
|
||||
);
|
||||
} catch (\Exception $e) {
|
||||
// Swallow all exceptions. We do not test the schema tool here.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function tearDown()
|
||||
{
|
||||
parent::tearDown();
|
||||
|
||||
$connection = $this->_em->getConnection();
|
||||
$platform = $connection->getDatabasePlatform();
|
||||
|
||||
// drop sequence manually due to dependency
|
||||
$connection->exec(
|
||||
$platform->getDropSequenceSQL(
|
||||
new Sequence($platform->getIdentitySequenceName('seq_identity', 'id'))
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
public function testPreSavePostSaveCallbacksAreInvoked()
|
||||
{
|
||||
$entity = new SequenceEmulatedIdentityEntity();
|
||||
$entity->setValue('hello');
|
||||
$this->_em->persist($entity);
|
||||
$this->_em->flush();
|
||||
$this->assertTrue(is_numeric($entity->getId()));
|
||||
$this->assertTrue($entity->getId() > 0);
|
||||
$this->assertTrue($this->_em->contains($entity));
|
||||
}
|
||||
}
|
||||
|
||||
/** @Entity @Table(name="seq_identity") */
|
||||
class SequenceEmulatedIdentityEntity
|
||||
{
|
||||
/** @Id @Column(type="integer") @GeneratedValue(strategy="IDENTITY") */
|
||||
private $id;
|
||||
|
||||
/** @Column(type="string") */
|
||||
private $value;
|
||||
|
||||
public function getId()
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function getValue()
|
||||
{
|
||||
return $this->value;
|
||||
}
|
||||
|
||||
public function setValue($value)
|
||||
{
|
||||
$this->value = $value;
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user