Commit 8bfde413 authored by beberlei's avatar beberlei

[2.0] DDC-169 - Add ColumnDiff and further Comparator column stuff

parent 63393727
......@@ -33,7 +33,7 @@ use Doctrine\DBAL\Schema\Visitor\Visitor;
* @version $Revision$
* @author Benjamin Eberlei <kontakt@beberlei.de>
*/
class Column extends AbstractAsset
class Column extends AbstractAsset implements \ArrayAccess
{
/**
* @var \Doctrine\DBAL\Types\Type
......@@ -288,4 +288,43 @@ class Column extends AbstractAsset
{
$visitor->accept($this);
}
/**
* @param string $option
* @return mixed
*/
public function offsetExists($option)
{
return (\property_exists($this, "_".$option) || $this->hasPlatformOption($option));
}
/**
* @param string $option
* @return mixed
*/
public function offsetGet($option)
{
$optionAccessor = "_".$option;
if(\property_exists($this, $optionAccessor)) {
return $this->$optionAccessor;
} else if($this->hasPlatformOption($option)) {
return $this->getPlatformOption($option);
} else {
return false;
}
}
public function offsetSet($offset, $value)
{
throw new \BadMethodCallException(
"Setting column property ".$this->_name."::".$offset." through the ArrayAccess interface is not allowed."
);
}
public function offsetUnset($offset)
{
throw new \BadMethodCallException(
"Unsetting column property ".$this->_name."::".$offset." through the ArrayAccess interface is not allowed."
);
}
}
\ No newline at end of file
<?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
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\DBAL\Schema;
/**
* Represent the change of a column
*
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @link www.doctrine-project.org
* @since 2.0
* @version $Revision$
* @author Benjamin Eberlei <kontakt@beberlei.de>
*/
class ColumnDiff
{
/**
* @var Column
*/
public $column;
/**
* @var array
*/
public $changedProperties = array();
public function __construct(Column $column, array $changedProperties = array())
{
$this->column = $column;
$this->changedProperties = $changedProperties;
}
public function hasChanged($propertyName)
{
return in_array($propertyName, $this->changedProperties);
}
}
\ No newline at end of file
......@@ -142,7 +142,7 @@ class Comparator
public function diffTable( Table $table1, Table $table2 )
{
$changes = 0;
$tableDifferences = new TableDiff();
$tableDifferences = new TableDiff($table1->getName());
$table1Columns = $table1->getColumns();
$table2Columns = $table2->getColumns();
......@@ -164,8 +164,10 @@ class Comparator
/* See if there are any changed fieldDefinitioninitions */
foreach ( $table1Columns as $columnName => $column ) {
if ( $table2->hasColumn($columnName) ) {
if ( $this->diffColumn( $column, $table2->getColumn($columnName) ) ) {
$tableDifferences->changedColumns[$column->getName()] = $table2->getColumn($columnName);
$changedProperties = $this->diffColumn( $column, $table2->getColumn($columnName) );
if (count($changedProperties) ) {
$columnDiff = new ColumnDiff($table2->getColumn($columnName), $changedProperties);
$tableDifferences->changedColumns[$column->getName()] = $columnDiff;
$changes++;
}
}
......@@ -174,7 +176,7 @@ class Comparator
// Try to find columns that only changed their name, rename operations maybe cheaper than add/drop
foreach ($tableDifferences->addedColumns AS $addedColumnName => $addedColumn) {
foreach ($tableDifferences->removedColumns AS $removedColumnName => $removedColumn) {
if ($this->diffColumn($addedColumn, $removedColumn) === false) {
if (count($this->diffColumn($addedColumn, $removedColumn)) == 0) {
$tableDifferences->renamedColumns[$removedColumn->getName()] = $addedColumn;
unset($tableDifferences->addedColumns[$addedColumnName]);
unset($tableDifferences->removedColumns[$removedColumnName]);
......@@ -286,56 +288,57 @@ class Comparator
* @param Column $column1
* @param Column $column2
*
* @return bool
* @return array
*/
public function diffColumn( Column $column1, Column $column2 )
{
$changedProperties = array();
if ( $column1->getType() != $column2->getType() ) {
return true;
$changedProperties[] = 'type';
}
if ($column1->getNotnull() != $column2->getNotnull()) {
return true;
$changedProperties[] = 'notnull';
}
if ($column1->getDefault() != $column2->getDefault()) {
return true;
$changedProperties[] = 'default';
}
if ($column1->getUnsigned() != $column2->getUnsigned()) {
return true;
$changedProperties[] = 'unsigned';
}
if ($column1->getType() instanceof \Doctrine\DBAL\Types\StringType) {
if ($column1->getLength() != $column2->getLength()) {
return true;
$changedProperties[] = 'length';
}
if ($column1->getFixed() != $column2->getFixed()) {
return true;
$changedProperties[] = 'fixed';
}
}
if ($column1->getType() instanceof \Doctrine\DBAL\Types\DecimalType) {
if ($column1->getPrecision() != $column2->getPrecision()) {
return true;
$changedProperties[] = 'precision';
}
if ($column1->getScale() != $column2->getScale()) {
return true;
$changedProperties[] = 'scale';
}
}
foreach ($this->_checkColumnPlatformOptions AS $optionName) {
if ($column1->hasPlatformOption($optionName) != $column2->hasPlatformOption($optionName)) {
return true;
}
if($column1->hasPlatformOption($optionName) && $column2->hasPlatformOption($optionName)) {
if ($column1->getPlatformOption($optionName) != $column2->getPlatformOption($optionName)) {
return true;
$changedProperties[] = $optionName;
}
} else if ($column1->hasPlatformOption($optionName) != $column2->hasPlatformOption($optionName)) {
$changedProperties[] = $optionName;
}
}
return false;
return $changedProperties;
}
/**
......
......@@ -34,6 +34,16 @@ namespace Doctrine\DBAL\Schema;
*/
class TableDiff
{
/**
* @var string
*/
public $name = null;
/**
* @var string
*/
public $newName = false;
/**
* All added fields
*
......@@ -114,10 +124,11 @@ class TableDiff
* @param array(string=>Index) $changedIndexes
* @param array(string=>bool) $removedIndexes
*/
function __construct( $addedColumns = array(), $changedColumns = array(),
function __construct( $tableName, $addedColumns = array(), $changedColumns = array(),
$removedColumns = array(), $addedIndexes = array(), $changedIndexes =
array(), $removedIndexes = array() )
{
$this->name = $tableName;
$this->addedColumns = $addedColumns;
$this->changedColumns = $changedColumns;
$this->removedColumns = $removedColumns;
......
......@@ -152,7 +152,7 @@ class ComparatorTest extends \PHPUnit_Framework_TestCase
$expected = new SchemaDiff ( array(),
array (
'bugdb' => new TableDiff( array(), array(),
'bugdb' => new TableDiff( 'bugdb', array(), array(),
array (
'integerfield1' => $missingColumn,
)
......@@ -182,7 +182,7 @@ class ComparatorTest extends \PHPUnit_Framework_TestCase
$expected = new SchemaDiff ( array(),
array (
'bugdb' => new TableDiff (
'bugdb' => new TableDiff ('bugdb',
array (
'integerfield2' => new Column('integerfield2', Type::getType('integer')),
)
......@@ -198,8 +198,8 @@ class ComparatorTest extends \PHPUnit_Framework_TestCase
$column2 = new Column('charfield1', Type::getType('integer'));
$c = new Comparator();
$this->assertTrue($c->diffColumn($column1, $column2));
$this->assertFalse($c->diffColumn($column1, $column1));
$this->assertEquals(array('type'), $c->diffColumn($column1, $column2));
$this->assertEquals(array(), $c->diffColumn($column1, $column1));
}
public function testCompareRemovedIndex()
......@@ -231,7 +231,7 @@ class ComparatorTest extends \PHPUnit_Framework_TestCase
$expected = new SchemaDiff ( array(),
array (
'bugdb' => new TableDiff( array(), array(), array(), array(), array(),
'bugdb' => new TableDiff( 'bugdb', array(), array(), array(), array(), array(),
array (
'primary' => true
)
......@@ -270,7 +270,7 @@ class ComparatorTest extends \PHPUnit_Framework_TestCase
$expected = new SchemaDiff ( array(),
array (
'bugdb' => new TableDiff( array(), array(), array(),
'bugdb' => new TableDiff( 'bugdb', array(), array(), array(),
array (
'primary' => new Index('primary',
array(
......@@ -320,7 +320,7 @@ class ComparatorTest extends \PHPUnit_Framework_TestCase
$expected = new SchemaDiff ( array(),
array (
'bugdb' => new TableDiff( array(), array(), array(), array(),
'bugdb' => new TableDiff( 'bugdb', array(), array(), array(), array(),
array (
'primary' => new Index('primary',
array(
......@@ -364,7 +364,7 @@ class ComparatorTest extends \PHPUnit_Framework_TestCase
$expected = new SchemaDiff ( array(),
array (
'bugdb' => new TableDiff( array(), array(), array(), array(),
'bugdb' => new TableDiff('bugdb', array(), array(), array(), array(),
array (
'primary' => new Index('primary', array('integerfield2', 'integerfield1'), true)
)
......
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