Skip to content

Commit

Permalink
Unify impl. for whole int range
Browse files Browse the repository at this point in the history
  • Loading branch information
mvorisek committed May 28, 2024
1 parent dcbddf3 commit 4c3258b
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 10 deletions.
24 changes: 14 additions & 10 deletions src/Types/BigIntType.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,10 @@
use function assert;
use function is_int;
use function is_string;

use const PHP_INT_MAX;
use const PHP_INT_MIN;
use function preg_replace;
use function rtrim;
use function strpos;
use function substr;

/**
* Type that attempts to map a database BIGINT to a PHP int.
Expand Down Expand Up @@ -47,18 +48,21 @@ public function convertToPHPValue(mixed $value, AbstractPlatform $platform): int
return $value;
}

if (
($value > PHP_INT_MIN && $value < PHP_INT_MAX)
|| $value === (string) (int) $value
) {
return (int) $value;
}

assert(
is_string($value),
'DBAL assumes values outside of the integer range to be returned as string by the database driver.',
);

// workaround https://github.com/php/php-src/issues/14345
$dotPos = strpos($value, '.');
if ($dotPos !== false && rtrim(substr($value, $dotPos + 1), '0') === '') {

Check failure on line 58 in src/Types/BigIntType.php

View workflow job for this annotation

GitHub Actions / Static Analysis with Psalm (8.3)

NoValue

src/Types/BigIntType.php:58:47: NoValue: All possible types for this argument were invalidated - This may be dead code (see https://psalm.dev/179)
$value = substr($value, 0, $dotPos);

Check failure on line 59 in src/Types/BigIntType.php

View workflow job for this annotation

GitHub Actions / Static Analysis with Psalm (8.3)

NoValue

src/Types/BigIntType.php:59:29: NoValue: All possible types for this argument were invalidated - This may be dead code (see https://psalm.dev/179)
}

if (preg_replace('~^(\+|-(?=0+$))|(?<=^|^[+\-])0+(?=\d)~', '', $value) === (string) (int) $value) {
return (int) $value;
}

return $value;
}
}
32 changes: 32 additions & 0 deletions tests/Functional/Types/BigIntTypeTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@
use Generator;
use PHPUnit\Framework\Attributes\DataProvider;

use function str_starts_with;
use function substr;

use const PHP_INT_MAX;
use const PHP_INT_MIN;
use const PHP_INT_SIZE;
Expand Down Expand Up @@ -38,6 +41,30 @@ public function testSelectBigInt(string $sqlLiteral, int|string|null $expectedVa
Types::BIGINT,
),
);

if ($expectedValue === null) {
return;
}

self::assertSame(
$expectedValue,
$this->connection->convertToPHPValue(
$sqlLiteral . '.00',
Types::BIGINT,
),
);

$startsWithSign = str_starts_with($sqlLiteral, '-') || str_starts_with($sqlLiteral, '+');

self::assertSame(
$expectedValue,
$this->connection->convertToPHPValue(
($startsWithSign ? substr($sqlLiteral, 0, 1) : '')
. '00'
. ($startsWithSign ? substr($sqlLiteral, 1) : $sqlLiteral),
Types::BIGINT,
),
);
}

/** @return Generator<string, array{string, int|string|null}> */
Expand All @@ -53,6 +80,11 @@ public static function provideBigIntLiterals(): Generator
yield 'large negative number' => [PHP_INT_SIZE === 4 ? '-2147483647' : '-9223372036854775807', PHP_INT_MIN + 1];
yield 'largest positive number' => [PHP_INT_SIZE === 4 ? '2147483647' : '9223372036854775807', PHP_INT_MAX];
yield 'largest negative number' => [PHP_INT_SIZE === 4 ? '-2147483648' : '-9223372036854775808', PHP_INT_MIN];

yield 'plus largest positive number' => [
PHP_INT_SIZE === 4 ? '+2147483647' : '+9223372036854775807',
PHP_INT_MAX,
];
}

public function testUnsignedBigIntOnMySQL(): void
Expand Down

0 comments on commit 4c3258b

Please sign in to comment.