Skip to content

Commit a7b9140

Browse files
Merge pull request #890 from deeky666/DBAL-563
[DBAL-563] Add general IDENTITY generator type support for sequence emulating platforms
2 parents 58c57c5 + 337857d commit a7b9140

File tree

3 files changed

+97
-62
lines changed

3 files changed

+97
-62
lines changed

lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php

+11-9
Original file line numberDiff line numberDiff line change
@@ -448,25 +448,27 @@ private function completeIdGeneratorMapping(ClassMetadataInfo $class)
448448
// Create & assign an appropriate ID generator instance
449449
switch ($class->generatorType) {
450450
case ClassMetadata::GENERATOR_TYPE_IDENTITY:
451-
// For PostgreSQL IDENTITY (SERIAL) we need a sequence name. It defaults to
452-
// <table>_<column>_seq in PostgreSQL for SERIAL columns.
453-
// Not pretty but necessary and the simplest solution that currently works.
454451
$sequenceName = null;
455452
$fieldName = $class->identifier ? $class->getSingleIdentifierFieldName() : null;
456453

457-
if ($this->targetPlatform instanceof Platforms\PostgreSqlPlatform) {
458-
$columnName = $class->getSingleIdentifierColumnName();
459-
$quoted = isset($class->fieldMappings[$fieldName]['quoted']) || isset($class->table['quoted']);
460-
$sequenceName = $class->getTableName() . '_' . $columnName . '_seq';
461-
$definition = array(
454+
// Platforms that do not have native IDENTITY support need a sequence to emulate this behaviour.
455+
if ($this->targetPlatform->usesSequenceEmulatedIdentityColumns()) {
456+
$columnName = $class->getSingleIdentifierColumnName();
457+
$quoted = isset($class->fieldMappings[$fieldName]['quoted']) || isset($class->table['quoted']);
458+
$sequenceName = $this->targetPlatform->getIdentitySequenceName($class->getTableName(), $columnName);
459+
$definition = array(
462460
'sequenceName' => $this->targetPlatform->fixSchemaElementName($sequenceName)
463461
);
464462

465463
if ($quoted) {
466464
$definition['quoted'] = true;
467465
}
468466

469-
$sequenceName = $this->em->getConfiguration()->getQuoteStrategy()->getSequenceName($definition, $class, $this->targetPlatform);
467+
$sequenceName = $this
468+
->em
469+
->getConfiguration()
470+
->getQuoteStrategy()
471+
->getSequenceName($definition, $class, $this->targetPlatform);
470472
}
471473

472474
$generator = ($fieldName && $class->fieldMappings[$fieldName]['type'] === 'bigint')

tests/Doctrine/Tests/ORM/Functional/PostgreSQLIdentityStrategyTest.php

-53
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
<?php
2+
3+
namespace Doctrine\Tests\ORM\Functional;
4+
5+
use Doctrine\DBAL\Schema\Sequence;
6+
7+
require_once __DIR__ . '/../../TestInit.php';
8+
9+
class SequenceEmulatedIdentityStrategyTest extends \Doctrine\Tests\OrmFunctionalTestCase
10+
{
11+
/**
12+
* {@inheritdoc}
13+
*/
14+
protected function setUp()
15+
{
16+
parent::setUp();
17+
18+
if ( ! $this->_em->getConnection()->getDatabasePlatform()->usesSequenceEmulatedIdentityColumns()) {
19+
$this->markTestSkipped(
20+
'This test is special to platforms emulating IDENTITY key generation strategy through sequences.'
21+
);
22+
} else {
23+
try {
24+
$this->_schemaTool->createSchema(
25+
array($this->_em->getClassMetadata('Doctrine\Tests\ORM\Functional\SequenceEmulatedIdentityEntity'))
26+
);
27+
} catch (\Exception $e) {
28+
// Swallow all exceptions. We do not test the schema tool here.
29+
}
30+
}
31+
}
32+
33+
/**
34+
* {@inheritdoc}
35+
*/
36+
protected function tearDown()
37+
{
38+
parent::tearDown();
39+
40+
$connection = $this->_em->getConnection();
41+
$platform = $connection->getDatabasePlatform();
42+
43+
// drop sequence manually due to dependency
44+
$connection->exec(
45+
$platform->getDropSequenceSQL(
46+
new Sequence($platform->getIdentitySequenceName('seq_identity', 'id'))
47+
)
48+
);
49+
}
50+
51+
public function testPreSavePostSaveCallbacksAreInvoked()
52+
{
53+
$entity = new SequenceEmulatedIdentityEntity();
54+
$entity->setValue('hello');
55+
$this->_em->persist($entity);
56+
$this->_em->flush();
57+
$this->assertTrue(is_numeric($entity->getId()));
58+
$this->assertTrue($entity->getId() > 0);
59+
$this->assertTrue($this->_em->contains($entity));
60+
}
61+
}
62+
63+
/** @Entity @Table(name="seq_identity") */
64+
class SequenceEmulatedIdentityEntity
65+
{
66+
/** @Id @Column(type="integer") @GeneratedValue(strategy="IDENTITY") */
67+
private $id;
68+
69+
/** @Column(type="string") */
70+
private $value;
71+
72+
public function getId()
73+
{
74+
return $this->id;
75+
}
76+
77+
public function getValue()
78+
{
79+
return $this->value;
80+
}
81+
82+
public function setValue($value)
83+
{
84+
$this->value = $value;
85+
}
86+
}

0 commit comments

Comments
 (0)