Skip to content

Commit

Permalink
Address issue doctrine#3631 by adding support for a float datatype
Browse files Browse the repository at this point in the history
Also try to add a new functional test per request.
  • Loading branch information
mmucklo committed Aug 11, 2019
1 parent 9ff47e7 commit 6b3774d
Show file tree
Hide file tree
Showing 20 changed files with 301 additions and 12 deletions.
2 changes: 1 addition & 1 deletion .appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ install:
New-Item -path c:\tools -name ocular -itemtype directory
}
if (!(Test-Path c:\tools\ocular\ocular.phar)) {
appveyor-retry appveyor DownloadFile https://github.com/scrutinizer-ci/ocular/releases/download/1.5.2/ocular.phar -Filename C:\tools\ocular\ocular.phar
appveyor-retry appveyor DownloadFile https://scrutinizer-ci.com/ocular.phar -Filename C:\tools\ocular\ocular.phar
Set-Content -path 'C:\tools\ocular\ocular.bat' -Value ('@php C:\tools\ocular\ocular.phar %*')
}
Expand Down
2 changes: 1 addition & 1 deletion .scrutinizer.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ before_commands:
tools:
external_code_coverage:
timeout: 3600
runs: 30 # 25x Travis (jobs with COVERAGE=yes) + 3x AppVeyor (jobs with coverage=yes) + 2x ContinuousPHP
runs: 32 # 27x Travis (jobs with COVERAGE=yes) + 3x AppVeyor (jobs with coverage=yes) + 2x ContinuousPHP

filter:
excluded_paths:
Expand Down
108 changes: 105 additions & 3 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,22 @@ install:

script:
- |
phpflags=
phpexe=
if [ "x$LANGUAGE" != "x" ]; then
phpflags=-dauto_prepend_file=$PWD/tests/travis/setlocale-de.php
phpexe=php
fi
if [ "x$COVERAGE" == "xyes" ]; then
./vendor/bin/phpunit --configuration tests/travis/$DB.travis.xml --coverage-clover clover.xml
$phpexe $phpflags ./vendor/bin/phpunit --configuration tests/travis/$DB.travis.xml --coverage-clover clover.xml
else
./vendor/bin/phpunit --configuration tests/travis/$DB.travis.xml
$phpexe $phpflags ./vendor/bin/phpunit --configuration tests/travis/$DB.travis.xml
fi
after_script:
- |
if [ "x$COVERAGE" == "xyes" ]; then
travis_retry wget https://github.com/scrutinizer-ci/ocular/releases/download/1.5.2/ocular.phar
travis_retry wget https://scrutinizer-ci.com/ocular.phar
travis_retry php ocular.phar code-coverage:upload --format=php-clover clover.xml
fi
Expand Down Expand Up @@ -339,3 +345,99 @@ jobs:
install:
- composer config minimum-stability dev
- travis_retry composer update --prefer-dist

- stage: Test
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-language.sh
- bash ./tests/travis/install-mysql-8.0.sh

- stage: Test
php: 7.3
env: LANGUAGE=de_DE.UTF-8 LC_ALL=de_DE.UTF-8 LANG=de_DE.UTF-8 DB=mysqli.docker MYSQL_VERSION=8.0 COVERAGE=yes
sudo: required
services:
- docker
before_script:
- bash ./tests/travis/install-language.sh
- bash ./tests/travis/install-mysql-8.0.sh

- stage: Test
php: 7.3
env: LANGUAGE=de_DE.UTF-8 LC_ALL=de_DE.UTF-8 LANG=de_DE.UTF-8 DB=mysqli.docker MYSQL_VERSION=5.7
sudo: required
services:
- docker
before_script:
- bash ./tests/travis/install-language.sh
- bash ./tests/travis/install-mysql-5.7.sh

- stage: Test
php: 7.3
env: LANGUAGE=de_DE.UTF-8 LC_ALL=de_DE.UTF-8 LANG=de_DE.UTF-8 DB=sqlite COVERAGE=yes
sudo: required
services:
- docker
before_script:
- bash ./tests/travis/install-language.sh

