diff --git a/src/Column/AbstractColumn.php b/src/Column/AbstractColumn.php index 61aa526..c6cdb17 100644 --- a/src/Column/AbstractColumn.php +++ b/src/Column/AbstractColumn.php @@ -535,4 +535,35 @@ public function setComment($comment) * DBMS-specific implementation for setting a column comment **/ abstract protected function _setComment(); + + /** + * Compare with given specification + * + * @param mixed[] $newSpec Specification to compare with. Same keys as toArray() output. + * @param string[] $keys Compare only given attributes (default: compare all) + * @return bool + */ + public function isDifferent(array $newSpec, array $keys = null) + { + $oldSpec = $this->toArray(); + if ($keys) { + $keys = array_flip($keys); + $oldSpec = array_intersect_key($oldSpec, $keys); + $newSpec = array_intersect_key($newSpec, $keys); + } + return $this->_isDifferent($oldSpec, $newSpec); + } + + /** + * Compare specifications + * + * DBMS may require extending this method with tweaks for emulated types. + * + * @param mixed[] $oldSpec + * @param mixed[] $newSpec + **/ + protected function _isDifferent($oldSpec, $newSpec) + { + return $newSpec != $oldSpec; + } } diff --git a/src/Column/Mysql.php b/src/Column/Mysql.php index 9a04cbb..0ac81e5 100644 --- a/src/Column/Mysql.php +++ b/src/Column/Mysql.php @@ -194,4 +194,21 @@ protected function _setComment() { $this->_modify(); } + + /** {@inheritdoc} */ + protected function _isDifferent($oldSpec, $newSpec) + { + if ( + array_key_exists('type', $newSpec) and + $newSpec['type'] == self::TYPE_BOOL and + $oldSpec['type'] == self::TYPE_INTEGER + ) { + // Booleans are detected as 8 bit INTEGER. + $newSpec['type'] = self::TYPE_INTEGER; + if (array_key_exists('length', $newSpec)) { + $newSpec['length'] = 8; + } + } + return parent::_isDifferent($oldSpec, $newSpec); + } } diff --git a/src/Column/Sqlite.php b/src/Column/Sqlite.php index 7c26f4a..5d436c8 100644 --- a/src/Column/Sqlite.php +++ b/src/Column/Sqlite.php @@ -158,4 +158,43 @@ protected function _setComment() { // Columnn comments are not supported by SQLite. } + + /** {@inheritdoc} */ + protected function _isDifferent($oldSpec, $newSpec) + { + if (array_key_exists('type', $newSpec)) { + $oldType = $oldSpec['type']; + $newType = $newSpec['type']; + if ( + $oldType == self::TYPE_INTEGER and + $newType == self::TYPE_INTEGER and + array_key_exists('length', $newSpec) + ) { + // Integers always have length set to NULL. + $newSpec['length'] = null; + } elseif ( + $oldType == self::TYPE_INTEGER and + $newType == self::TYPE_BOOL + ) { + // Booleans are detected as INTEGER. + $newSpec['type'] = self::TYPE_INTEGER; + } elseif ( + $oldType == self::TYPE_CLOB and + ($newType == self::TYPE_TIMESTAMP or $newType == self::TYPE_DATE) + ) { + // Timestamps and dates are detected as CLOB. + $newSpec['type'] = self::TYPE_CLOB; + } elseif ( + $oldType == self::TYPE_FLOAT and + $newType == self::TYPE_DECIMAL + ) { + // Decimals are detected as FLOAT. + $newSpec['type'] = self::TYPE_FLOAT; + if (array_key_exists('length', $newSpec)) { + $newSpec['length'] = null; + } + } + } + return parent::_isDifferent($oldSpec, $newSpec); + } }