Skip to content

Commit

Permalink
added option convertDecimal & converts to int/float [Closes #257]
Browse files Browse the repository at this point in the history
  • Loading branch information
dg committed Aug 29, 2024
1 parent c5e1d3e commit d2db229
Show file tree
Hide file tree
Showing 6 changed files with 85 additions and 11 deletions.
3 changes: 0 additions & 3 deletions src/Database/Drivers/Engines/MySQLEngine.php
Original file line number Diff line number Diff line change
Expand Up @@ -176,9 +176,6 @@ public function getForeignKeys(string $table): array
public function resolveColumnConverter(array $meta, TypeConverter $converter): ?\Closure
{
return match ($meta['nativeType']) {
'NEWDECIMAL' => $meta['scale'] === 0
? $converter->toInt(...)
: $converter->toFloat(...),
'TINY' => $meta['length'] === 1 && $converter->convertBoolean
? $converter->toBool(...)
: $converter->toInt(...),
Expand Down
2 changes: 1 addition & 1 deletion src/Database/Factory.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ final class Factory
'pdo-sqlite' => Drivers\PDO\SQLite\Driver::class,
'pdo-sqlsrv' => Drivers\PDO\SQLSrv\Driver::class,
];
private const TypeConverterOptions = ['convertBoolean', 'convertDateTime', 'newDateTime'];
private const TypeConverterOptions = ['convertBoolean', 'convertDateTime', 'convertDecimal', 'newDateTime'];


/** @internal */
Expand Down
9 changes: 6 additions & 3 deletions src/Database/TypeConverter.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ final class TypeConverter

public bool $convertBoolean = true;
public bool $convertDateTime = true;
public bool $convertDecimal = true;
public bool $newDateTime = true;


Expand All @@ -64,8 +65,10 @@ public function resolve(array $meta): ?\Closure
{
return match ($this->detectType($meta['nativeType'])) {
self::Integer => $this->toInt(...),
self::Float,
self::Decimal => $this->toFloat(...),
self::Float => $this->toFloat(...),
self::Decimal => $this->convertDecimal
? ($meta['scale'] === 0 ? $this->toInt(...) : $this->toFloat(...))
: null,
self::Boolean => $this->convertBoolean ? $this->toBool(...) : null,
self::DateTime, self::Date => $this->convertDateTime ? $this->toDateTime(...) : null,
self::Time => $this->convertDateTime ? $this->toTime(...) : null,
Expand All @@ -75,7 +78,7 @@ public function resolve(array $meta): ?\Closure
}


public function toInt(int|string $value): int|float
public function toInt(int|float|string $value): int|float|string
{
return is_float($tmp = $value * 1) ? $value : $tmp;
}
Expand Down
8 changes: 4 additions & 4 deletions tests/Database/ResultSet.normalizeRow.sqlsrv.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ Assert::equal([
'date' => new DateTime('2012-10-13 00:00:00'),
'datetime' => new DateTime('2012-10-13 10:10:10'),
'datetime2' => new DateTime('2012-10-13 10:10:10'),
'decimal' => 1.0,
'decimal' => 1,
'float' => 1.1,
'geography' => "\xe6\x10\x00\x00\x01\x14\x87\x16\xd9\xce\xf7\xd3G@\xd7\xa3p=\n\x97^\xc0\x87\x16\xd9\xce\xf7\xd3G@\xcb\xa1E\xb6\xf3\x95^\xc0",
'geometry' => "\x00\x00\x00\x00\x01\x04\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00Y@\x00\x00\x00\x00\x00\x00Y@\x00\x00\x00\x00\x00\x004@\x00\x00\x00\x00\x00\x80f@\x00\x00\x00\x00\x00\x80f@\x00\x00\x00\x00\x00\x80f@\x01\x00\x00\x00\x01\x00\x00\x00\x00\x01\x00\x00\x00\xff\xff\xff\xff\x00\x00\x00\x00\x02",
Expand All @@ -35,7 +35,7 @@ Assert::equal([
'money' => 1111.1,
'nchar' => 'a',
'ntext' => 'a',
'numeric_10_0' => 1.0,
'numeric_10_0' => 1,
'numeric_10_2' => 1.1,
'nvarchar' => 'a',
'real' => 1.1,
Expand All @@ -59,7 +59,7 @@ Assert::equal([
'date' => new DateTime('0001-01-01 00:00:00'),
'datetime' => new DateTime('1753-01-01 00:00:00'),
'datetime2' => new DateTime('0001-01-01 00:00:00'),
'decimal' => 0.0,
'decimal' => 0,
'float' => 0.5,
'geography' => null,
'geometry' => null,
Expand All @@ -68,7 +68,7 @@ Assert::equal([
'money' => 0.0,
'nchar' => ' ',
'ntext' => '',
'numeric_10_0' => 0.0,
'numeric_10_0' => 0,
'numeric_10_2' => 0.5,
'nvarchar' => '',
'real' => 0.0,
Expand Down
34 changes: 34 additions & 0 deletions tests/Database/connection.options.mysql.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -91,3 +91,37 @@ test('convertDateTime = true', function () {
$field = $connection->fetchField('SELECT NOW()');
Assert::type(Nette\Database\DateTime::class, $field);
});


test('default convertDecimal', function () {
$connection = connectToDB(['convertDecimal' => null])->getConnection();
Nette\Database\Helpers::loadFromFile($connection, __DIR__ . '/files/mysql-nette_test3.sql');
$row = $connection->fetch('SELECT * FROM types');
Assert::same(1, $row->decimal);
Assert::same(1.1, $row->decimal2);

$fields = $connection->fetchFields('SELECT 10, 10.5');
Assert::same([10, 10.5], $fields);
});

test('convertDecimal = false', function () {
$connection = connectToDB(['convertDecimal' => false])->getConnection();
Nette\Database\Helpers::loadFromFile($connection, __DIR__ . '/files/mysql-nette_test3.sql');
$row = $connection->fetch('SELECT * FROM types');
Assert::same('1', $row->decimal);
Assert::same('1.10', $row->decimal2);

$fields = $connection->fetchFields('SELECT 10, 10.5');
Assert::same([10, '10.5'], $fields);
});

test('convertDecimal = true', function () {
$connection = connectToDB(['convertDecimal' => true])->getConnection();
Nette\Database\Helpers::loadFromFile($connection, __DIR__ . '/files/mysql-nette_test3.sql');
$row = $connection->fetch('SELECT * FROM types');
Assert::same(1, $row->decimal);
Assert::same(1.1, $row->decimal2);

$fields = $connection->fetchFields('SELECT 10, 10.5');
Assert::same([10, 10.5], $fields);
});
40 changes: 40 additions & 0 deletions tests/Database/connection.options.sqlsrv.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?php

/**
* Test: Nette\Database\Connection sqlsrv options.
* @dataProvider? databases.ini sqlsrv
*/

declare(strict_types=1);

use Tester\Assert;

require __DIR__ . '/../bootstrap.php';


test('default convertDecimal', function () {
$connection = connectToDB(['convertDecimal' => null])->getConnection();
Nette\Database\Helpers::loadFromFile($connection, __DIR__ . '/files/sqlsrv-nette_test3.sql');
$row = $connection->fetch('SELECT * FROM types');
Assert::same(1, $row->decimal);
Assert::same(1, $row->numeric_10_0);
Assert::same(1.1, $row->numeric_10_2);
});

test('convertDecimal = true', function () {
$connection = connectToDB(['convertDecimal' => true])->getConnection();
Nette\Database\Helpers::loadFromFile($connection, __DIR__ . '/files/sqlsrv-nette_test3.sql');
$row = $connection->fetch('SELECT * FROM types');
Assert::same(1, $row->decimal);
Assert::same(1, $row->numeric_10_0);
Assert::same(1.1, $row->numeric_10_2);
});

test('convertDecimal = false', function () {
$connection = connectToDB(['convertDecimal' => false])->getConnection();
Nette\Database\Helpers::loadFromFile($connection, __DIR__ . '/files/sqlsrv-nette_test3.sql');
$row = $connection->fetch('SELECT * FROM types');
Assert::same('1', $row->decimal);
Assert::same('1', $row->numeric_10_0);
Assert::same('1.10', $row->numeric_10_2);
});

0 comments on commit d2db229

Please sign in to comment.