- stage: Test
php: 7.3
env: LANGUAGE=de_DE.UTF-8 LC_ALL=de_DE.UTF-8 LANG=de_DE.UTF-8 DB=pgsql POSTGRESQL_VERSION=10.0
sudo: required
services:
- postgresql
addons:
postgresql: "9.6"
before_script:
- bash ./tests/travis/install-language.sh
- bash ./tests/travis/install-postgres-10.sh

- stage: Test
php: 7.3
env: LANGUAGE=de_DE.UTF-8 LC_ALL=de_DE.UTF-8 LANG=de_DE.UTF-8 DB=pgsql POSTGRESQL_VERSION=11.0
sudo: required
services:
- docker
before_script:
- bash ./tests/travis/install-language.sh
- bash ./tests/travis/install-postgres-11.sh

- stage: Test
php: 7.3
env: LANGUAGE=de_DE.UTF-8 LC_ALL=de_DE.UTF-8 LANG=de_DE.UTF-8 DB=sqlsrv
sudo: required
services:
- docker
before_script:
- bash ./tests/travis/install-language.sh
- bash ./tests/travis/install-sqlsrv-dependencies.sh
- bash ./tests/travis/install-mssql-sqlsrv.sh
- bash ./tests/travis/install-mssql.sh

- stage: Test
php: 7.3
env: LANGUAGE=de_DE.UTF-8 LC_ALL=de_DE.UTF-8 LANG=de_DE.UTF-8 DB=pdo_sqlsrv
sudo: required
services:
- docker
before_script:
- bash ./tests/travis/install-language.sh
- bash ./tests/travis/install-sqlsrv-dependencies.sh
- bash ./tests/travis/install-mssql-pdo_sqlsrv.sh
- bash ./tests/travis/install-mssql.sh

- stage: Test
php: 7.3
env: LANGUAGE=de_DE.UTF-8 LC_ALL=de_DE.UTF-8 LANG=de_DE.UTF-8 DB=ibm_db2
sudo: required
services:
- docker
before_script:
- bash ./tests/travis/install-language.sh
- bash ./tests/travis/install-db2.sh
- bash ./tests/travis/install-db2-ibm_db2.sh
7 changes: 6 additions & 1 deletion lib/Doctrine/DBAL/Driver/AbstractMySQLDriver.php
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,13 @@ public function convertException($message, DriverException $exception)
case '1429':
case '2002':
case '2005':
case '2054':
return new Exception\ConnectionException($message, $exception);

case '2006':
if ($exception instanceof Driver\Mysqli\MysqliConnectionException || $exception instanceof PDOConnectionException) {
return new Exception\ConnectionException($message, $exception);
}
break;
case '1048':
case '1121':
case '1138':
Expand Down
2 changes: 1 addition & 1 deletion lib/Doctrine/DBAL/Driver/Mysqli/MysqliConnection.php
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ public function __construct(array $params, $username, $password, array $driverOp
});
try {
if (! $this->conn->real_connect($params['host'], $username, $password, $dbname, $port, $socket, $flags)) {
throw new MysqliException($this->conn->connect_error, $this->conn->sqlstate ?? 'HY000', $this->conn->connect_errno);
throw new MysqliConnectionException($this->conn->connect_error, $this->conn->sqlstate ?? 'HY000', $this->conn->connect_errno);
}
} finally {
restore_error_handler();
Expand Down
10 changes: 10 additions & 0 deletions lib/Doctrine/DBAL/Driver/Mysqli/MysqliConnectionException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php

namespace Doctrine\DBAL\Driver\Mysqli;

/**
* Exception thrown in case the mysqli driver errors while connecting.
*/
class MysqliConnectionException extends MysqliException
{
}
16 changes: 14 additions & 2 deletions lib/Doctrine/DBAL/Driver/Mysqli/MysqliStatement.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
use function feof;
use function fread;
use function get_resource_type;
use function gettype;
use function is_array;
use function is_int;
use function is_resource;
Expand All @@ -34,6 +35,7 @@ class MysqliStatement implements IteratorAggregate, Statement
ParameterType::NULL => 's',
ParameterType::INTEGER => 'i',
ParameterType::LARGE_OBJECT => 'b',
ParameterType::DOUBLE => 'd',
];

