diff --git a/src/Bridges/DatabaseTracy/ConnectionPanel.php b/src/Bridges/DatabaseTracy/ConnectionPanel.php index c974cc898..ad078c747 100644 --- a/src/Bridges/DatabaseTracy/ConnectionPanel.php +++ b/src/Bridges/DatabaseTracy/ConnectionPanel.php @@ -156,7 +156,7 @@ public function getPanel(): ?string $cmd = is_string($this->explain) ? $this->explain : 'EXPLAIN'; - $explain = (new ResultSet($connection->getConnectionDriver()->query("$cmd $sql", $params)))->fetchAll(); + $explain = (new ResultSet($connection, $connection->getConnectionDriver()->query("$cmd $sql", $params)))->fetchAll(); } catch (\PDOException) { } } diff --git a/src/Database/Connection.php b/src/Database/Connection.php index 74d8b5652..c34ef14bc 100644 --- a/src/Database/Connection.php +++ b/src/Database/Connection.php @@ -30,7 +30,6 @@ class Connection private ?SqlPreprocessor $preprocessor; /** @var callable(array, ResultSet): array */ - private $rowNormalizer = [Helpers::class, 'normalizeRow']; private TypeConverter $typeConverter; private ?string $sql = null; private int $transactionDepth = 0; @@ -136,10 +135,9 @@ public function getReflection(): Reflection } - public function setRowNormalizer(?callable $normalizer): static + public function setRowNormalizer(): static { - $this->rowNormalizer = $normalizer; - return $this; + throw new Nette\DeprecatedException(__METHOD__ . '() is deprecated, use getTypeConverter() instead.'); } @@ -229,7 +227,7 @@ public function query(#[Language('SQL')] string $sql, #[Language('GenericSQL')] $time = microtime(true); $result = $this->connection->query($this->sql, $params); $time = microtime(true) - $time; - $resultSet = new ResultSet($result, new SqlLiteral($this->sql, $params), $this->rowNormalizer, $time); + $resultSet = new ResultSet($this, $result, new SqlLiteral($this->sql, $params), $time); } catch (DriverException $e) { Arrays::invoke($this->onQuery, $this, $e); throw $e; diff --git a/src/Database/Helpers.php b/src/Database/Helpers.php index f07237e44..2ef57fc6a 100644 --- a/src/Database/Helpers.php +++ b/src/Database/Helpers.php @@ -151,19 +151,6 @@ public static function dumpSql(string $sql, ?array $params = null, ?Connection $ } - /** @internal */ - public static function normalizeRow(array $row, ResultSet $resultSet): array - { - foreach ($resultSet->resolveColumnConverters() as $key => $converter) { - $value = $row[$key]; - $row[$key] = isset($value, $converter) - ? $converter($value) - : $value; - } - return $row; - } - - /** * Import SQL dump from file - extremely fast. * @param ?array $onProgress diff --git a/src/Database/ResultSet.php b/src/Database/ResultSet.php index e9896bfc9..0fa66eb2f 100644 --- a/src/Database/ResultSet.php +++ b/src/Database/ResultSet.php @@ -17,8 +17,6 @@ */ class ResultSet implements \Iterator { - /** @var callable(array, ResultSet): array */ - private readonly mixed $normalizer; private Row|false|null $lastRow = null; private int $lastRowKey = -1; @@ -28,19 +26,18 @@ class ResultSet implements \Iterator public function __construct( + private readonly Connection $connection, private readonly Drivers\Result $result, private readonly ?SqlLiteral $query = null, - ?callable $normalizer = null, private ?float $time = null, ) { - $this->normalizer = $normalizer; } /** @deprecated */ public function getConnection(): Connection { - throw new Nette\DeprecatedException(__METHOD__ . '() is deprecated.'); + return $this->connection; } @@ -77,18 +74,20 @@ public function getTime(): float /** @internal */ public function normalizeRow(array $row): array { - return $this->normalizer - ? ($this->normalizer)($row, $this) - : $row; + $converters = $this->converters ??= $this->resolveColumnConverters(); + foreach ($row as $key => $value) { + $converter = $converters[$key]; + $row[$key] = isset($value, $converter) + ? $converter($value) + : $value; + } + + return $row; } - public function resolveColumnConverters(): array + private function resolveColumnConverters(): array { - if (isset($this->converters)) { - return $this->converters; - } - $res = []; $engine = $this->connection->getDatabaseEngine(); $converter = $this->connection->getTypeConverter(); @@ -97,7 +96,7 @@ public function resolveColumnConverters(): array ? $engine->resolveColumnConverter($meta, $converter) : null; } - return $this->converters = $res; + return $res; } diff --git a/src/Database/TypeConverter.php b/src/Database/TypeConverter.php index 190905dc9..29db37be1 100644 --- a/src/Database/TypeConverter.php +++ b/src/Database/TypeConverter.php @@ -33,7 +33,7 @@ final class TypeConverter * Heuristic column type detection. * @return Type::* */ - public static function detectType(string $nativeType): string + private function detectType(string $nativeType): string { static $cache; if (!isset($cache[$nativeType])) { @@ -51,7 +51,7 @@ public static function detectType(string $nativeType): string public function resolve(string $nativeType): ?\Closure { - return match (self::detectType($nativeType)) { + return match ($this->detectType($nativeType)) { Type::Integer => $this->toInt(...), Type::Decimal => $this->convertDecimal ? $this->toDecimal(...) : null, Type::Float => $this->toFloat(...), diff --git a/tests/Database/ResultSet.customNormalizer.phpt b/tests/Database/ResultSet.customNormalizer.phpt index 4da4189ae..8749182c8 100644 --- a/tests/Database/ResultSet.customNormalizer.phpt +++ b/tests/Database/ResultSet.customNormalizer.phpt @@ -16,10 +16,11 @@ Nette\Database\Helpers::loadFromFile($connection, __DIR__ . "/files/{$driverName $connection->query('UPDATE author SET born=?', new DateTime('2022-01-23')); +// TODO test('disabled normalization', function () use ($connection) { $driverName = $GLOBALS['driverName']; - $connection->setRowNormalizer(null); + $connection->getTypeConverter()->convertDateTime = false; $res = $connection->query('SELECT * FROM author'); $asInt = $driverName === 'pgsql' || ($driverName !== 'sqlsrv' && PHP_VERSION_ID >= 80100); Assert::same([