From 38101995b4404317a068e3278c756e70ea89b668 Mon Sep 17 00:00:00 2001 From: Sebastien Barre Date: Sun, 5 Mar 2017 12:25:14 -0500 Subject: [PATCH] introduce new tinyint, smallint types for smaller storage requirements --- lib/Cake/Model/Datasource/Database/Mysql.php | 46 ++--------- .../Model/Datasource/Database/Postgres.php | 6 ++ lib/Cake/Model/Datasource/Database/Sqlite.php | 4 + .../Model/Datasource/Database/Sqlserver.php | 10 +++ lib/Cake/Model/Datasource/DboSource.php | 24 ++---- .../Model/Datasource/Database/MysqlTest.php | 79 +++---------------- .../Datasource/Database/PostgresTest.php | 6 +- .../Model/Datasource/Database/SqliteTest.php | 22 ++++++ .../Datasource/Database/SqlserverTest.php | 10 +++ 9 files changed, 79 insertions(+), 128 deletions(-) diff --git a/lib/Cake/Model/Datasource/Database/Mysql.php b/lib/Cake/Model/Datasource/Database/Mysql.php index 4a01dc29ec4..de517a42f41 100644 --- a/lib/Cake/Model/Datasource/Database/Mysql.php +++ b/lib/Cake/Model/Datasource/Database/Mysql.php @@ -117,10 +117,8 @@ class Mysql extends DboSource { 'text' => array('name' => 'text'), 'biginteger' => array('name' => 'bigint', 'limit' => '20'), 'integer' => array('name' => 'int', 'limit' => '11', 'formatter' => 'intval'), - 'integer/4' => array('name' => 'int', 'limit' => '11', 'formatter' => 'intval'), - 'integer/3' => array('name' => 'mediumint', 'limit' => '9', 'formatter' => 'intval'), - 'integer/2' => array('name' => 'smallint', 'limit' => '6', 'formatter' => 'intval'), - 'integer/1' => array('name' => 'tinyint', 'limit' => '4', 'formatter' => 'intval'), + 'smallint' => array('name' => 'smallint', 'limit' => '6', 'formatter' => 'intval'), + 'tinyint' => array('name' => 'tinyint', 'limit' => '4', 'formatter' => 'intval'), 'float' => array('name' => 'float', 'formatter' => 'floatval'), 'decimal' => array('name' => 'decimal', 'formatter' => 'floatval'), 'datetime' => array('name' => 'datetime', 'format' => 'Y-m-d H:i:s', 'formatter' => 'date'), @@ -373,10 +371,6 @@ public function describe($model) { $fields[$column->Field]['charset'] = $charset; } } - $storage = $this->storageRequirement($column->Type); - if (is_numeric($storage)) { - $fields[$column->Field]['storage'] = $storage; - } } $this->_cacheDescription($key, $fields); $cols->closeCursor(); @@ -791,6 +785,12 @@ public function column($real) { if (strpos($col, 'bigint') !== false || $col === 'bigint') { return 'biginteger'; } + if (strpos($col, 'tinyint') !== false) { + return 'tinyint'; + } + if (strpos($col, 'smallint') !== false) { + return 'smallint'; + } if (strpos($col, 'int') !== false) { return 'integer'; } @@ -818,36 +818,6 @@ public function column($real) { return 'text'; } -/** - * Gets the storage requirement of a database-native column description, or null if unknown or N/A - * - * @param string $real Real database-layer column type (i.e. "varchar(255)") - * @return mixed An integer representing the storage requirement of the column in bytes, or null if unknown or N/A. - */ - public function storageRequirement($real) { - if (is_array($real)) { - $col = $real['name']; - } else { - $col = $real; - if (strpos($col, '(') !== false) { - list($col, $vals) = explode('(', $col); - } - } - - // Base on Storage Requirements for Numeric Types - // https://dev.mysql.com/doc/refman/5.7/en/storage-requirements.html - if ($col === 'tinyint') { - return 1; - } - if ($col === 'smallint') { - return 2; - } - if ($col === 'mediumint') { - return 3; - } - return null; - } - /** * {@inheritDoc} */ diff --git a/lib/Cake/Model/Datasource/Database/Postgres.php b/lib/Cake/Model/Datasource/Database/Postgres.php index 8673fbc5cfc..b8dbf462ac2 100644 --- a/lib/Cake/Model/Datasource/Database/Postgres.php +++ b/lib/Cake/Model/Datasource/Database/Postgres.php @@ -51,6 +51,8 @@ class Postgres extends DboSource { /** * Columns * + * @link https://www.postgresql.org/docs/9.6/static/datatype.html PostgreSQL Data Types + * * @var array */ public $columns = array( @@ -58,6 +60,8 @@ class Postgres extends DboSource { 'string' => array('name' => 'varchar', 'limit' => '255'), 'text' => array('name' => 'text'), 'integer' => array('name' => 'integer', 'formatter' => 'intval'), + 'smallint' => array('name' => 'smallint', 'formatter' => 'intval'), + 'tinyint' => array('name' => 'smallint', 'formatter' => 'intval'), 'biginteger' => array('name' => 'bigint', 'limit' => '20'), 'float' => array('name' => 'float', 'formatter' => 'floatval'), 'decimal' => array('name' => 'decimal', 'formatter' => 'floatval'), @@ -701,6 +705,8 @@ public function column($real) { return 'time'; case ($col === 'bigint'): return 'biginteger'; + case ($col === 'smallint'): + return 'smallint'; case (strpos($col, 'int') !== false && $col !== 'interval'): return 'integer'; case (strpos($col, 'char') !== false): diff --git a/lib/Cake/Model/Datasource/Database/Sqlite.php b/lib/Cake/Model/Datasource/Database/Sqlite.php index bfda2c8dd9a..6ad7b54bc6e 100644 --- a/lib/Cake/Model/Datasource/Database/Sqlite.php +++ b/lib/Cake/Model/Datasource/Database/Sqlite.php @@ -63,6 +63,8 @@ class Sqlite extends DboSource { /** * SQLite3 column definition * + * @link https://www.sqlite.org/datatype3.html Datatypes In SQLite Version 3 + * * @var array */ public $columns = array( @@ -70,6 +72,8 @@ class Sqlite extends DboSource { 'string' => array('name' => 'varchar', 'limit' => '255'), 'text' => array('name' => 'text'), 'integer' => array('name' => 'integer', 'limit' => null, 'formatter' => 'intval'), + 'smallint' => array('name' => 'integer', 'limit' => null, 'formatter' => 'intval'), + 'tinyint' => array('name' => 'integer', 'limit' => null, 'formatter' => 'intval'), 'biginteger' => array('name' => 'bigint', 'limit' => 20), 'float' => array('name' => 'float', 'formatter' => 'floatval'), 'decimal' => array('name' => 'decimal', 'formatter' => 'floatval'), diff --git a/lib/Cake/Model/Datasource/Database/Sqlserver.php b/lib/Cake/Model/Datasource/Database/Sqlserver.php index 90590e6ad2f..a25ecc04ac3 100644 --- a/lib/Cake/Model/Datasource/Database/Sqlserver.php +++ b/lib/Cake/Model/Datasource/Database/Sqlserver.php @@ -84,6 +84,8 @@ class Sqlserver extends DboSource { /** * MS SQL column definition * + * @link https://msdn.microsoft.com/en-us/library/ms187752.aspx SQL Server Data Types + * * @var array */ public $columns = array( @@ -91,6 +93,8 @@ class Sqlserver extends DboSource { 'string' => array('name' => 'nvarchar', 'limit' => '255'), 'text' => array('name' => 'nvarchar', 'limit' => 'MAX'), 'integer' => array('name' => 'int', 'formatter' => 'intval'), + 'smallint' => array('name' => 'smallint', 'formatter' => 'intval'), + 'tinyint' => array('name' => 'tinyint', 'formatter' => 'intval'), 'biginteger' => array('name' => 'bigint'), 'numeric' => array('name' => 'decimal', 'formatter' => 'floatval'), 'decimal' => array('name' => 'decimal', 'formatter' => 'floatval'), @@ -435,6 +439,12 @@ public function column($real) { if (strpos($col, 'bigint') !== false) { return 'biginteger'; } + if (strpos($col, 'smallint') !== false) { + return 'smallint'; + } + if (strpos($col, 'tinyint') !== false) { + return 'tinyint'; + } if (strpos($col, 'int') !== false) { return 'integer'; } diff --git a/lib/Cake/Model/Datasource/DboSource.php b/lib/Cake/Model/Datasource/DboSource.php index 2491bb9536f..f69144746ea 100644 --- a/lib/Cake/Model/Datasource/DboSource.php +++ b/lib/Cake/Model/Datasource/DboSource.php @@ -3246,16 +3246,6 @@ public function length($real) { return (int)$length; } -/** - * Gets the storage requirement of a database-native column description, or null if unknown or N/A - * - * @param string $real Real database-layer column type (i.e. "varchar(255)") - * @return mixed An integer representing the storage requirement of the column in bytes, or null if unknown or N/A. - */ - public function storageRequirement($real) { - return null; - } - /** * Translates between PHP boolean values and Database (faked) boolean values * @@ -3469,16 +3459,12 @@ public function buildColumn($column) { return null; } - // if a storage requirement in bytes was set, try it first (i.e. 'integer/4' before 'integer') - if (isset($storage) && isset($this->columns[$type . '/' . $storage])) { - $real = $this->columns[$type . '/' . $storage]; - } else { - if (!isset($this->columns[$type])) { - trigger_error(__d('cake_dev', 'Column type %s does not exist', $type), E_USER_WARNING); - return null; - } - $real = $this->columns[$type]; + if (!isset($this->columns[$type])) { + trigger_error(__d('cake_dev', 'Column type %s does not exist', $type), E_USER_WARNING); + return null; } + + $real = $this->columns[$type]; $out = $this->name($name) . ' ' . $real['name']; if (isset($column['length'])) { diff --git a/lib/Cake/Test/Case/Model/Datasource/Database/MysqlTest.php b/lib/Cake/Test/Case/Model/Datasource/Database/MysqlTest.php index cd0beaef5dd..9bd6faf91a9 100644 --- a/lib/Cake/Test/Case/Model/Datasource/Database/MysqlTest.php +++ b/lib/Cake/Test/Case/Model/Datasource/Database/MysqlTest.php @@ -201,7 +201,7 @@ public function testScientificNotation() { public function testTinyintCasting() { $this->Dbo->cacheSources = false; $tableName = 'tinyint_' . uniqid(); - $this->Dbo->rawQuery('CREATE TABLE ' . $this->Dbo->fullTableName($tableName) . ' (id int(11) AUTO_INCREMENT, bool tinyint(1), small_int tinyint(2), primary key(id));'); + $this->Dbo->rawQuery('CREATE TABLE ' . $this->Dbo->fullTableName($tableName) . ' (id int(11) AUTO_INCREMENT, bool tinyint(1), tiny_int tinyint(2), primary key(id));'); $this->model = new CakeTestModel(array( 'name' => 'Tinyint', 'table' => $tableName, 'ds' => 'test' @@ -209,24 +209,24 @@ public function testTinyintCasting() { $result = $this->model->schema(); $this->assertEquals('boolean', $result['bool']['type']); - $this->assertEquals('integer', $result['small_int']['type']); + $this->assertEquals('tinyint', $result['tiny_int']['type']); - $this->assertTrue((bool)$this->model->save(array('bool' => 5, 'small_int' => 5))); + $this->assertTrue((bool)$this->model->save(array('bool' => 5, 'tiny_int' => 5))); $result = $this->model->find('first'); $this->assertTrue($result['Tinyint']['bool']); - $this->assertSame($result['Tinyint']['small_int'], '5'); + $this->assertSame($result['Tinyint']['tiny_int'], '5'); $this->model->deleteAll(true); - $this->assertTrue((bool)$this->model->save(array('bool' => 0, 'small_int' => 100))); + $this->assertTrue((bool)$this->model->save(array('bool' => 0, 'tiny_int' => 100))); $result = $this->model->find('first'); $this->assertFalse($result['Tinyint']['bool']); - $this->assertSame($result['Tinyint']['small_int'], '100'); + $this->assertSame($result['Tinyint']['tiny_int'], '100'); $this->model->deleteAll(true); - $this->assertTrue((bool)$this->model->save(array('bool' => true, 'small_int' => 0))); + $this->assertTrue((bool)$this->model->save(array('bool' => true, 'tiny_int' => 0))); $result = $this->model->find('first'); $this->assertTrue($result['Tinyint']['bool']); - $this->assertSame($result['Tinyint']['small_int'], '0'); + $this->assertSame($result['Tinyint']['tiny_int'], '0'); $this->model->deleteAll(true); $this->Dbo->rawQuery('DROP TABLE ' . $this->Dbo->fullTableName($tableName)); @@ -389,36 +389,6 @@ public function testBuildColumn() { $expected = '`testName` CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL'; $this->assertEquals($expected, $result); $this->Dbo->columns = $restore; - - $data = array( - 'name' => 'testName', - 'type' => 'integer', - 'storage' => 1 - ); - $result = $this->Dbo->buildColumn($data); - $expected = '`testName` tinyint(4)'; - $this->assertEquals($expected, $result); - $this->Dbo->columns = $restore; - - $data = array( - 'name' => 'testName', - 'type' => 'integer', - 'storage' => 2 - ); - $result = $this->Dbo->buildColumn($data); - $expected = '`testName` smallint(6)'; - $this->assertEquals($expected, $result); - $this->Dbo->columns = $restore; - - $data = array( - 'name' => 'testName', - 'type' => 'integer', - 'storage' => 3 - ); - $result = $this->Dbo->buildColumn($data); - $expected = '`testName` mediumint(9)'; - $this->assertEquals($expected, $result); - $this->Dbo->columns = $restore; } /** @@ -556,16 +526,12 @@ public function testColumn() { $expected = 'boolean'; $this->assertEquals($expected, $result); - $result = $this->Dbo->column('tinyint(4)'); - $expected = 'integer'; + $result = $this->Dbo->column('tinyint'); + $expected = 'tinyint'; $this->assertEquals($expected, $result); $result = $this->Dbo->column('smallint'); - $expected = 'integer'; - $this->assertEquals($expected, $result); - - $result = $this->Dbo->column('mediumint'); - $expected = 'integer'; + $expected = 'smallint'; $this->assertEquals($expected, $result); $result = $this->Dbo->column('boolean'); @@ -3134,29 +3100,6 @@ public function testLength() { $this->assertSame($expected, $result); } -/** - * test storageRequirement method - * - * @return void - */ - public function testStorageRequirement() { - $result = $this->Dbo->storageRequirement('varchar(255)'); - $expected = null; - $this->assertSame($expected, $result); - - $result = $this->Dbo->storageRequirement('mediumint'); - $expected = 3; - $this->assertSame($expected, $result); - - $result = $this->Dbo->storageRequirement('smallint'); - $expected = 2; - $this->assertSame($expected, $result); - - $result = $this->Dbo->storageRequirement('tinyint'); - $expected = 1; - $this->assertSame($expected, $result); - } - /** * testBuildIndex method * diff --git a/lib/Cake/Test/Case/Model/Datasource/Database/PostgresTest.php b/lib/Cake/Test/Case/Model/Datasource/Database/PostgresTest.php index 9158efcd247..68db54f3314 100644 --- a/lib/Cake/Test/Case/Model/Datasource/Database/PostgresTest.php +++ b/lib/Cake/Test/Case/Model/Datasource/Database/PostgresTest.php @@ -304,9 +304,9 @@ public function testColumnParsing() { $this->assertEquals('float', $this->Dbo2->column('double precision')); $this->assertEquals('uuid', $this->Dbo2->column('uuid')); - $result = $this->Dbo2->column('bigint'); - $expected = 'biginteger'; - $this->assertEquals($expected, $result); + $this->assertEquals('biginteger', $this->Dbo2->column('bigint')); + $this->assertEquals('integer', $this->Dbo2->column('integer')); + $this->assertEquals('smallint', $this->Dbo2->column('smallint')); } /** diff --git a/lib/Cake/Test/Case/Model/Datasource/Database/SqliteTest.php b/lib/Cake/Test/Case/Model/Datasource/Database/SqliteTest.php index 8f831a671f8..bc32275f877 100644 --- a/lib/Cake/Test/Case/Model/Datasource/Database/SqliteTest.php +++ b/lib/Cake/Test/Case/Model/Datasource/Database/SqliteTest.php @@ -263,6 +263,28 @@ public function testBuildColumn() { $expected = '"testName" integer(10) DEFAULT 10 NOT NULL'; $this->assertEquals($expected, $result); + $data = array( + 'name' => 'testName', + 'type' => 'smallint', + 'length' => 6, + 'default' => 6, + 'null' => false, + ); + $result = $this->Dbo->buildColumn($data); + $expected = '"testName" integer(6) DEFAULT 6 NOT NULL'; + $this->assertEquals($expected, $result); + + $data = array( + 'name' => 'testName', + 'type' => 'tinyint', + 'length' => 4, + 'default' => 4, + 'null' => false, + ); + $result = $this->Dbo->buildColumn($data); + $expected = '"testName" integer(4) DEFAULT 4 NOT NULL'; + $this->assertEquals($expected, $result); + $data = array( 'name' => 'huge', 'type' => 'biginteger', diff --git a/lib/Cake/Test/Case/Model/Datasource/Database/SqlserverTest.php b/lib/Cake/Test/Case/Model/Datasource/Database/SqlserverTest.php index 81fa8e7b2f1..5d7df51ad19 100644 --- a/lib/Cake/Test/Case/Model/Datasource/Database/SqlserverTest.php +++ b/lib/Cake/Test/Case/Model/Datasource/Database/SqlserverTest.php @@ -532,6 +532,16 @@ public function testBuildColumn() { $expected = '[client_id] int NULL'; $this->assertEquals($expected, $result); + $column = array('type' => 'smallint', 'name' => 'client_id'); + $result = $this->db->buildColumn($column); + $expected = '[client_id] smallint NULL'; + $this->assertEquals($expected, $result); + + $column = array('type' => 'tinyint', 'name' => 'client_id'); + $result = $this->db->buildColumn($column); + $expected = '[client_id] tinyint NULL'; + $this->assertEquals($expected, $result); + $column = array('type' => 'string', 'name' => 'name'); $result = $this->db->buildColumn($column); $expected = '[name] nvarchar(255) NULL';