/** @var mysqli */
Expand Down Expand Up @@ -272,10 +274,20 @@ private function sendLongData($streams)
private function bindUntypedValues(array $values)
{
$params = [];
$types = str_repeat('s', count($values));

$types = '';
foreach ($values as &$v) {
$params[] =& $v;
// fix for issue #3631 - detect parameter types as they have to be bound differently
switch (gettype($v)) {
case 'boolean':
$types .= self::$_paramTypeMap[ParameterType::BOOLEAN];
break;
case 'double':
$types .= self::$_paramTypeMap[ParameterType::DOUBLE];
break;
default:
$types .= self::$_paramTypeMap[ParameterType::STRING];
}
}

return $this->_stmt->bind_param($types, ...$params);
Expand Down
2 changes: 1 addition & 1 deletion lib/Doctrine/DBAL/Driver/PDOConnection.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public function __construct($dsn, $user = null, $password = null, ?array $option
$this->setAttribute(PDO::ATTR_STATEMENT_CLASS, [PDOStatement::class, []]);
$this->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (\PDOException $exception) {
throw new PDOException($exception);
throw new PDOConnectionException($exception);
}
}

Expand Down
10 changes: 10 additions & 0 deletions lib/Doctrine/DBAL/Driver/PDOConnectionException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php

namespace Doctrine\DBAL\Driver;

/**
* PDOConnectionException is used to distinguish connection failures from regular PDOExceptions.
*/
class PDOConnectionException extends PDOException
{
}
1 change: 1 addition & 0 deletions lib/Doctrine/DBAL/Driver/PDOStatement.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ class PDOStatement extends \PDOStatement implements Statement
ParameterType::BINARY => PDO::PARAM_LOB,
ParameterType::LARGE_OBJECT => PDO::PARAM_LOB,
ParameterType::BOOLEAN => PDO::PARAM_BOOL,
ParameterType::DOUBLE => PDO::PARAM_STR,
];

private const FETCH_MODE_MAP = [
Expand Down
5 changes: 5 additions & 0 deletions lib/Doctrine/DBAL/ParameterType.php
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*/
Expand Down
14 changes: 14 additions & 0 deletions lib/Doctrine/DBAL/Schema/Column.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,13 @@
use Doctrine\DBAL\Types\Type;
use const E_USER_DEPRECATED;
use function array_merge;
use function is_float;
use function is_numeric;
use function localeconv;
use function method_exists;
use function sprintf;
use function str_replace;
use function strval;
use function trigger_error;

/**
Expand Down Expand Up @@ -193,6 +197,16 @@ public function setNotnull($notnull)
*/
public function setDefault($default)
{
if (is_float($default)) {
$localeInfo = localeconv();
$decimal = $localeInfo['decimal_point'] ?? '.';
if ($decimal !== '.') {
// SQL standard is '.' for all decimal points so convert to string (issue #3631)
// Also see https://stackoverflow.com/questions/6627239/insert-non-english-decimal-points-in-mysql/6627551#6627551
$default = strval($default);
$default = str_replace($decimal, '.', $default);
}
}
$this->_default = $default;

return $this;
Expand Down
9 changes: 9 additions & 0 deletions lib/Doctrine/DBAL/Types/FloatType.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace Doctrine\DBAL\Types;

use Doctrine\DBAL\ParameterType;
use Doctrine\DBAL\Platforms\AbstractPlatform;

class FloatType extends Type
Expand Down Expand Up @@ -29,4 +30,12 @@ public function convertToPHPValue($value, AbstractPlatform $platform)
{
return $value === null ? null : (float) $value;
}

/**
* {@inheritdoc}
*/
public function getBindingType()
{
return ParameterType::DOUBLE;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ public function testRestoresErrorHandlerOnException() : void
new MysqliConnection(['host' => '255.255.255.255'], 'user', 'pass');
self::fail('An exception was supposed to be raised');
} catch (MysqliException $e) {
self::assertSame('Network is unreachable', $e->getMessage());
self::assertSame(2002, $e->getErrorCode());
}

self::assertSame($handler, set_error_handler($default_handler), 'Restoring error handler failed.');
Expand Down
Loading

0 comments on commit 6b3774d

Please sign in to comment.