diff --git a/lib/Cake/Model/Datasource/Database/Mysql.php b/lib/Cake/Model/Datasource/Database/Mysql.php index 5211f3422..33b44c558 100644 --- a/lib/Cake/Model/Datasource/Database/Mysql.php +++ b/lib/Cake/Model/Datasource/Database/Mysql.php @@ -112,6 +112,8 @@ 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'), 'time' => array('name' => 'time', 'format' => 'H:i:s', 'formatter' => 'date'), @@ -763,9 +765,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 || strpos($col, 'numeric') !== false) { + return 'decimal'; + } if (strpos($col, 'enum') !== false) { return "enum($vals)"; } 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/Model/Datasource/Database/Sqlite.php b/lib/Cake/Model/Datasource/Database/Sqlite.php index af9d55a03..37278c98d 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'), @@ -280,7 +281,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/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'; } diff --git a/lib/Cake/Test/Case/Model/CakeSchemaTest.php b/lib/Cake/Test/Case/Model/CakeSchemaTest.php index 244568adc..2404d116a 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/Case/Model/Datasource/Database/MysqlTest.php b/lib/Cake/Test/Case/Model/Datasource/Database/MysqlTest.php index 09c7d221c..c1a382490 100644 --- a/lib/Cake/Test/Case/Model/Datasource/Database/MysqlTest.php +++ b/lib/Cake/Test/Case/Model/Datasource/Database/MysqlTest.php @@ -543,8 +543,16 @@ 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('numeric'); + $expected = 'decimal'; + $this->assertEquals($expected, $result); + $result = $this->Dbo->column('decimal(14,7) unsigned'); - $expected = 'float'; + $expected = 'decimal'; $this->assertEquals($expected, $result); } 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'; diff --git a/lib/Cake/Test/Case/Model/Datasource/Database/SqliteTest.php b/lib/Cake/Test/Case/Model/Datasource/Database/SqliteTest.php index 403b46e06..f9dbeca49 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, diff --git a/lib/Cake/Test/Case/View/Helper/FormHelperTest.php b/lib/Cake/Test/Case/View/Helper/FormHelperTest.php index 1f3dd51d9..4ff0bd655 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', 'step' => '0.001', '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/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), ); diff --git a/lib/Cake/View/Helper/FormHelper.php b/lib/Cake/View/Helper/FormHelper.php index 709c4d0b1..c7650125f 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])) { @@ -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'; + } } }