Browse Source

Split out Integer and Float type converters.

Having separate classes makes it much easier to handle the '' => null
conversions. It also makes these types 'faster' as the concrete type has
fewer/simpler code than the base Type class.

This solves integer casting issues that came up in #4058
mark_story 11 years ago
parent
commit
98ca880a05

+ 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' => [

+ 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);
+	}
+
+}

+ 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));
+	}
+
+}