Browse Source

Merge pull request #4262 from cakephp/3.0-nullable-types

3.0 Make Integer, Float and Date/Time types handle '' better
José Lorenzo Rodríguez 11 years ago
parent
commit
ee14edf7f2

+ 4 - 4
src/Database/Type.php

@@ -31,8 +31,12 @@ class Type {
  * @var array
  */
 	protected static $_types = [
+		'biginteger' => 'Cake\Database\Type\IntegerType',
 		'binary' => 'Cake\Database\Type\BinaryType',
 		'date' => 'Cake\Database\Type\DateType',
+		'float' => 'Cake\Database\Type\FloatType',
+		'decimal' => 'Cake\Database\Type\FloatType',
+		'integer' => 'Cake\Database\Type\IntegerType',
 		'time' => 'Cake\Database\Type\TimeType',
 		'datetime' => 'Cake\Database\Type\DateTimeType',
 		'timestamp' => 'Cake\Database\Type\DateTimeType',
@@ -46,10 +50,6 @@ class Type {
  * @var array
  */
 	protected static $_basicTypes = [
-		'float' => ['callback' => 'floatval'],
-		'decimal' => ['callback' => 'floatval'],
-		'integer' => ['callback' => 'intval', 'pdo' => PDO::PARAM_INT],
-		'biginteger' => ['callback' => 'intval', 'pdo' => PDO::PARAM_INT],
 		'string' => ['callback' => 'strval'],
 		'text' => ['callback' => 'strval'],
 		'boolean' => [

+ 1 - 1
src/Database/Type/DateTimeType.php

@@ -95,7 +95,7 @@ class DateTimeType extends \Cake\Database\Type {
 		$class = static::$dateTimeClass;
 		try {
 			if ($value === '' || $value === null || $value === false || $value === true) {
-				return $value;
+				return null;
 			} elseif (is_numeric($value)) {
 				$date = new $class('@' . $value);
 			} elseif (is_string($value)) {

+ 81 - 0
src/Database/Type/FloatType.php

@@ -0,0 +1,81 @@
+<?php
+/**
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * For full copyright and license information, please see the LICENSE.txt
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link          http://cakephp.org CakePHP(tm) Project
+ * @since         3.0.0
+ * @license       http://www.opensource.org/licenses/mit-license.php MIT License
+ */
+namespace Cake\Database\Type;
+
+use Cake\Database\Driver;
+use Cake\Error;
+use \PDO;
+
+/**
+ * Float type converter.
+ *
+ * Use to convert float/decimal data between PHP and the database types.
+ */
+class FloatType extends \Cake\Database\Type {
+
+/**
+ * Convert integer data into the database format.
+ *
+ * @param string|resource $value The value to convert.
+ * @param Driver $driver The driver instance to convert with.
+ * @return string|resource
+ */
+	public function toDatabase($value, Driver $driver) {
+		if ($value === null || $value === '') {
+			return null;
+		}
+		return floatval($value);
+	}
+
+/**
+ * Convert float values to PHP integers
+ *
+ * @param null|string|resource $value The value to convert.
+ * @param Driver $driver The driver instance to convert with.
+ * @return resource
+ * @throws \Cake\Error\Exception
+ */
+	public function toPHP($value, Driver $driver) {
+		if ($value === null) {
+			return null;
+		}
+		return floatval($value);
+	}
+
+/**
+ * Get the correct PDO binding type for integer data.
+ *
+ * @param mixed $value The value being bound.
+ * @param Driver $driver The driver.
+ * @return int
+ */
+	public function toStatement($value, Driver $driver) {
+		return PDO::PARAM_STR;
+	}
+
+/**
+ * Marshalls request data into PHP floats.
+ *
+ * @param mixed $value The value to convert.
+ * @return mixed Converted value.
+ */
+	public function marshal($value) {
+		if ($value === null || $value === '') {
+			return null;
+		}
+		return floatval($value);
+	}
+
+}

+ 81 - 0
src/Database/Type/IntegerType.php

@@ -0,0 +1,81 @@
+<?php
+/**
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * For full copyright and license information, please see the LICENSE.txt
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link          http://cakephp.org CakePHP(tm) Project
+ * @since         3.0.0
+ * @license       http://www.opensource.org/licenses/mit-license.php MIT License
+ */
+namespace Cake\Database\Type;
+
+use Cake\Database\Driver;
+use Cake\Error;
+use \PDO;
+
+/**
+ * Integer type converter.
+ *
+ * Use to convert integer data between PHP and the database types.
+ */
+class IntegerType extends \Cake\Database\Type {
+
+/**
+ * Convert integer data into the database format.
+ *
+ * @param string|resource $value The value to convert.
+ * @param Driver $driver The driver instance to convert with.
+ * @return string|resource
+ */
+	public function toDatabase($value, Driver $driver) {
+		if ($value === null || $value === '') {
+			return null;
+		}
+		return intval($value);
+	}
+
+/**
+ * Convert integer values to PHP integers
+ *
+ * @param null|string|resource $value The value to convert.
+ * @param Driver $driver The driver instance to convert with.
+ * @return resource
+ * @throws \Cake\Error\Exception
+ */
+	public function toPHP($value, Driver $driver) {
+		if ($value === null) {
+			return null;
+		}
+		return intval($value);
+	}
+
+/**
+ * Get the correct PDO binding type for integer data.
+ *
+ * @param mixed $value The value being bound.
+ * @param Driver $driver The driver.
+ * @return int
+ */
+	public function toStatement($value, Driver $driver) {
+		return PDO::PARAM_INT;
+	}
+
+/**
+ * Marshalls request data into PHP floats.
+ *
+ * @param mixed $value The value to convert.
+ * @return mixed Converted value.
+ */
+	public function marshal($value) {
+		if ($value === null || $value === '') {
+			return null;
+		}
+		return intval($value);
+	}
+
+}

+ 8 - 4
tests/TestCase/Database/Type/DateTimeTypeTest.php

@@ -95,9 +95,9 @@ class DateTimeTypeTest extends TestCase {
 		return [
 			// invalid types.
 			[null, null],
-			[false, false],
-			[true, true],
-			['', ''],
+			[false, null],
+			[true, null],
+			['', null],
 			['derpy', 'derpy'],
 			['2013-nope!', '2013-nope!'],
 
@@ -166,7 +166,11 @@ class DateTimeTypeTest extends TestCase {
  */
 	public function testMarshal($value, $expected) {
 		$result = $this->type->marshal($value);
-		$this->assertEquals($expected, $result);
+		if (is_object($expected)) {
+			$this->assertEquals($expected, $result);
+		} else {
+			$this->assertSame($expected, $result);
+		}
 	}
 
 }

+ 8 - 4
tests/TestCase/Database/Type/DateTypeTest.php

@@ -91,9 +91,9 @@ class DateTypeTest extends TestCase {
 		return [
 			// invalid types.
 			[null, null],
-			[false, false],
-			[true, true],
-			['', ''],
+			[false, null],
+			[true, null],
+			['', null],
 			['derpy', 'derpy'],
 			['2013-nope!', '2013-nope!'],
 
@@ -158,7 +158,11 @@ class DateTypeTest extends TestCase {
  */
 	public function testMarshal($value, $expected) {
 		$result = $this->type->marshal($value);
-		$this->assertEquals($expected, $result);
+		if (is_object($expected)) {
+			$this->assertEquals($expected, $result);
+		} else {
+			$this->assertSame($expected, $result);
+		}
 	}
 
 }

+ 98 - 0
tests/TestCase/Database/Type/FloatTypeTest.php

@@ -0,0 +1,98 @@
+<?php
+/**
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * For full copyright and license information, please see the LICENSE.txt
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link          http://cakephp.org CakePHP(tm) Project
+ * @since         3.0.0
+ * @license       http://www.opensource.org/licenses/mit-license.php MIT License
+ */
+namespace Cake\Test\TestCase\Database\Type;
+
+use Cake\Database\Type;
+use Cake\Database\Type\FloatType;
+use Cake\TestSuite\TestCase;
+use \PDO;
+
+/**
+ * Test for the Float type.
+ */
+class FloatTypeTest extends TestCase {
+
+/**
+ * Setup
+ *
+ * @return void
+ */
+	public function setUp() {
+		parent::setUp();
+		$this->type = Type::build('float');
+		$this->driver = $this->getMock('Cake\Database\Driver');
+	}
+
+/**
+ * Test toPHP
+ *
+ * @return void
+ */
+	public function testToPHP() {
+		$this->assertNull($this->type->toPHP(null, $this->driver));
+
+		$result = $this->type->toPHP('some data', $this->driver);
+		$this->assertSame(0.0, $result);
+
+		$result = $this->type->toPHP('2', $this->driver);
+		$this->assertSame(2.0, $result);
+
+		$result = $this->type->toPHP('2 bears', $this->driver);
+		$this->assertSame(2.0, $result);
+	}
+
+/**
+ * Test converting to database format
+ *
+ * @return void
+ */
+	public function testToDatabase() {
+		$result = $this->type->toDatabase('some data', $this->driver);
+		$this->assertSame(0.0, $result);
+
+		$result = $this->type->toDatabase(2, $this->driver);
+		$this->assertSame(2.0, $result);
+
+		$result = $this->type->toDatabase('2.51', $this->driver);
+		$this->assertSame(2.51, $result);
+	}
+
+/**
+ * Test marshalling
+ *
+ * @return void
+ */
+	public function testMarshal() {
+		$result = $this->type->marshal('some data', $this->driver);
+		$this->assertSame(0.0, $result);
+
+		$result = $this->type->marshal('', $this->driver);
+		$this->assertNull($result);
+
+		$result = $this->type->marshal('2.51', $this->driver);
+		$this->assertSame(2.51, $result);
+	}
+
+
+/**
+ * Test that the PDO binding type is correct.
+ *
+ * @return void
+ */
+	public function testToStatement() {
+		$this->assertEquals(PDO::PARAM_STR, $this->type->toStatement('', $this->driver));
+	}
+
+}

+ 98 - 0
tests/TestCase/Database/Type/IntegerTypeTest.php

@@ -0,0 +1,98 @@
+<?php
+/**
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * For full copyright and license information, please see the LICENSE.txt
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link          http://cakephp.org CakePHP(tm) Project
+ * @since         3.0.0
+ * @license       http://www.opensource.org/licenses/mit-license.php MIT License
+ */
+namespace Cake\Test\TestCase\Database\Type;
+
+use Cake\Database\Type;
+use Cake\Database\Type\IntegerType;
+use Cake\TestSuite\TestCase;
+use \PDO;
+
+/**
+ * Test for the Integer type.
+ */
+class IntegerTypeTest extends TestCase {
+
+/**
+ * Setup
+ *
+ * @return void
+ */
+	public function setUp() {
+		parent::setUp();
+		$this->type = Type::build('integer');
+		$this->driver = $this->getMock('Cake\Database\Driver');
+	}
+
+/**
+ * Test toPHP
+ *
+ * @return void
+ */
+	public function testToPHP() {
+		$this->assertNull($this->type->toPHP(null, $this->driver));
+
+		$result = $this->type->toPHP('some data', $this->driver);
+		$this->assertSame(0, $result);
+
+		$result = $this->type->toPHP('2', $this->driver);
+		$this->assertSame(2, $result);
+
+		$result = $this->type->toPHP('2 bears', $this->driver);
+		$this->assertSame(2, $result);
+	}
+
+/**
+ * Test converting to database format
+ *
+ * @return void
+ */
+	public function testToDatabase() {
+		$result = $this->type->toDatabase('some data', $this->driver);
+		$this->assertSame(0, $result);
+
+		$result = $this->type->toDatabase(2, $this->driver);
+		$this->assertSame(2, $result);
+
+		$result = $this->type->toDatabase('2', $this->driver);
+		$this->assertSame(2, $result);
+	}
+
+/**
+ * Test marshalling
+ *
+ * @return void
+ */
+	public function testMarshal() {
+		$result = $this->type->marshal('some data', $this->driver);
+		$this->assertSame(0, $result);
+
+		$result = $this->type->marshal('', $this->driver);
+		$this->assertNull($result);
+
+		$result = $this->type->marshal('0', $this->driver);
+		$this->assertSame(0, $result);
+	}
+
+
+/**
+ * Test that the PDO binding type is correct.
+ *
+ * @return void
+ */
+	public function testToStatement() {
+		$this->assertEquals(PDO::PARAM_INT, $this->type->toStatement('', $this->driver));
+	}
+
+}

+ 8 - 4
tests/TestCase/Database/Type/TimeTypeTest.php

@@ -90,9 +90,9 @@ class TimeTypeTest extends TestCase {
 		return [
 			// invalid types.
 			[null, null],
-			[false, false],
-			[true, true],
-			['', ''],
+			[false, null],
+			[true, null],
+			['', null],
 			['derpy', 'derpy'],
 			['16-nope!', '16-nope!'],
 
@@ -153,7 +153,11 @@ class TimeTypeTest extends TestCase {
  */
 	public function testMarshal($value, $expected) {
 		$result = $this->type->marshal($value);
-		$this->assertEquals($expected, $result);
+		if (is_object($expected)) {
+			$this->assertEquals($expected, $result);
+		} else {
+			$this->assertSame($expected, $result);
+		}
 	}
 
 }