Skip to content

Commit

Permalink
Add unsigned support to SQLite.
Browse files Browse the repository at this point in the history
integer, biginteger, float and decimal types can now be unsigned in
Sqlite. Both the schema reflection and generation will handle unsigned
values.
  • Loading branch information
markstory committed Nov 22, 2013
1 parent 9e4c94b commit d6c68b1
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 36 deletions.
40 changes: 25 additions & 15 deletions Cake/Database/Schema/SqliteSchema.php
@@ -1,7 +1,5 @@
<?php
/**
* PHP Version 5.4
*
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
*
Expand Down Expand Up @@ -42,7 +40,7 @@ class SqliteSchema extends BaseSchema {
* @return array Array of column information.
*/
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));
}
Expand All @@ -51,26 +49,25 @@ protected function _convertColumn($column) {
if (isset($matches[2])) {
$length = (int)$matches[2];
}
$unsigned = (isset($matches[3]) && strtolower($matches[3]) === 'unsigned');

if ($col === 'bigint') {
return ['type' => 'biginteger', 'length' => $length];
return ['type' => 'biginteger', 'length' => $length, 'unsigned' => $unsigned];
}
if (in_array($col, ['blob', 'clob'])) {
return ['type' => 'binary', 'length' => null];
if (strpos($col, 'decimal') !== false) {
return ['type' => 'decimal', 'length' => null, 'unsigned' => $unsigned];
}
if (in_array($col, ['date', 'time', 'timestamp', 'datetime'])) {
return ['type' => $col, 'length' => null];
if (strpos($col, 'int') !== false) {
return ['type' => 'integer', 'length' => $length, 'unsigned' => $unsigned];
}
if (strpos($col, 'decimal') !== false) {
return ['type' => 'decimal', 'length' => null];
if (in_array($col, ['float', 'real', 'double'])) {
return ['type' => 'float', 'length' => null, 'unsigned' => $unsigned];
}

if (strpos($col, 'boolean') !== false) {
return ['type' => 'boolean', 'length' => null];
}
if (strpos($col, 'int') !== false) {
return ['type' => 'integer', 'length' => $length];
}

if ($col === 'char' && $length === 36) {
return ['type' => 'uuid', 'length' => null];
}
Expand All @@ -80,9 +77,14 @@ protected function _convertColumn($column) {
if (strpos($col, 'char') !== false) {
return ['type' => 'string', 'length' => $length];
}
if (in_array($col, ['float', 'real', 'double'])) {
return ['type' => 'float', 'length' => null];

if (in_array($col, ['blob', 'clob'])) {
return ['type' => 'binary', 'length' => null];
}
if (in_array($col, ['date', 'time', 'timestamp', 'datetime'])) {
return ['type' => $col, 'length' => null];
}

return ['type' => 'text', 'length' => null];
}

Expand Down Expand Up @@ -239,6 +241,14 @@ public function columnSql(Table $table, $name) {
) {
$out .= '(' . (int)$data['length'] . ',' . (int)$data['precision'] . ')';
}
$hasUnsigned = ['biginteger', 'integer', 'float', 'decimal'];
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';
}
Expand Down
68 changes: 47 additions & 21 deletions Cake/Test/TestCase/Database/Schema/SqliteSchemaTest.php
@@ -1,7 +1,5 @@
<?php
/**
* PHP Version 5.4
*
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
*
Expand Down Expand Up @@ -63,7 +61,11 @@ public static function convertColumnProvider() {
],
[
'BIGINT',
['type' => 'biginteger', 'length' => null]
['type' => 'biginteger', 'length' => null, 'unsigned' => false]
],
[
'BIGINT UNSIGNED',
['type' => 'biginteger', 'length' => null, 'unsigned' => true]
],
[
'VARCHAR(255)',
Expand All @@ -83,31 +85,43 @@ public static function convertColumnProvider() {
],
[
'INTEGER(11)',
['type' => 'integer', 'length' => 11]
['type' => 'integer', 'length' => 11, 'unsigned' => false]
],
[
'INTEGER(11) UNSIGNED',
['type' => 'integer', 'length' => 11, 'unsigned' => true]
],
[
'TINYINT(5)',
['type' => 'integer', 'length' => 5]
['type' => 'integer', 'length' => 5, 'unsigned' => false]
],
[
'MEDIUMINT(10)',
['type' => 'integer', 'length' => 10]
['type' => 'integer', 'length' => 10, 'unsigned' => false]
],
[
'FLOAT',
['type' => 'float', 'length' => null]
['type' => 'float', 'length' => null, 'unsigned' => false]
],
[
'DOUBLE',
['type' => 'float', 'length' => null]
['type' => 'float', 'length' => null, 'unsigned' => false]
],
[
'DOUBLE UNSIGNED',
['type' => 'float', 'length' => null, 'unsigned' => true]
],
[
'REAL',
['type' => 'float', 'length' => null]
['type' => 'float', 'length' => null, 'unsigned' => false]
],
[
'DECIMAL(11,2)',
['type' => 'decimal', 'length' => null]
['type' => 'decimal', 'length' => null, 'unsigned' => false]
],
[
'DECIMAL(11,2) UNSIGNED',
['type' => 'decimal', 'length' => null, 'unsigned' => true]
],
];
}
Expand Down Expand Up @@ -214,8 +228,8 @@ public function testDescribeTable() {
'default' => null,
'length' => null,
'precision' => null,
'fixed' => null,
'comment' => null,
'unsigned' => false,
],
'title' => [
'type' => 'string',
Expand All @@ -232,16 +246,15 @@ public function testDescribeTable() {
'default' => null,
'length' => null,
'precision' => null,
'fixed' => null,
'comment' => null,
],
'author_id' => [
'type' => 'integer',
'null' => false,
'default' => null,
'length' => 11,
'unsigned' => false,
'precision' => null,
'fixed' => null,
'comment' => null,
],
'published' => [
Expand All @@ -250,7 +263,6 @@ public function testDescribeTable() {
'default' => 0,
'length' => null,
'precision' => null,
'fixed' => null,
'comment' => null,
],
'created' => [
Expand All @@ -259,7 +271,6 @@ public function testDescribeTable() {
'default' => null,
'length' => null,
'precision' => null,
'fixed' => null,
'comment' => null,
],
];
Expand Down Expand Up @@ -369,28 +380,38 @@ public static function columnSqlProvider() {
// Integers
[
'post_id',
['type' => 'integer', 'length' => 11],
['type' => 'integer', 'length' => 11, 'unsigned' => false],
'"post_id" INTEGER(11)'
],
[
'post_id',
['type' => 'biginteger', 'length' => 20],
['type' => 'biginteger', 'length' => 20, 'unsigned' => false],
'"post_id" BIGINT'
],
[
'post_id',
['type' => 'biginteger', 'length' => 20, 'unsigned' => true],
'"post_id" BIGINT UNSIGNED'
],
// Decimal
[
'value',
['type' => 'decimal'],
['type' => 'decimal', 'unsigned' => false],
'"value" DECIMAL'
],
[
'value',
['type' => 'decimal', 'length' => 11],
['type' => 'decimal', 'length' => 11, 'unsigned' => false],
'"value" DECIMAL(11,0)'
],
[
'value',
['type' => 'decimal', 'length' => 12, 'precision' => 5],
['type' => 'decimal', 'length' => 11, 'unsigned' => true],
'"value" DECIMAL(11,0) UNSIGNED'
],
[
'value',
['type' => 'decimal', 'length' => 12, 'precision' => 5, 'unsigned' => false],
'"value" DECIMAL(12,5)'
],
// Float
Expand All @@ -401,9 +422,14 @@ public static function columnSqlProvider() {
],
[
'value',
['type' => 'float', 'length' => 11, 'precision' => 3],
['type' => 'float', 'length' => 11, 'precision' => 3, 'unsigned' => false],
'"value" FLOAT(11,3)'
],
[
'value',
['type' => 'float', 'length' => 11, 'precision' => 3, 'unsigned' => true],
'"value" FLOAT(11,3) UNSIGNED'
],
// Boolean
[
'checked',
Expand Down

0 comments on commit d6c68b1

Please sign in to comment.