[2.0] DDC-169 - Finalized implementation of Schema diff algorithm, added diffs of sequences and foreign keys. Fixed several bugs and changed the API of the Schema objects.
This commit is contained in:
parent
f22a56cdd7
commit
709dfb52c4
@ -59,4 +59,27 @@ abstract class AbstractAsset
|
||||
{
|
||||
return $this->_name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate an identifier from a list of column names obeying a certain string length.
|
||||
*
|
||||
* This is especially important for Oracle, since it does not allow identifiers larger than 30 chars,
|
||||
* however building idents automatically for foreign keys, composite keys or such can easily create
|
||||
* very long names.
|
||||
*
|
||||
* @param array $columnNames
|
||||
* @param string $postfix
|
||||
* @param int $maxSize
|
||||
* @return string
|
||||
*/
|
||||
protected function _generateIdentifierName($columnNames, $postfix='', $maxSize=30)
|
||||
{
|
||||
$columnCount = count($columnNames);
|
||||
$postfixLen = strlen($postfix);
|
||||
$parts = array_map(function($columnName) use($columnCount, $postfixLen, $maxSize) {
|
||||
return substr($columnName, 0, floor(($maxSize-$postfixLen)/$columnCount - 1));
|
||||
}, $columnNames);
|
||||
$parts[] = $postfix;
|
||||
return implode("_", $parts);
|
||||
}
|
||||
}
|
@ -34,6 +34,19 @@ namespace Doctrine\DBAL\Schema;
|
||||
*/
|
||||
class Comparator
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $_checkColumnPlatformOptions = array();
|
||||
|
||||
/**
|
||||
* @param string $optionName
|
||||
*/
|
||||
public function addColumnPlatformOptionCheck($optionName)
|
||||
{
|
||||
$this->_checkColumnPlatformOptions[] = $optionName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Schema $fromSchema
|
||||
* @param Schema $toSchema
|
||||
@ -79,11 +92,43 @@ class Comparator
|
||||
}
|
||||
}
|
||||
|
||||
// Todo add code for sequence diff
|
||||
foreach ( $toSchema->getSequences() AS $sequenceName => $sequence) {
|
||||
if (!$fromSchema->hasSequence($sequenceName)) {
|
||||
$diff->newSequences[] = $sequence;
|
||||
} else {
|
||||
if ($this->diffSequence($sequence, $fromSchema->getSequence($sequenceName))) {
|
||||
$diff->changedSequences[] = $fromSchema->getSequence($sequenceName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($fromSchema->getSequences() AS $sequenceName => $sequence) {
|
||||
if (!$toSchema->hasSequence($sequenceName)) {
|
||||
$diff->removedSequences[] = $sequence;
|
||||
}
|
||||
}
|
||||
|
||||
return $diff;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param Sequence $sequence1
|
||||
* @param Sequence $sequence2
|
||||
*/
|
||||
public function diffSequence($sequence1, $sequence2)
|
||||
{
|
||||
if($sequence1->getAllocationSize() != $sequence2->getAllocationSize()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if($sequence1->getInitialValue() != $sequence2->getInitialValue()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the difference between the tables $table1 and $table2.
|
||||
*
|
||||
@ -94,7 +139,7 @@ class Comparator
|
||||
*
|
||||
* @return bool|TableDiff
|
||||
*/
|
||||
private function diffTable( Table $table1, Table $table2 )
|
||||
public function diffTable( Table $table1, Table $table2 )
|
||||
{
|
||||
$changes = 0;
|
||||
$tableDifferences = new TableDiff();
|
||||
@ -116,9 +161,8 @@ class Comparator
|
||||
/* See if there are any changed fieldDefinitioninitions */
|
||||
foreach ( $table1->getColumns() as $columnName => $column ) {
|
||||
if ( $table2->hasColumn($columnName) ) {
|
||||
$fieldDifferences = $this->diffField( $column, $table2->getColumn($columnName) );
|
||||
if ( $fieldDifferences ) {
|
||||
$tableDifferences->changedFields[$columnName] = $fieldDifferences;
|
||||
if ( $this->diffColumn( $column, $table2->getColumn($columnName) ) ) {
|
||||
$tableDifferences->changedFields[$columnName] = $table2->getColumn($columnName);
|
||||
$changes++;
|
||||
}
|
||||
}
|
||||
@ -144,19 +188,71 @@ class Comparator
|
||||
/* See if there are any changed indexDefinitions */
|
||||
foreach ( $table1Indexes as $indexName => $indexDefinition ) {
|
||||
if ( isset( $table2Indexes[$indexName] ) ) {
|
||||
$indexDifferences = $this->diffIndex( $indexDefinition, $table2Indexes[$indexName] );
|
||||
if ( $indexDifferences ) {
|
||||
$tableDifferences->changedIndexes[$indexName] = $indexDifferences;
|
||||
if ( $this->diffIndex( $indexDefinition, $table2Indexes[$indexName] ) ) {
|
||||
$tableDifferences->changedIndexes[$indexName] = $table2Indexes[$indexName];
|
||||
$changes++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Todo add code for foreign key differences
|
||||
foreach ($table2->getForeignKeys() AS $constraint) {
|
||||
$fkName = $constraint->getName();
|
||||
if (!$table1->hasForeignKey($fkName)) {
|
||||
$tableDifferences->addedForeignKeys[$fkName] = $constraint;
|
||||
$changes++;
|
||||
} else {
|
||||
if ($this->diffForeignKey($constraint, $table1->getForeignKey($fkName))) {
|
||||
$tableDifferences->changedForeignKeys[$fkName] = $constraint;
|
||||
$changes++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($table1->getForeignKeys() AS $constraint) {
|
||||
$fkName = $constraint->getName();
|
||||
if (!$table2->hasForeignKey($fkName)) {
|
||||
$tableDifferences->removedForeignKeys[$fkName] = $constraint;
|
||||
$changes++;
|
||||
}
|
||||
}
|
||||
|
||||
return $changes ? $tableDifferences : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ForeignKeyConstraint $key1
|
||||
* @param ForeignKeyConstraint $key2
|
||||
* @return bool
|
||||
*/
|
||||
public function diffForeignKey($key1, $key2)
|
||||
{
|
||||
if ($key1->getLocalColumnNames() != $key2->getLocalColumnNames()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($key1->getForeignColumnNames() != $key2->getForeignColumnNames()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($key1->hasOption('onUpdate') != $key2->hasOption('onUpdate')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($key1->getOption('onUpdate') != $key2->getOption('onUpdate')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($key1->hasOption('onDelete') != $key2->hasOption('onDelete')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($key1->getOption('onDelete') != $key2->getOption('onDelete')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the difference between the fields $field1 and $field2.
|
||||
*
|
||||
@ -166,12 +262,53 @@ class Comparator
|
||||
* @param Column $column1
|
||||
* @param Column $column2
|
||||
*
|
||||
* @return bool|Column
|
||||
* @return bool
|
||||
*/
|
||||
private function diffField( Column $column1, Column $column2 )
|
||||
public function diffColumn( Column $column1, Column $column2 )
|
||||
{
|
||||
if ( $column1->getType() != $column2->getType() ) {
|
||||
return $column2;
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($column1->getNotnull() != $column2->getNotnull()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($column1->getDefault() != $column2->getDefault()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($column1->getUnsigned() != $column2->getUnsigned()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($column1->getType() instanceof \Doctrine\DBAL\Types\StringType) {
|
||||
if ($column1->getLength() != $column2->getLength()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($column1->getFixed() != $column2->getFixed()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if ($column1->getType() instanceof \Doctrine\DBAL\Types\DecimalType) {
|
||||
if ($column1->getPrecision() != $column2->getPrecision()) {
|
||||
return true;
|
||||
}
|
||||
if ($column1->getScale() != $column2->getScale()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($this->_checkColumnPlatformOptions AS $optionName) {
|
||||
if ($column1->hasPlatformOption($optionName) != $column2->hasPlatformOption($optionName)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($column1->getPlatformOption($optionName) != $column2->getPlatformOption($optionName)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
@ -185,15 +322,15 @@ class Comparator
|
||||
*
|
||||
* @param Index $index1
|
||||
* @param Index $index2
|
||||
* @return bool|Index
|
||||
* @return bool
|
||||
*/
|
||||
private function diffIndex( Index $index1, Index $index2 )
|
||||
public function diffIndex( Index $index1, Index $index2 )
|
||||
{
|
||||
if($index1->isPrimary() != $index2->isPrimary()) {
|
||||
return $index2;
|
||||
return true;
|
||||
}
|
||||
if($index1->isUnique() != $index2->isUnique()) {
|
||||
return $index2;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check for removed index fields in $index2
|
||||
@ -201,7 +338,7 @@ class Comparator
|
||||
for($i = 0; $i < count($index1Columns); $i++) {
|
||||
$indexColumn = $index1Columns[$i];
|
||||
if (!$index2->hasColumnAtPosition($indexColumn, $i)) {
|
||||
return $index2;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -210,7 +347,7 @@ class Comparator
|
||||
for($i = 0; $i < count($index2Columns); $i++) {
|
||||
$indexColumn = $index2Columns[$i];
|
||||
if (!$index1->hasColumnAtPosition($indexColumn, $i)) {
|
||||
return $index2;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -48,6 +48,8 @@ class Index extends AbstractAsset
|
||||
*/
|
||||
public function __construct($indexName, array $columns, $isUnique=false, $isPrimary=false)
|
||||
{
|
||||
$isUnique = ($isPrimary)?true:$isUnique;
|
||||
|
||||
$this->_setName($indexName);
|
||||
$this->_isUnique = $isUnique;
|
||||
$this->_isPrimary = $isPrimary;
|
||||
|
@ -39,21 +39,36 @@ class SchemaDiff
|
||||
*
|
||||
* @var array(string=>ezcDbSchemaTable)
|
||||
*/
|
||||
public $newTables;
|
||||
public $newTables = array();
|
||||
|
||||
/**
|
||||
* All changed tables
|
||||
*
|
||||
* @var array(string=>ezcDbSchemaTableDiff)
|
||||
*/
|
||||
public $changedTables;
|
||||
public $changedTables = array();
|
||||
|
||||
/**
|
||||
* All removed tables
|
||||
*
|
||||
* @var array(string=>bool)
|
||||
* @var array(string=>Table)
|
||||
*/
|
||||
public $removedTables;
|
||||
public $removedTables = array();
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
public $newSequences = array();
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
public $changedSequences = array();
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
public $removedSequences = array();
|
||||
|
||||
/**
|
||||
* Constructs an SchemaDiff object.
|
||||
|
@ -13,6 +13,7 @@ class SchemaException extends \Doctrine\DBAL\DBALException
|
||||
const SEQUENCE_DOENST_EXIST = 70;
|
||||
const SEQUENCE_ALREADY_EXISTS = 80;
|
||||
const INDEX_INVALID_NAME = 90;
|
||||
const FOREIGNKEY_DOESNT_EXIST = 100;
|
||||
|
||||
/**
|
||||
* @param string $tableName
|
||||
@ -99,4 +100,13 @@ class SchemaException extends \Doctrine\DBAL\DBALException
|
||||
{
|
||||
return new self("There exists no sequence with the name '".$sequenceName."'.", self::SEQUENCE_DOENST_EXIST);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $fkName
|
||||
* @return SchemaException
|
||||
*/
|
||||
static public function foreignKeyDoesNotExist($fkName)
|
||||
{
|
||||
return new self("There exists no foreign key with the name '".$fkName."'.", self::FOREIGNKEY_DOESNT_EXIST);
|
||||
}
|
||||
}
|
@ -73,7 +73,7 @@ class Table extends AbstractAsset
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $_constraints = array();
|
||||
protected $_fkConstraints = array();
|
||||
|
||||
/**
|
||||
* @var array
|
||||
@ -90,11 +90,11 @@ class Table extends AbstractAsset
|
||||
* @param string $tableName
|
||||
* @param array $columns
|
||||
* @param array $indexes
|
||||
* @param array $constraints
|
||||
* @param array $fkConstraints
|
||||
* @param int $idGeneratorType
|
||||
* @param array $options
|
||||
*/
|
||||
public function __construct($tableName, array $columns=array(), array $indexes=array(), array $constraints=array(), $idGeneratorType=self::ID_NONE, array $options=array())
|
||||
public function __construct($tableName, array $columns=array(), array $indexes=array(), array $fkConstraints=array(), $idGeneratorType=self::ID_NONE, array $options=array())
|
||||
{
|
||||
$this->_name = $tableName;
|
||||
$this->_idGeneratorType = $idGeneratorType;
|
||||
@ -107,8 +107,8 @@ class Table extends AbstractAsset
|
||||
$this->_addIndex($idx);
|
||||
}
|
||||
|
||||
foreach ($constraints AS $constraint) {
|
||||
$this->_addConstraint($constraint);
|
||||
foreach ($fkConstraints AS $constraint) {
|
||||
$this->_addForeignKeyConstraint($constraint);
|
||||
}
|
||||
|
||||
$this->_options = $options;
|
||||
@ -143,6 +143,10 @@ class Table extends AbstractAsset
|
||||
*/
|
||||
public function addIndex(array $columnNames, $indexName=null)
|
||||
{
|
||||
if($indexName == null) {
|
||||
$indexName = $this->_generateIdentifierName($columnNames, "idx");
|
||||
}
|
||||
|
||||
return $this->_createIndex($columnNames, $indexName, false, false);
|
||||
}
|
||||
|
||||
@ -154,6 +158,10 @@ class Table extends AbstractAsset
|
||||
*/
|
||||
public function addUniqueIndex(array $columnNames, $indexName=null)
|
||||
{
|
||||
if ($indexName == null) {
|
||||
$indexName = $this->_generateIdentifierName($columnNames, "uniq");
|
||||
}
|
||||
|
||||
return $this->_createIndex($columnNames, $indexName, true, false);
|
||||
}
|
||||
|
||||
@ -241,13 +249,31 @@ class Table extends AbstractAsset
|
||||
/**
|
||||
* Add a foreign key constraint
|
||||
*
|
||||
* Name is inferred from the local columns
|
||||
*
|
||||
* @param Table $foreignTable
|
||||
* @param array $localColumns
|
||||
* @param array $foreignColumns
|
||||
* @param array $options
|
||||
* @return Table
|
||||
*/
|
||||
public function addForeignKeyConstraint($foreignTable, array $localColumnNames, array $foreignColumnNames, $name=null, array $options=array())
|
||||
public function addForeignKeyConstraint($foreignTable, array $localColumnNames, array $foreignColumnNames, array $options=array())
|
||||
{
|
||||
$name = $this->_generateIdentifierName($localColumnNames, "fk");
|
||||
return $this->addNamedForeignKeyConstraint($name, $foreignTable, $localColumnNames, $foreignColumnNames, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a foreign key constraint with a given name
|
||||
*
|
||||
* @param string $name
|
||||
* @param Table $foreignTable
|
||||
* @param array $localColumns
|
||||
* @param array $foreignColumns
|
||||
* @param array $options
|
||||
* @return Table
|
||||
*/
|
||||
public function addNamedForeignKeyConstraint($name, $foreignTable, array $localColumnNames, array $foreignColumnNames, array $options=array())
|
||||
{
|
||||
if ($foreignTable instanceof Table) {
|
||||
$foreignTableName = $foreignTable->getName();
|
||||
@ -270,7 +296,7 @@ class Table extends AbstractAsset
|
||||
$constraint = new ForeignKeyConstraint(
|
||||
$localColumnNames, $foreignTableName, $foreignColumnNames, $name, $options
|
||||
);
|
||||
$this->_addConstraint($constraint);
|
||||
$this->_addForeignKeyConstraint($constraint);
|
||||
return $this;
|
||||
}
|
||||
|
||||
@ -323,9 +349,33 @@ class Table extends AbstractAsset
|
||||
/**
|
||||
* @param Constraint $constraint
|
||||
*/
|
||||
protected function _addConstraint(Constraint $constraint)
|
||||
protected function _addForeignKeyConstraint(Constraint $constraint)
|
||||
{
|
||||
$this->_constraints[] = $constraint;
|
||||
$this->_fkConstraints[$constraint->getName()] = $constraint;
|
||||
}
|
||||
|
||||
/**
|
||||
* Does Table have a foreign key constraint with the given name?
|
||||
* *
|
||||
* @param string $constraintName
|
||||
* @return bool
|
||||
*/
|
||||
public function hasForeignKey($constraintName)
|
||||
{
|
||||
return isset($this->_fkConstraints[$constraintName]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $constraintName
|
||||
* @return ForeignKeyConstraint
|
||||
*/
|
||||
public function getForeignKey($constraintName)
|
||||
{
|
||||
if(!$this->hasForeignKey($constraintName)) {
|
||||
throw SchemaException::foreignKeyDoesNotExist($constraintName);
|
||||
}
|
||||
|
||||
return $this->_fkConstraints[$constraintName];
|
||||
}
|
||||
|
||||
/**
|
||||
@ -421,9 +471,9 @@ class Table extends AbstractAsset
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getConstraints()
|
||||
public function getForeignKeys()
|
||||
{
|
||||
return $this->_constraints;
|
||||
return $this->_fkConstraints;
|
||||
}
|
||||
|
||||
public function hasOption($name)
|
||||
@ -456,12 +506,8 @@ class Table extends AbstractAsset
|
||||
$visitor->acceptIndex($this, $index);
|
||||
}
|
||||
|
||||
foreach ($this->getConstraints() AS $constraint) {
|
||||
if ($constraint instanceof ForeignKeyConstraint) {
|
||||
foreach ($this->getForeignKeys() AS $constraint) {
|
||||
$visitor->acceptForeignKey($this, $constraint);
|
||||
} else {
|
||||
$visitor->acceptCheckConstraint($this, $constraint);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -44,37 +44,58 @@ class TableDiff
|
||||
/**
|
||||
* All changed fields
|
||||
*
|
||||
* @var array(string=>ezcDbSchemaField)
|
||||
* @var array(string=>Column)
|
||||
*/
|
||||
public $changedFields;
|
||||
public $changedFields = array();
|
||||
|
||||
/**
|
||||
* All removed fields
|
||||
*
|
||||
* @var array(string=>bool)
|
||||
*/
|
||||
public $removedFields;
|
||||
public $removedFields = array();
|
||||
|
||||
/**
|
||||
* All added indexes
|
||||
*
|
||||
* @var array(string=>ezcDbSchemaIndex)
|
||||
* @var array(string=>Index)
|
||||
*/
|
||||
public $addedIndexes;
|
||||
public $addedIndexes = array();
|
||||
|
||||
/**
|
||||
* All changed indexes
|
||||
*
|
||||
* @var array(string=>ezcDbSchemaIndex)
|
||||
* @var array(string=>Index)
|
||||
*/
|
||||
public $changedIndexes;
|
||||
public $changedIndexes = array();
|
||||
|
||||
/**
|
||||
* All removed indexes
|
||||
*
|
||||
* @var array(string=>bool)
|
||||
*/
|
||||
public $removedIndexes;
|
||||
public $removedIndexes = array();
|
||||
|
||||
/**
|
||||
* All added foreign key definitions
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $addedForeignKeys = array();
|
||||
|
||||
/**
|
||||
* All changed foreign keys
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $changedForeignKeys = array();
|
||||
|
||||
/**
|
||||
* All removed foreign keys
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $removedForeignKeys = array();
|
||||
|
||||
/**
|
||||
* Constructs an TableDiff object.
|
||||
|
@ -179,8 +179,7 @@ class SchemaTool
|
||||
// Add a FK constraint on the ID column
|
||||
$table->addForeignKeyConstraint(
|
||||
$this->_em->getClassMetadata($class->rootEntityName)->getQuotedTableName($this->_platform),
|
||||
array($columnName), array($columnName), null,
|
||||
array('onDelete' => 'CASCADE')
|
||||
array($columnName), array($columnName), array('onDelete' => 'CASCADE')
|
||||
);
|
||||
}
|
||||
|
||||
@ -416,7 +415,7 @@ class SchemaTool
|
||||
}
|
||||
|
||||
$theJoinTable->addForeignKeyConstraint(
|
||||
$class->getQuotedTableName($this->_platform), $localColumns, $foreignColumns, null, $fkOptions
|
||||
$class->getQuotedTableName($this->_platform), $localColumns, $foreignColumns, $fkOptions
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -193,31 +193,12 @@ class ComparatorTest extends \PHPUnit_Framework_TestCase
|
||||
|
||||
public function testCompareChangedColumns_ChangeType()
|
||||
{
|
||||
$schema1 = new Schema( array(
|
||||
'bugdb' => new Table('bugdb',
|
||||
array (
|
||||
'charfield1' => new Column('charfield1', Type::getType('string')),
|
||||
)
|
||||
),
|
||||
) );
|
||||
$schema2 = new Schema( array(
|
||||
'bugdb' => new Table('bugdb',
|
||||
array (
|
||||
'charfield1' => new Column('charfield1', Type::getType('integer')),
|
||||
)
|
||||
),
|
||||
) );
|
||||
$column1 = new Column('charfield1', Type::getType('string'));
|
||||
$column2 = new Column('charfield1', Type::getType('integer'));
|
||||
|
||||
$expected = new SchemaDiff ( array(),
|
||||
array (
|
||||
'bugdb' => new TableDiff( array(),
|
||||
array (
|
||||
'charfield1' => new Column('charfield1', Type::getType('integer')),
|
||||
)
|
||||
),
|
||||
)
|
||||
);
|
||||
$this->assertEquals($expected, Comparator::compareSchemas( $schema1, $schema2 ) );
|
||||
$c = new Comparator();
|
||||
$this->assertTrue($c->diffColumn($column1, $column2));
|
||||
$this->assertFalse($c->diffColumn($column1, $column1));
|
||||
}
|
||||
|
||||
public function testCompareRemovedIndex()
|
||||
@ -354,4 +335,140 @@ class ComparatorTest extends \PHPUnit_Framework_TestCase
|
||||
$actual = Comparator::compareSchemas( $schema1, $schema2 );
|
||||
$this->assertEquals($expected, $actual);
|
||||
}
|
||||
|
||||
public function testCompareChangedIndexFieldPositions()
|
||||
{
|
||||
$schema1 = new Schema( array(
|
||||
'bugdb' => new Table('bugdb',
|
||||
array (
|
||||
'integerfield1' => new Column('integerfield1', Type::getType('integer')),
|
||||
'integerfield2' => new Column('integerfield2', Type::getType('integer')),
|
||||
),
|
||||
array (
|
||||
'primary' => new Index('primary', array('integerfield1', 'integerfield2'), true)
|
||||
)
|
||||
),
|
||||
) );
|
||||
$schema2 = new Schema( array(
|
||||
'bugdb' => new Table('bugdb',
|
||||
array (
|
||||
'integerfield1' => new Column('integerfield1', Type::getType('integer')),
|
||||
'integerfield2' => new Column('integerfield2', Type::getType('integer')),
|
||||
),
|
||||
array (
|
||||
'primary' => new Index('primary', array('integerfield2', 'integerfield1'), true)
|
||||
)
|
||||
),
|
||||
) );
|
||||
|
||||
$expected = new SchemaDiff ( array(),
|
||||
array (
|
||||
'bugdb' => new TableDiff( array(), array(), array(), array(),
|
||||
array (
|
||||
'primary' => new Index('primary', array('integerfield2', 'integerfield1'), true)
|
||||
)
|
||||
),
|
||||
)
|
||||
);
|
||||
$actual = Comparator::compareSchemas( $schema1, $schema2 );
|
||||
$this->assertEquals($expected, $actual);
|
||||
}
|
||||
|
||||
public function testCompareSequences()
|
||||
{
|
||||
$seq1 = new Sequence('foo', 1, 1);
|
||||
$seq2 = new Sequence('foo', 1, 2);
|
||||
$seq3 = new Sequence('foo', 2, 1);
|
||||
|
||||
$c = new Comparator();
|
||||
|
||||
$this->assertTrue($c->diffSequence($seq1, $seq2));
|
||||
$this->assertTrue($c->diffSequence($seq1, $seq3));
|
||||
}
|
||||
|
||||
public function testRemovedSequence()
|
||||
{
|
||||
$schema1 = new Schema();
|
||||
$seq = $schema1->createSequence('foo');
|
||||
|
||||
$schema2 = new Schema();
|
||||
|
||||
$c = new Comparator();
|
||||
$diffSchema = $c->compare($schema1, $schema2);
|
||||
|
||||
$this->assertEquals(1, count($diffSchema->removedSequences));
|
||||
$this->assertSame($seq, $diffSchema->removedSequences[0]);
|
||||
}
|
||||
|
||||
public function testAddedSequence()
|
||||
{
|
||||
$schema1 = new Schema();
|
||||
|
||||
$schema2 = new Schema();
|
||||
$seq = $schema2->createSequence('foo');
|
||||
|
||||
$c = new Comparator();
|
||||
$diffSchema = $c->compare($schema1, $schema2);
|
||||
|
||||
$this->assertEquals(1, count($diffSchema->newSequences));
|
||||
$this->assertSame($seq, $diffSchema->newSequences[0]);
|
||||
}
|
||||
|
||||
public function testTableAddForeignKey()
|
||||
{
|
||||
$tableForeign = new Table("bar");
|
||||
$tableForeign->createColumn('id', 'integer');
|
||||
|
||||
$table1 = new Table("foo");
|
||||
$table1->createColumn('fk', 'integer');
|
||||
|
||||
$table2 = new Table("foo");
|
||||
$table2->createColumn('fk', 'integer');
|
||||
$table2->addForeignKeyConstraint($tableForeign, array('fk'), array('id'));
|
||||
|
||||
$c = new Comparator();
|
||||
$tableDiff = $c->diffTable($table1, $table2);
|
||||
|
||||
$this->assertType('Doctrine\DBAL\Schema\TableDiff', $tableDiff);
|
||||
$this->assertEquals(1, count($tableDiff->addedForeignKeys));
|
||||
}
|
||||
|
||||
public function testTableRemoveForeignKey()
|
||||
{
|
||||
$tableForeign = new Table("bar");
|
||||
$tableForeign->createColumn('id', 'integer');
|
||||
|
||||
$table1 = new Table("foo");
|
||||
$table1->createColumn('fk', 'integer');
|
||||
|
||||
$table2 = new Table("foo");
|
||||
$table2->createColumn('fk', 'integer');
|
||||
$table2->addForeignKeyConstraint($tableForeign, array('fk'), array('id'));
|
||||
|
||||
$c = new Comparator();
|
||||
$tableDiff = $c->diffTable($table2, $table1);
|
||||
|
||||
$this->assertType('Doctrine\DBAL\Schema\TableDiff', $tableDiff);
|
||||
$this->assertEquals(1, count($tableDiff->removedForeignKeys));
|
||||
}
|
||||
|
||||
public function testTableUpdateForeignKey()
|
||||
{
|
||||
$tableForeign = new Table("bar");
|
||||
$tableForeign->createColumn('id', 'integer');
|
||||
|
||||
$table1 = new Table("foo");
|
||||
$table1->createColumn('fk', 'integer');
|
||||
$table1->addForeignKeyConstraint($tableForeign, array('fk'), array('id'));
|
||||
|
||||
$table2 = new Table("foo");
|
||||
$table2->createColumn('fk', 'integer');
|
||||
$table2->addForeignKeyConstraint($tableForeign, array('fk'), array('id'), array('onUpdate' => 'CASCADE'));
|
||||
|
||||
$c = new Comparator();
|
||||
$tableDiff = $c->diffTable($table1, $table2);
|
||||
|
||||
$this->assertType('Doctrine\DBAL\Schema\TableDiff', $tableDiff);
|
||||
$this->assertEquals(1, count($tableDiff->changedForeignKeys));
|
||||
}
|
||||
}
|
@ -30,7 +30,7 @@ class IndexTest extends \PHPUnit_Framework_TestCase
|
||||
public function testCreatePrimary()
|
||||
{
|
||||
$idx = $this->createIndex(false, true);
|
||||
$this->assertFalse($idx->isUnique());
|
||||
$this->assertTrue($idx->isUnique());
|
||||
$this->assertTrue($idx->isPrimary());
|
||||
}
|
||||
|
||||
|
@ -86,6 +86,18 @@ class TableTest extends \PHPUnit_Framework_TestCase
|
||||
$table = new Table("foo", $columns, array(), array());
|
||||
}
|
||||
|
||||
public function testCreateIndex()
|
||||
{
|
||||
$type = \Doctrine\DBAL\Types\Type::getType('integer');
|
||||
$columns = array(new Column("foo", $type), new Column("bar", $type), new Column("baz", $type));
|
||||
$table = new Table("foo", $columns);
|
||||
$table->addIndex(array("foo", "bar", "baz"));
|
||||
$table->addUniqueIndex(array("foo", "bar", "baz"));
|
||||
|
||||
$this->assertTrue($table->hasIndex("foo_bar_baz_idx"));
|
||||
$this->assertTrue($table->hasIndex("foo_bar_baz_uniq"));
|
||||
}
|
||||
|
||||
public function testAddIndexes()
|
||||
{
|
||||
$type = \Doctrine\DBAL\Types\Type::getType('integer');
|
||||
@ -159,10 +171,10 @@ class TableTest extends \PHPUnit_Framework_TestCase
|
||||
$constraint = new ForeignKeyConstraint(array(), "foo", array());
|
||||
|
||||
$tableA = new Table("foo", array(), array(), array($constraint));
|
||||
$constraints = $tableA->getConstraints();
|
||||
$constraints = $tableA->getForeignKeys();
|
||||
|
||||
$this->assertEquals(1, count($constraints));
|
||||
$this->assertSame($constraint, $constraints[0]);
|
||||
$this->assertSame($constraint, array_shift($constraints));
|
||||
}
|
||||
|
||||
public function testOptions()
|
||||
@ -256,7 +268,7 @@ class TableTest extends \PHPUnit_Framework_TestCase
|
||||
$foreignTable = new Table("bar");
|
||||
$foreignTable->createColumn("id", 'int');
|
||||
|
||||
$table->addForeignKeyConstraint($foreignTable, array("foo"), array("id"), array());
|
||||
$table->addForeignKeyConstraint($foreignTable, array("foo"), array("id"));
|
||||
}
|
||||
|
||||
public function testAddForeignKeyConstraint_UnknownForeignColumn_ThrowsException()
|
||||
@ -269,7 +281,7 @@ class TableTest extends \PHPUnit_Framework_TestCase
|
||||
$foreignTable = new Table("bar");
|
||||
$foreignTable->createColumn("id", 'integer');
|
||||
|
||||
$table->addForeignKeyConstraint($foreignTable, array("id"), array("foo"), array());
|
||||
$table->addForeignKeyConstraint($foreignTable, array("id"), array("foo"));
|
||||
}
|
||||
|
||||
public function testAddForeignKeyConstraint()
|
||||
@ -280,15 +292,15 @@ class TableTest extends \PHPUnit_Framework_TestCase
|
||||
$foreignTable = new Table("bar");
|
||||
$foreignTable->createColumn("id", 'integer');
|
||||
|
||||
$table->addForeignKeyConstraint($foreignTable, array("id"), array("id"), "fkName", array("foo" => "bar"));
|
||||
$table->addForeignKeyConstraint($foreignTable, array("id"), array("id"), array("foo" => "bar"));
|
||||
|
||||
$constraints = $table->getConstraints();
|
||||
$constraints = $table->getForeignKeys();
|
||||
$this->assertEquals(1, count($constraints));
|
||||
$this->assertType('Doctrine\DBAL\Schema\ForeignKeyConstraint', $constraints[0]);
|
||||
$this->assertType('Doctrine\DBAL\Schema\ForeignKeyConstraint', $constraints["id_fk"]);
|
||||
|
||||
$this->assertEquals("fkName", $constraints[0]->getName());
|
||||
$this->assertTrue($constraints[0]->hasOption("foo"));
|
||||
$this->assertEquals("bar", $constraints[0]->getOption("foo"));
|
||||
$this->assertEquals("id_fk", $constraints["id_fk"]->getName());
|
||||
$this->assertTrue($constraints["id_fk"]->hasOption("foo"));
|
||||
$this->assertEquals("bar", $constraints["id_fk"]->getOption("foo"));
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user