From a2fa17ec609140d3ebfdb0165cdf3a6146c1ba28 Mon Sep 17 00:00:00 2001 From: "Matthew J. Mucklo" Date: Sun, 4 Aug 2019 15:49:46 -0700 Subject: [PATCH] Address issue #3631 by adding support for a float datatype Also try to add a new functional test per request. --- .travis.yml | 17 +++ .../DBAL/Driver/Mysqli/MysqliStatement.php | 1 + lib/Doctrine/DBAL/ParameterType.php | 5 + lib/Doctrine/DBAL/Types/FloatType.php | 9 ++ .../DBAL/Functional/Types/DoubleTest.php | 102 ++++++++++++++++++ tests/travis/setlocale-de.php | 3 + 6 files changed, 137 insertions(+) create mode 100644 tests/Doctrine/Tests/DBAL/Functional/Types/DoubleTest.php create mode 100644 tests/travis/setlocale-de.php diff --git a/.travis.yml b/.travis.yml index e0d87665991..a59a1a94337 100644 --- a/.travis.yml +++ b/.travis.yml @@ -36,6 +36,11 @@ after_script: travis_retry php ocular.phar code-coverage:upload --format=php-clover clover.xml fi +addons: + apt: + packages: + - language-pack-de + jobs: allow_failures: - php: 7.4snapshot @@ -339,3 +344,15 @@ jobs: install: - composer config minimum-stability dev - travis_retry composer update --prefer-dist + + - stage: TestIntl + php: 7.2 + env: LANGUAGE=de_DE.UTF-8 LC_ALL=de_DE.UTF-8 LANG=de_DE.UTF-8 DB=mysqli.docker MYSQL_VERSION=8.0 + sudo: required + services: + - docker + before_script: + - bash ./tests/travis/install-mysql-8.0.sh + script: + - php -d"auto_prepend_file=$PWD/tests/travis/setlocale-de.php" ./vendor/bin/phpunit --configuration tests/travis/$DB.travis.xml + diff --git a/lib/Doctrine/DBAL/Driver/Mysqli/MysqliStatement.php b/lib/Doctrine/DBAL/Driver/Mysqli/MysqliStatement.php index 43d70853ef5..87946c9fddc 100644 --- a/lib/Doctrine/DBAL/Driver/Mysqli/MysqliStatement.php +++ b/lib/Doctrine/DBAL/Driver/Mysqli/MysqliStatement.php @@ -34,6 +34,7 @@ class MysqliStatement implements IteratorAggregate, Statement ParameterType::NULL => 's', ParameterType::INTEGER => 'i', ParameterType::LARGE_OBJECT => 'b', + ParameterType::DOUBLE => 'd', ]; /** @var mysqli */ diff --git a/lib/Doctrine/DBAL/ParameterType.php b/lib/Doctrine/DBAL/ParameterType.php index 422fee895ee..53ba350c7f8 100644 --- a/lib/Doctrine/DBAL/ParameterType.php +++ b/lib/Doctrine/DBAL/ParameterType.php @@ -49,6 +49,11 @@ final class ParameterType */ public const BINARY = 16; + /** + * Represents a double data type. + */ + public const DOUBLE = 17; + /** * This class cannot be instantiated. */ diff --git a/lib/Doctrine/DBAL/Types/FloatType.php b/lib/Doctrine/DBAL/Types/FloatType.php index 4988d7253dc..f11a0a04f08 100644 --- a/lib/Doctrine/DBAL/Types/FloatType.php +++ b/lib/Doctrine/DBAL/Types/FloatType.php @@ -2,6 +2,7 @@ namespace Doctrine\DBAL\Types; +use Doctrine\DBAL\ParameterType; use Doctrine\DBAL\Platforms\AbstractPlatform; class FloatType extends Type @@ -29,4 +30,12 @@ public function convertToPHPValue($value, AbstractPlatform $platform) { return $value === null ? null : (float) $value; } + + /** + * {@inheritdoc} + */ + public function getBindingType() + { + return ParameterType::DOUBLE; + } } diff --git a/tests/Doctrine/Tests/DBAL/Functional/Types/DoubleTest.php b/tests/Doctrine/Tests/DBAL/Functional/Types/DoubleTest.php new file mode 100644 index 00000000000..f1c838b1c51 --- /dev/null +++ b/tests/Doctrine/Tests/DBAL/Functional/Types/DoubleTest.php @@ -0,0 +1,102 @@ +addColumn('id', 'integer'); + $table->addColumn('val', 'float'); + $table->setPrimaryKey(['id']); + + $sm = $this->connection->getSchemaManager(); + $sm->dropAndCreateTable($table); + } + + public function testInsertAndSelect() : void + { + $value1 = 1.1; + $value2 = 77.99999999999; + $value3 = microtime(true); + $valStr = (string) $value3; + $localeInfo = localeconv(); + $len = strlen(substr($valStr, strpos($valStr, $localeInfo['decimal_point'] ?? '.') + 1)); + + $this->insert(1, $value1); + $this->insert(2, $value2); + $this->insert(3, $value3); + + $result1 = $this->select(1); + $result2 = $this->select(2); + $result3 = $this->select(3); + + $this->assertSame(is_float($result1) ? $value1 : number_format($value1, 1, '.', ''), $result1); + $this->assertSame(is_float($result2) ? $value2 : number_format($value2, 11, '.', ''), $result2); + $this->assertSame(is_float($result3) ? $value3 : number_format($value3, $len, '.', ''), $result3); + + $result1 = $this->selectDouble($value1); + $result2 = $this->selectDouble($value2); + $result3 = $this->selectDouble($value3); + + $this->assertSame(is_int($result1) ? 1 : '1', $result1); + $this->assertSame(is_int($result2) ? 2 : '2', $result2); + $this->assertSame(is_int($result3) ? 3 : '3', $result3); + } + + private function insert(int $id, float $value) : void + { + $result = $this->connection->insert('double_table', [ + 'id' => $id, + 'val' => $value, + ], [ + ParameterType::INTEGER, + ParameterType::DOUBLE, + ]); + + self::assertSame(1, $result); + } + + /** + * @return mixed + */ + private function select(int $id) + { + return $this->connection->fetchColumn( + 'SELECT val FROM double_table WHERE id = ?', + [$id], + 0, + [ParameterType::INTEGER] + ); + } + + /** + * @return mixed + */ + private function selectDouble(float $value) + { + return $this->connection->fetchColumn( + 'SELECT id FROM double_table WHERE val = ?', + [$value], + 0, + [ParameterType::DOUBLE] + ); + } +} diff --git a/tests/travis/setlocale-de.php b/tests/travis/setlocale-de.php new file mode 100644 index 00000000000..e47ee1e2001 --- /dev/null +++ b/tests/travis/setlocale-de.php @@ -0,0 +1,3 @@ +