diff --git a/Cake/Database/Schema/MysqlSchema.php b/Cake/Database/Schema/MysqlSchema.php index 9b8aa75a249..fbd096087fc 100644 --- a/Cake/Database/Schema/MysqlSchema.php +++ b/Cake/Database/Schema/MysqlSchema.php @@ -1,7 +1,5 @@ _driver->quoteIdentifier($config['database']), []]; @@ -35,7 +31,6 @@ public function listTablesSql($config) { /** * {@inheritdoc} - * */ public function describeTableSql($name, $config) { return ['SHOW FULL COLUMNS FROM ' . $this->_driver->quoteIdentifier($name), []]; @@ -43,7 +38,6 @@ public function describeTableSql($name, $config) { /** * {@inheritdoc} - * */ public function describeIndexSql($table, $config) { return ['SHOW INDEXES FROM ' . $this->_driver->quoteIdentifier($table), []]; @@ -59,7 +53,7 @@ public function describeIndexSql($table, $config) { * @throws Cake\Database\Exception When column type cannot be parsed. */ protected function _convertColumn($column) { - preg_match('/([a-z]+)(?:\(([0-9,]+)\))?/i', $column, $matches); + preg_match('/([a-z]+)(?:\(([0-9,]+)\))?\s*([a-z]+)?/i', $column, $matches); if (empty($matches)) { throw new Exception(__d('cake_dev', 'Unable to parse column type from "%s"', $column)); } @@ -81,11 +75,13 @@ protected function _convertColumn($column) { if (($col === 'tinyint' && $length === 1) || $col === 'boolean') { return ['type' => 'boolean', 'length' => null]; } + + $unsigned = (isset($matches[3]) && strtolower($matches[3]) === 'unsigned'); if (strpos($col, 'bigint') !== false || $col === 'bigint') { - return ['type' => 'biginteger', 'length' => $length]; + return ['type' => 'biginteger', 'length' => $length, 'unsigned' => $unsigned]; } if (strpos($col, 'int') !== false) { - return ['type' => 'integer', 'length' => $length]; + return ['type' => 'integer', 'length' => $length, 'unsigned' => $unsigned]; } if ($col === 'char' && $length === 36) { return ['type' => 'uuid', 'length' => null]; @@ -103,10 +99,20 @@ protected function _convertColumn($column) { return ['type' => 'binary', 'length' => $length]; } if (strpos($col, 'float') !== false || strpos($col, 'double') !== false) { - return ['type' => 'float', 'length' => $length, 'precision' => $precision]; + return [ + 'type' => 'float', + 'length' => $length, + 'precision' => $precision, + 'unsigned' => $unsigned + ]; } if (strpos($col, 'decimal') !== false) { - return ['type' => 'decimal', 'length' => $length, 'precision' => $precision]; + return [ + 'type' => 'decimal', + 'length' => $length, + 'precision' => $precision, + 'unsigned' => $unsigned + ]; } return ['type' => 'text', 'length' => null]; } @@ -280,6 +286,7 @@ public function columnSql(Table $table, $name) { if (in_array($data['type'], $hasLength, true) && isset($data['length'])) { $out .= '(' . (int)$data['length'] . ')'; } + $hasPrecision = ['float', 'decimal']; if ( in_array($data['type'], $hasPrecision, true) && @@ -287,6 +294,15 @@ public function columnSql(Table $table, $name) { ) { $out .= '(' . (int)$data['length'] . ',' . (int)$data['precision'] . ')'; } + + $hasUnsigned = ['float', 'decimal', 'integer', 'biginteger']; + if ( + in_array($data['type'], $hasUnsigned, true) && + isset($data['unsigned']) && $data['unsigned'] === true + ) { + $out .= ' UNSIGNED'; + } + if (isset($data['null']) && $data['null'] === false) { $out .= ' NOT NULL'; } diff --git a/Cake/Test/TestCase/Database/Schema/MysqlSchemaTest.php b/Cake/Test/TestCase/Database/Schema/MysqlSchemaTest.php index 260cbc9bac9..1224e2a65ab 100644 --- a/Cake/Test/TestCase/Database/Schema/MysqlSchemaTest.php +++ b/Cake/Test/TestCase/Database/Schema/MysqlSchemaTest.php @@ -1,7 +1,5 @@ 'integer', 'length' => 2] + ['type' => 'integer', 'length' => 2, 'unsigned' => false] ], [ 'INTEGER(11)', - ['type' => 'integer', 'length' => 11] + ['type' => 'integer', 'length' => 11, 'unsigned' => false] + ], + [ + 'INTEGER(11) UNSIGNED', + ['type' => 'integer', 'length' => 11, 'unsigned' => true] ], [ 'BIGINT', - ['type' => 'biginteger', 'length' => null] + ['type' => 'biginteger', 'length' => null, 'unsigned' => false] + ], + [ + 'BIGINT UNSIGNED', + ['type' => 'biginteger', 'length' => null, 'unsigned' => true] ], [ 'VARCHAR(255)', @@ -99,23 +105,39 @@ public static function convertColumnProvider() { ], [ 'FLOAT', - ['type' => 'float', 'length' => null, 'precision' => null] + ['type' => 'float', 'length' => null, 'precision' => null, 'unsigned' => false] ], [ 'DOUBLE', - ['type' => 'float', 'length' => null, 'precision' => null] + ['type' => 'float', 'length' => null, 'precision' => null, 'unsigned' => false] + ], + [ + 'DOUBLE UNSIGNED', + ['type' => 'float', 'length' => null, 'precision' => null, 'unsigned' => true] + ], + [ + 'DECIMAL(11,2) UNSIGNED', + ['type' => 'decimal', 'length' => 11, 'precision' => 2, 'unsigned' => true] ], [ 'DECIMAL(11,2)', - ['type' => 'decimal', 'length' => 11, 'precision' => 2] + ['type' => 'decimal', 'length' => 11, 'precision' => 2, 'unsigned' => false] ], [ 'FLOAT(11,2)', - ['type' => 'float', 'length' => 11, 'precision' => 2] + ['type' => 'float', 'length' => 11, 'precision' => 2, 'unsigned' => false] + ], + [ + 'FLOAT(11,2) UNSIGNED', + ['type' => 'float', 'length' => 11, 'precision' => 2, 'unsigned' => true] ], [ 'DOUBLE(10,4)', - ['type' => 'float', 'length' => 10, 'precision' => 4] + ['type' => 'float', 'length' => 10, 'precision' => 4, 'unsigned' => false] + ], + [ + 'DOUBLE(10,4) UNSIGNED', + ['type' => 'float', 'length' => 10, 'precision' => 4, 'unsigned' => true] ], ]; } @@ -222,10 +244,10 @@ public function testDescribeTable() { 'id' => [ 'type' => 'biginteger', 'null' => false, + 'unsigned' => false, 'default' => null, 'length' => 20, 'precision' => null, - 'fixed' => null, 'comment' => null, ], 'title' => [ @@ -243,16 +265,15 @@ public function testDescribeTable() { 'default' => null, 'length' => null, 'precision' => null, - 'fixed' => null, 'comment' => null, ], 'author_id' => [ 'type' => 'integer', 'null' => false, + 'unsigned' => false, 'default' => null, 'length' => 11, 'precision' => null, - 'fixed' => null, 'comment' => null, ], 'published' => [ @@ -261,7 +282,6 @@ public function testDescribeTable() { 'default' => 0, 'length' => null, 'precision' => null, - 'fixed' => null, 'comment' => null, ], 'allow_comments' => [ @@ -270,7 +290,6 @@ public function testDescribeTable() { 'default' => 0, 'length' => null, 'precision' => null, - 'fixed' => null, 'comment' => null, ], 'created' => [ @@ -279,7 +298,6 @@ public function testDescribeTable() { 'default' => null, 'length' => null, 'precision' => null, - 'fixed' => null, 'comment' => null, ], ]; @@ -392,11 +410,21 @@ public static function columnSqlProvider() { ['type' => 'integer', 'length' => 11], '`post_id` INTEGER(11)' ], + [ + 'post_id', + ['type' => 'integer', 'length' => 11, 'unsigned' => true], + '`post_id` INTEGER(11) UNSIGNED' + ], [ 'post_id', ['type' => 'biginteger', 'length' => 20], '`post_id` BIGINT' ], + [ + 'post_id', + ['type' => 'biginteger', 'length' => 20, 'unsigned' => true], + '`post_id` BIGINT UNSIGNED' + ], // Decimal [ 'value', @@ -405,8 +433,8 @@ public static function columnSqlProvider() { ], [ 'value', - ['type' => 'decimal', 'length' => 11], - '`value` DECIMAL(11,0)' + ['type' => 'decimal', 'length' => 11, 'unsigned' => true], + '`value` DECIMAL(11,0) UNSIGNED' ], [ 'value', @@ -416,9 +444,14 @@ public static function columnSqlProvider() { // Float [ 'value', - ['type' => 'float'], + ['type' => 'float', 'unsigned'], '`value` FLOAT' ], + [ + 'value', + ['type' => 'float', 'unsigned' => true], + '`value` FLOAT UNSIGNED' + ], [ 'value', ['type' => 'float', 'length' => 11, 'precision' => 3],