Commit 79e894b4 authored by Benjamin Eberlei's avatar Benjamin Eberlei

[DDC-1657] Prevent autoincrement sequences from creating DROP SEQUENCE...

[DDC-1657] Prevent autoincrement sequences from creating DROP SEQUENCE statements because of old/new schema missmatch.
parent 78dbf289
......@@ -110,7 +110,12 @@ class Comparator
}
foreach ($fromSchema->getSequences() as $sequence) {
if ($this->isAutoIncrementSequenceInSchema($toSchema, $sequence)) {
continue;
}
$sequenceName = $sequence->getShortestName($fromSchema->getName());
if ( ! $toSchema->hasSequence($sequenceName)) {
$diff->removedSequences[] = $sequence;
}
......@@ -119,6 +124,17 @@ class Comparator
return $diff;
}
private function isAutoIncrementSequenceInSchema($schema, $sequence)
{
foreach ($schema->getTables() as $table) {
if ($sequence->isAutoIncrementsFor($table)) {
return true;
}
}
return false;
}
/**
*
* @param Sequence $sequence1
......
......@@ -87,6 +87,7 @@ class Schema extends AbstractAsset
foreach ($tables as $table) {
$this->_addTable($table);
}
foreach ($sequences as $sequence) {
$this->_addSequence($sequence);
}
......
<?php
/*
* $Id$
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
......@@ -77,6 +75,41 @@ class Sequence extends AbstractAsset
$this->_initialValue = (is_numeric($initialValue))?$initialValue:1;
}
/**
* Check if this sequence is an autoincrement sequence for a given table.
*
* This is used inside the comparator to not report sequences as missing,
* when the "from" schema implicitly creates the sequences.
*
* @param Table $table
*
* @return bool
*/
public function isAutoIncrementsFor(Table $table)
{
if ( ! $table->hasPrimaryKey()) {
return false;
}
$pkColumns = $table->getPrimaryKey()->getColumns();
if (count($pkColumns) != 1) {
return false;
}
$column = $table->getColumn($pkColumns[0]);
if ( ! $column->getAutoincrement()) {
return false;
}
$sequenceName = $this->getShortestName($table->getNamespaceName());
$tableName = $table->getShortestName($table->getNamespaceName());
$tableSequenceName = sprintf('%s_%s_seq', $tableName, $pkColumns[0]);
return $tableSequenceName === $sequenceName;
}
/**
* @param Visitor $visitor
*/
......
......@@ -565,6 +565,14 @@ class Table extends AbstractAsset
return $this->getIndex($this->_primaryKeyName);
}
public function getPrimaryKeyColumns()
{
if ( ! $this->hasPrimaryKey()) {
throw new DBALException("Table " . $this->getName() . " has no primary key.");
}
return $this->getPrimaryKey()->getColumns();
}
/**
* Check if this table has a primary key.
*
......
......@@ -759,6 +759,28 @@ class ComparatorTest extends \PHPUnit_Framework_TestCase
$this->assertEquals(new SchemaDiff(), $c->compare($oldSchema, $newSchema));
}
/**
* @group DDC-1657
*/
public function testAutoIncremenetSequences()
{
$oldSchema = new Schema();
$table = $oldSchema->createTable("foo");
$table->addColumn("id", "integer", array("autoincrement" => true));
$table->setPrimaryKey(array("id"));
$oldSchema->createSequence("foo_id_seq");
$newSchema = new Schema();
$table = $newSchema->createTable("foo");
$table->addColumn("id", "integer", array("autoincrement" => true));
$table->setPrimaryKey(array("id"));
$c = new Comparator();
$diff = $c->compare($oldSchema, $newSchema);
$this->assertCount(0, $diff->removedSequences);
}
/**
* @param SchemaDiff $diff
* @param int $newTableCount
......
<?php
namespace Doctrine\Tests\DBAL\Schema;
use Doctrine\DBAL\Schema\Table;
use Doctrine\DBAL\Schema\Sequence;
class SequenceTest extends \Doctrine\Tests\DbalTestCase
{
/**
* @group DDC-1657
*/
public function testIsAutoincrementFor()
{
$table = new Table("foo");
$table->addColumn("id", "integer", array("autoincrement" => true));
$table->setPrimaryKey(array("id"));
$sequence = new Sequence("foo_id_seq");
$sequence2 = new Sequence("bar_id_seq");
$sequence3 = new Sequence("other.foo_id_seq");
$this->assertTrue($sequence->isAutoIncrementsFor($table));
$this->assertFalse($sequence2->isAutoIncrementsFor($table));
$this->assertFalse($sequence3->isAutoIncrementsFor($table));
}
}
......@@ -2,8 +2,6 @@
namespace Doctrine\Tests\DBAL\Schema;
require_once __DIR__ . '/../../TestInit.php';
use Doctrine\DBAL\Schema\Schema;
use Doctrine\DBAL\Schema\Table;
use Doctrine\DBAL\Schema\TableBuilder;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment