From 7fb51ab50ffa68f48728c3fc83da44ea33fcb45d Mon Sep 17 00:00:00 2001 From: U-Zyn Chua Date: Sat, 28 Sep 2013 09:23:46 +0800 Subject: [PATCH 1/8] Decimal support for MySQL. #3171 --- lib/Cake/Model/Datasource/Database/Mysql.php | 6 +++++- lib/Cake/Test/Case/Model/Datasource/Database/MysqlTest.php | 6 +++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/lib/Cake/Model/Datasource/Database/Mysql.php b/lib/Cake/Model/Datasource/Database/Mysql.php index 5211f3422..11f9c8f09 100644 --- a/lib/Cake/Model/Datasource/Database/Mysql.php +++ b/lib/Cake/Model/Datasource/Database/Mysql.php @@ -112,6 +112,7 @@ class Mysql extends DboSource { 'biginteger' => array('name' => 'bigint', 'limit' => '20'), 'integer' => array('name' => 'int', 'limit' => '11', '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'), 'timestamp' => array('name' => 'timestamp', 'format' => 'Y-m-d H:i:s', 'formatter' => 'date'), 'time' => array('name' => 'time', 'format' => 'H:i:s', 'formatter' => 'date'), @@ -763,9 +764,12 @@ class Mysql extends DboSource { if (strpos($col, 'blob') !== false || $col === 'binary') { return 'binary'; } - if (strpos($col, 'float') !== false || strpos($col, 'double') !== false || strpos($col, 'decimal') !== false) { + if (strpos($col, 'float') !== false || strpos($col, 'double') !== false) { return 'float'; } + if (strpos($col, 'decimal') !== false) { + return 'decimal'; + } if (strpos($col, 'enum') !== false) { return "enum($vals)"; } diff --git a/lib/Cake/Test/Case/Model/Datasource/Database/MysqlTest.php b/lib/Cake/Test/Case/Model/Datasource/Database/MysqlTest.php index 09c7d221c..a42f2b78f 100644 --- a/lib/Cake/Test/Case/Model/Datasource/Database/MysqlTest.php +++ b/lib/Cake/Test/Case/Model/Datasource/Database/MysqlTest.php @@ -543,8 +543,12 @@ class MysqlTest extends CakeTestCase { $expected = 'float'; $this->assertEquals($expected, $result); + $result = $this->Dbo->column('decimal'); + $expected = 'decimal'; + $this->assertEquals($expected, $result); + $result = $this->Dbo->column('decimal(14,7) unsigned'); - $expected = 'float'; + $expected = 'decimal'; $this->assertEquals($expected, $result); } From a1a3e70039cc6bdd43d6bb36cb69829713a6e5f7 Mon Sep 17 00:00:00 2001 From: U-Zyn Chua Date: Sat, 28 Sep 2013 14:07:00 +0800 Subject: [PATCH 2/8] Decimal support for PostgreSQL. #3171 --- lib/Cake/Model/Datasource/Database/Postgres.php | 5 ++++- .../Test/Case/Model/Datasource/Database/PostgresTest.php | 4 ++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/lib/Cake/Model/Datasource/Database/Postgres.php b/lib/Cake/Model/Datasource/Database/Postgres.php index d8a6e0f42..8dca7c7d8 100644 --- a/lib/Cake/Model/Datasource/Database/Postgres.php +++ b/lib/Cake/Model/Datasource/Database/Postgres.php @@ -62,6 +62,7 @@ class Postgres extends DboSource { 'integer' => array('name' => 'integer', 'formatter' => 'intval'), 'biginteger' => array('name' => 'bigint', 'limit' => '20'), 'float' => array('name' => 'float', 'formatter' => 'floatval'), + 'decimal' => array('name' => 'decimal', 'formatter' => 'floatval'), 'datetime' => array('name' => 'timestamp', 'format' => 'Y-m-d H:i:s', 'formatter' => 'date'), 'timestamp' => array('name' => 'timestamp', 'format' => 'Y-m-d H:i:s', 'formatter' => 'date'), 'time' => array('name' => 'time', 'format' => 'H:i:s', 'formatter' => 'date'), @@ -665,7 +666,7 @@ class Postgres extends DboSource { } $floats = array( - 'float', 'float4', 'float8', 'double', 'double precision', 'decimal', 'real', 'numeric' + 'float', 'float4', 'float8', 'double', 'double precision', 'real' ); switch (true) { @@ -685,6 +686,8 @@ class Postgres extends DboSource { return 'text'; case (strpos($col, 'bytea') !== false): return 'binary'; + case ($col === 'decimal' || $col === 'numeric'): + return 'decimal'; case (in_array($col, $floats)): return 'float'; default: diff --git a/lib/Cake/Test/Case/Model/Datasource/Database/PostgresTest.php b/lib/Cake/Test/Case/Model/Datasource/Database/PostgresTest.php index 937c8ae3d..58f8f29fc 100644 --- a/lib/Cake/Test/Case/Model/Datasource/Database/PostgresTest.php +++ b/lib/Cake/Test/Case/Model/Datasource/Database/PostgresTest.php @@ -295,6 +295,10 @@ class PostgresTest extends CakeTestCase { $this->assertEquals('string', $this->Dbo2->column('character varying')); $this->assertEquals('time', $this->Dbo2->column('time without time zone')); $this->assertEquals('datetime', $this->Dbo2->column('timestamp without time zone')); + $this->assertEquals('decimal', $this->Dbo2->column('decimal')); + $this->assertEquals('decimal', $this->Dbo2->column('numeric')); + $this->assertEquals('float', $this->Dbo2->column('float')); + $this->assertEquals('float', $this->Dbo2->column('double precision')); $result = $this->Dbo2->column('bigint'); $expected = 'biginteger'; From e0eb8f8e18da7f23f85119b78eae735230115a89 Mon Sep 17 00:00:00 2001 From: U-Zyn Chua Date: Sat, 28 Sep 2013 14:29:39 +0800 Subject: [PATCH 3/8] Added decimal CakeSchema test case and DatatypeFixture. #3171 --- lib/Cake/Test/Case/Model/CakeSchemaTest.php | 1 + lib/Cake/Test/Fixture/DatatypeFixture.php | 1 + 2 files changed, 2 insertions(+) diff --git a/lib/Cake/Test/Case/Model/CakeSchemaTest.php b/lib/Cake/Test/Case/Model/CakeSchemaTest.php index 07afe7fee..9ef077833 100644 --- a/lib/Cake/Test/Case/Model/CakeSchemaTest.php +++ b/lib/Cake/Test/Case/Model/CakeSchemaTest.php @@ -174,6 +174,7 @@ class TestAppSchema extends CakeSchema { public $datatypes = array( 'id' => array('type' => 'integer', 'null' => false, 'default' => 0, 'key' => 'primary'), 'float_field' => array('type' => 'float', 'null' => false, 'length' => '5,2', 'default' => ''), + 'decimal_field' => array('type' => 'decimal', 'length' => '6,3', 'default' => '0.000'), 'huge_int' => array('type' => 'biginteger'), 'bool' => array('type' => 'boolean', 'null' => false, 'default' => false), 'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => true)), diff --git a/lib/Cake/Test/Fixture/DatatypeFixture.php b/lib/Cake/Test/Fixture/DatatypeFixture.php index 413ca74e3..aacafdc4f 100644 --- a/lib/Cake/Test/Fixture/DatatypeFixture.php +++ b/lib/Cake/Test/Fixture/DatatypeFixture.php @@ -33,6 +33,7 @@ class DatatypeFixture extends CakeTestFixture { public $fields = array( 'id' => array('type' => 'integer', 'null' => false, 'default' => 0, 'key' => 'primary'), 'float_field' => array('type' => 'float', 'length' => '5,2', 'null' => false, 'default' => null), + 'decimal_field' => array('type' => 'decimal', 'length' => '6,3', 'default' => '0.000'), 'huge_int' => array('type' => 'biginteger'), 'bool' => array('type' => 'boolean', 'null' => false, 'default' => false), ); From c74c8d49a1eb94f935ef0ffecc558df2ccb26129 Mon Sep 17 00:00:00 2001 From: U-Zyn Chua Date: Sat, 28 Sep 2013 14:36:55 +0800 Subject: [PATCH 4/8] Decimal support for SQLite. #3171 --- lib/Cake/Model/Datasource/Database/Sqlite.php | 3 ++- lib/Cake/Test/Case/Model/Datasource/Database/SqliteTest.php | 6 ++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/lib/Cake/Model/Datasource/Database/Sqlite.php b/lib/Cake/Model/Datasource/Database/Sqlite.php index 8251fc34b..6a7f3576a 100644 --- a/lib/Cake/Model/Datasource/Database/Sqlite.php +++ b/lib/Cake/Model/Datasource/Database/Sqlite.php @@ -73,6 +73,7 @@ class Sqlite extends DboSource { 'integer' => 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'), 'datetime' => array('name' => 'datetime', 'format' => 'Y-m-d H:i:s', 'formatter' => 'date'), 'timestamp' => array('name' => 'timestamp', 'format' => 'Y-m-d H:i:s', 'formatter' => 'date'), 'time' => array('name' => 'time', 'format' => 'H:i:s', 'formatter' => 'date'), @@ -278,7 +279,7 @@ class Sqlite extends DboSource { return 'binary'; } if (strpos($col, 'numeric') !== false || strpos($col, 'decimal') !== false) { - return 'float'; + return 'decimal'; } return 'text'; } diff --git a/lib/Cake/Test/Case/Model/Datasource/Database/SqliteTest.php b/lib/Cake/Test/Case/Model/Datasource/Database/SqliteTest.php index a121da575..5fae5688c 100644 --- a/lib/Cake/Test/Case/Model/Datasource/Database/SqliteTest.php +++ b/lib/Cake/Test/Case/Model/Datasource/Database/SqliteTest.php @@ -363,6 +363,12 @@ class SqliteTest extends CakeTestCase { 'default' => '', 'length' => '5,2', ), + 'decimal_field' => array( + 'type' => 'decimal', + 'null' => true, + 'default' => '0.000', + 'length' => '6,3', + ), 'huge_int' => array( 'type' => 'biginteger', 'null' => true, From 73cae88a6f959f9386b220fa0caff30ac8212043 Mon Sep 17 00:00:00 2001 From: U-Zyn Chua Date: Sat, 28 Sep 2013 22:48:37 +0800 Subject: [PATCH 5/8] SQL Server support of numeric type. #3171 Float & real map to float. Numeric & decimal map to numeric. --- lib/Cake/Model/Datasource/Database/Sqlserver.php | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/lib/Cake/Model/Datasource/Database/Sqlserver.php b/lib/Cake/Model/Datasource/Database/Sqlserver.php index 81169b44e..a64c6fd90 100644 --- a/lib/Cake/Model/Datasource/Database/Sqlserver.php +++ b/lib/Cake/Model/Datasource/Database/Sqlserver.php @@ -93,7 +93,10 @@ class Sqlserver extends DboSource { 'text' => array('name' => 'nvarchar', 'limit' => 'MAX'), 'integer' => array('name' => 'int', 'formatter' => 'intval'), 'biginteger' => array('name' => 'bigint'), - 'float' => array('name' => 'numeric', 'formatter' => 'floatval'), + 'numeric' => array('name' => 'decimal', 'formatter' => 'floatval'), + 'decimal' => array('name' => 'decimal', 'formatter' => 'floatval'), + 'float' => array('name' => 'float', 'formatter' => 'floatval'), + 'real' => array('name' => 'float', 'formatter' => 'floatval'), 'datetime' => array('name' => 'datetime', 'format' => 'Y-m-d H:i:s', 'formatter' => 'date'), 'timestamp' => array('name' => 'timestamp', 'format' => 'Y-m-d H:i:s', 'formatter' => 'date'), 'time' => array('name' => 'datetime', 'format' => 'H:i:s', 'formatter' => 'date'), @@ -441,9 +444,12 @@ class Sqlserver extends DboSource { if (strpos($col, 'binary') !== false || $col === 'image') { return 'binary'; } - if (in_array($col, array('float', 'real', 'decimal', 'numeric'))) { + if (in_array($col, array('float', 'real'))) { return 'float'; } + if (in_array($col, array('decimal', 'numeric'))) { + return 'decimal'; + } return 'text'; } From e527506c397dc07c38e89bd59b77f326992c4a17 Mon Sep 17 00:00:00 2001 From: U-Zyn Chua Date: Sat, 28 Sep 2013 23:05:53 +0800 Subject: [PATCH 6/8] MySQL: Numeric data type now supported under decimal column. #3171 --- lib/Cake/Model/Datasource/Database/Mysql.php | 3 ++- lib/Cake/Test/Case/Model/Datasource/Database/MysqlTest.php | 4 ++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/Cake/Model/Datasource/Database/Mysql.php b/lib/Cake/Model/Datasource/Database/Mysql.php index 11f9c8f09..33b44c558 100644 --- a/lib/Cake/Model/Datasource/Database/Mysql.php +++ b/lib/Cake/Model/Datasource/Database/Mysql.php @@ -112,6 +112,7 @@ class Mysql extends DboSource { 'biginteger' => array('name' => 'bigint', 'limit' => '20'), 'integer' => array('name' => 'int', 'limit' => '11', 'formatter' => 'intval'), 'float' => array('name' => 'float', 'formatter' => 'floatval'), + 'numeric' => array('name' => 'decimal', 'formatter' => 'floatval'), 'decimal' => array('name' => 'decimal', 'formatter' => 'floatval'), 'datetime' => array('name' => 'datetime', 'format' => 'Y-m-d H:i:s', 'formatter' => 'date'), 'timestamp' => array('name' => 'timestamp', 'format' => 'Y-m-d H:i:s', 'formatter' => 'date'), @@ -767,7 +768,7 @@ class Mysql extends DboSource { if (strpos($col, 'float') !== false || strpos($col, 'double') !== false) { return 'float'; } - if (strpos($col, 'decimal') !== false) { + if (strpos($col, 'decimal') !== false || strpos($col, 'numeric') !== false) { return 'decimal'; } if (strpos($col, 'enum') !== false) { diff --git a/lib/Cake/Test/Case/Model/Datasource/Database/MysqlTest.php b/lib/Cake/Test/Case/Model/Datasource/Database/MysqlTest.php index a42f2b78f..c1a382490 100644 --- a/lib/Cake/Test/Case/Model/Datasource/Database/MysqlTest.php +++ b/lib/Cake/Test/Case/Model/Datasource/Database/MysqlTest.php @@ -547,6 +547,10 @@ class MysqlTest extends CakeTestCase { $expected = 'decimal'; $this->assertEquals($expected, $result); + $result = $this->Dbo->column('numeric'); + $expected = 'decimal'; + $this->assertEquals($expected, $result); + $result = $this->Dbo->column('decimal(14,7) unsigned'); $expected = 'decimal'; $this->assertEquals($expected, $result); From 091658a7529c3775434e9d567035d3ec7ff736fa Mon Sep 17 00:00:00 2001 From: U-Zyn Chua Date: Sun, 29 Sep 2013 22:40:35 +0800 Subject: [PATCH 7/8] Decimal support for FormHelper. --- lib/Cake/Test/Case/View/Helper/FormHelperTest.php | 12 ++++++++++++ lib/Cake/View/Helper/FormHelper.php | 2 +- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/lib/Cake/Test/Case/View/Helper/FormHelperTest.php b/lib/Cake/Test/Case/View/Helper/FormHelperTest.php index 97dd8a0ae..a3c39aeeb 100644 --- a/lib/Cake/Test/Case/View/Helper/FormHelperTest.php +++ b/lib/Cake/Test/Case/View/Helper/FormHelperTest.php @@ -354,6 +354,7 @@ class ValidateUser extends CakeTestModel { 'name' => array('type' => 'string', 'null' => '', 'default' => '', 'length' => '255'), 'email' => array('type' => 'string', 'null' => '', 'default' => '', 'length' => '255'), 'balance' => array('type' => 'float', 'null' => false, 'length' => '5,2'), + 'cost_decimal' => array('type' => 'decimal', 'null' => false, 'length' => '6,3'), 'created' => array('type' => 'date', 'null' => '1', 'default' => '', 'length' => ''), 'updated' => array('type' => 'datetime', 'null' => '1', 'default' => '', 'length' => null) ); @@ -1876,6 +1877,17 @@ class FormHelperTest extends CakeTestCase { ); $this->assertTags($result, $expected); + $result = $this->Form->input('ValidateUser.cost_decimal'); + $expected = array( + 'div' => array('class'), + 'label' => array('for'), + 'Cost Decimal', + '/label', + 'input' => array('name', 'type' => 'number', 'id'), + '/div', + ); + $this->assertTags($result, $expected); + $result = $this->Form->input('Contact.email', array('id' => 'custom')); $expected = array( 'div' => array('class' => 'input email'), diff --git a/lib/Cake/View/Helper/FormHelper.php b/lib/Cake/View/Helper/FormHelper.php index 377728b8f..11f2fc070 100644 --- a/lib/Cake/View/Helper/FormHelper.php +++ b/lib/Cake/View/Helper/FormHelper.php @@ -1147,7 +1147,7 @@ class FormHelper extends AppHelper { 'boolean' => 'checkbox', 'timestamp' => 'datetime', 'text' => 'textarea', 'time' => 'time', 'date' => 'date', 'float' => 'number', - 'integer' => 'number' + 'integer' => 'number', 'decimal' => 'number' ); if (isset($this->map[$type])) { From 4806d09d7e3a118fc65d98f082d8a75687339ec8 Mon Sep 17 00:00:00 2001 From: U-Zyn Chua Date: Sun, 29 Sep 2013 22:44:50 +0800 Subject: [PATCH 8/8] Setting of step for decimal field based on precision. --- lib/Cake/Test/Case/View/Helper/FormHelperTest.php | 2 +- lib/Cake/View/Helper/FormHelper.php | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/lib/Cake/Test/Case/View/Helper/FormHelperTest.php b/lib/Cake/Test/Case/View/Helper/FormHelperTest.php index a3c39aeeb..f8712b409 100644 --- a/lib/Cake/Test/Case/View/Helper/FormHelperTest.php +++ b/lib/Cake/Test/Case/View/Helper/FormHelperTest.php @@ -1883,7 +1883,7 @@ class FormHelperTest extends CakeTestCase { 'label' => array('for'), 'Cost Decimal', '/label', - 'input' => array('name', 'type' => 'number', 'id'), + 'input' => array('name', 'type' => 'number', 'step' => '0.001', 'id'), '/div', ); $this->assertTags($result, $expected); diff --git a/lib/Cake/View/Helper/FormHelper.php b/lib/Cake/View/Helper/FormHelper.php index 11f2fc070..f7f2fbb63 100644 --- a/lib/Cake/View/Helper/FormHelper.php +++ b/lib/Cake/View/Helper/FormHelper.php @@ -1160,10 +1160,13 @@ class FormHelper extends AppHelper { } if ( $options['type'] === 'number' && - $type === 'float' && !isset($options['step']) ) { - $options['step'] = 'any'; + if ($type === 'decimal') { + $options['step'] = pow(10, -1 * substr($fieldDef['length'], strpos($fieldDef['length'], ',') + 1)); + } elseif ($type === 'float') { + $options['step'] = 'any'; + } } }