Skip to content

Commit

Permalink
resolveColumnConverter
Browse files Browse the repository at this point in the history
  • Loading branch information
dg committed Aug 18, 2024
1 parent 480dea8 commit 8811567
Show file tree
Hide file tree
Showing 23 changed files with 159 additions and 120 deletions.
2 changes: 1 addition & 1 deletion src/Bridges/DatabaseTracy/ConnectionPanel.php
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
}
}
Expand Down
24 changes: 19 additions & 5 deletions src/Database/Connection.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,17 +30,26 @@ class Connection
private ?SqlPreprocessor $preprocessor;

/** @var callable(array, ResultSet): array */
private $rowNormalizer;
private TypeConverter $typeConverter;

Check failure on line 33 in src/Database/Connection.php

View workflow job for this annotation

GitHub Actions / PHPStan

PHPDoc tag @var for property Nette\Database\Connection::$typeConverter with type callable is incompatible with native type Nette\Database\TypeConverter.
private ?string $sql = null;
private int $transactionDepth = 0;


public function __construct(
\Closure|string $connector,
) {
$this->typeConverter = new TypeConverter;

if (is_string($connector)) { // compatibility with version 3.x
//trigger_error('Passing DSN as string is deprecated, use Nette\Database\Factory::createFromDsn() instead.', E_USER_DEPRECATED);
[$dsn, $user, $password, $options] = func_get_args() + [null, null, null, []];

foreach (['convertBoolean', 'convertDateTime', 'convertDecimal'] as $opt) {
if (isset($options[$opt])) {
$this->typeConverter->$opt = (bool) $options[$opt];
unset($options[$opt]);
}
}
$lazy = $options['lazy'] ?? false;
unset($options['newDateTime'], $options['lazy']);
$this->connector = (new Factory)->createConnectorFromDsn($dsn, $user, $password, $options);
Expand Down Expand Up @@ -126,10 +135,15 @@ public function getReflection(): Reflection
}


public function setRowNormalizer(?callable $normalizer): static
public function setRowNormalizer(): static
{
throw new Nette\DeprecatedException(__METHOD__ . '() is deprecated, use getTypeConverter() instead.');
}


public function getTypeConverter(): TypeConverter
{
$this->rowNormalizer = $normalizer;
return $this;
return $this->typeConverter;
}


Expand Down Expand Up @@ -213,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;
Expand Down
4 changes: 4 additions & 0 deletions src/Database/Drivers/Engine.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@

namespace Nette\Database\Drivers;

use Nette\Database\TypeConverter;


/**
* Database driver.
Expand Down Expand Up @@ -67,6 +69,8 @@ function getIndexes(string $table): array;
/** @return list<array{name: string, local: list<string>, table: string, foreign: list<string>}> */
function getForeignKeys(string $table): array;

function resolveColumnConverter(array $meta, TypeConverter $converter): ?\Closure;

/**
* Cheks if driver supports specific property
* @param self::Support* $item
Expand Down
6 changes: 6 additions & 0 deletions src/Database/Drivers/Engines/MSSQLEngine.php
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,12 @@ public function getForeignKeys(string $table): array
}


public function resolveColumnConverter(array $meta, TypeConverter $converter): ?\Closure
{
return $converter->resolve($meta['nativeType']);
}


public function isSupported(string $item): bool
{
return $item === self::SupportSubselect;
Expand Down
24 changes: 13 additions & 11 deletions src/Database/Drivers/Engines/MySQLEngine.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@
namespace Nette\Database\Drivers\Engines;

use Nette;
use Nette\Database\DateTime;
use Nette\Database\Drivers\Connection;
use Nette\Database\Drivers\Engine;
use Nette\Database\Type;
use Nette\Database\TypeConverter;


Expand All @@ -39,16 +39,6 @@ public function determineExceptionClass(int $code, ?string $sqlState, string $me
}


public function resolveTypeConverter(string $nativeType, TypeConverter $converter): ?\Closure
{
return match ($nativeType) {
'TIME' => $converter->convertDateTime ? $converter->toInterval(...) : null,
'DATE', 'DATETIME', 'TIMESTAMP' => $converter->convertDateTime ? (fn($value) => str_starts_with($value, '0000-00') ? null : $converter->toDateTime($value)) : null,
default => $converter->resolve($nativeType),
};
}


/********************* SQL ****************d*g**/


Expand Down Expand Up @@ -176,6 +166,18 @@ public function getForeignKeys(string $table): array
}


public function resolveColumnConverter(array $meta, TypeConverter $converter): ?\Closure
{
return match ($meta['nativeType']) {
'NEWDECIMAL' => $meta['precision'] === 0 ? $converter->toInt(...) : $converter->toFloat(...),
'TINY' => $meta['length'] === 1 && $converter->convertBoolean ? $converter->toBool(...) : $converter->toInt(...),
'TIME' => $converter->convertDateTime ? $converter->toInterval(...) : null,
'DATE', 'DATETIME', 'TIMESTAMP' => $converter->convertDateTime ? (fn($value): ?DateTime => str_starts_with($value, '0000-00') ? null : $converter->toDateTime($value)) : null,
default => $converter->resolve($meta['nativeType']),
};
}


public function isSupported(string $item): bool
{
// MULTI_COLUMN_AS_OR_COND due to mysql bugs:
Expand Down
7 changes: 7 additions & 0 deletions src/Database/Drivers/Engines/ODBCEngine.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

use Nette;
use Nette\Database\Drivers\Engine;
use Nette\Database\TypeConverter;


/**
Expand Down Expand Up @@ -96,6 +97,12 @@ public function getForeignKeys(string $table): array
}


public function resolveColumnConverter(array $meta, TypeConverter $converter): ?\Closure
{
return $converter->resolve($meta['nativeType']);
}


public function isSupported(string $item): bool
{
return $item === self::SupportSubselect;
Expand Down
7 changes: 7 additions & 0 deletions src/Database/Drivers/Engines/OracleEngine.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
use Nette;
use Nette\Database\Drivers\Connection;
use Nette\Database\Drivers\Engine;
use Nette\Database\TypeConverter;


/**
Expand Down Expand Up @@ -123,6 +124,12 @@ public function getForeignKeys(string $table): array
}


public function resolveColumnConverter(array $meta, TypeConverter $converter): ?\Closure
{
return $converter->resolve($meta['nativeType']);
}


public function isSupported(string $item): bool
{
return $item === self::SupportSequence || $item === self::SupportSubselect;
Expand Down
16 changes: 8 additions & 8 deletions src/Database/Drivers/Engines/PostgreSQLEngine.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,6 @@ public function determineExceptionClass(int $code, ?string $sqlState, string $me
}


public function resolveTypeConverter(string $nativeType, TypeConverter $converter): ?\Closure
{
return $nativeType === 'bool'
? fn($value) => ($value && $value !== 'f' && $value !== 'F')
: $converter->resolve($nativeType);
}


/********************* SQL ****************d*g**/


Expand Down Expand Up @@ -237,6 +229,14 @@ public function getForeignKeys(string $table): array
}


public function resolveColumnConverter(array $meta, TypeConverter $converter): ?\Closure
{
return $meta['nativeType'] === 'bool'
? fn($value): bool => ($value && $value !== 'f' && $value !== 'F')
: $converter->resolve($meta['nativeType']);
}


public function isSupported(string $item): bool
{
return $item === self::SupportSequence || $item === self::SupportSubselect || $item === self::SupportSchema;
Expand Down
20 changes: 10 additions & 10 deletions src/Database/Drivers/Engines/SQLServerEngine.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,16 +32,6 @@ public function determineExceptionClass(int $code, ?string $sqlState, string $me
}


public function resolveTypeConverter(string $nativeType, TypeConverter $converter): ?\Closure
{
return match ($nativeType) {
'timestamp' => null, // timestamp does not mean time in sqlsrv
'bit' => $converter->convertBoolean ? fn($value) => (bool) $value : null,
default => $converter->resolve($nativeType),
};
}


/********************* SQL ****************d*g**/


Expand Down Expand Up @@ -229,6 +219,16 @@ public function getForeignKeys(string $table): array
}


public function resolveColumnConverter(array $meta, TypeConverter $converter): ?\Closure
{
return match ($meta['nativeType']) {
'timestamp' => null, // timestamp does not mean time in sqlsrv
'bit' => $converter->convertBoolean ? $converter->toBool(...) : null,
default => $converter->resolve($meta['nativeType']),
};
}


public function isSupported(string $item): bool
{
return $item === self::SupportSubselect;
Expand Down
16 changes: 8 additions & 8 deletions src/Database/Drivers/Engines/SQLiteEngine.php
Original file line number Diff line number Diff line change
Expand Up @@ -60,14 +60,6 @@ public function determineExceptionClass(int $code, ?string $sqlState, string $me
}


public function resolveTypeConverter(string $nativeType, TypeConverter $converter): ?\Closure
{
return $converter->convertDateTime && in_array($nativeType, ['DATE', 'DATETIME'], true)
? (fn($value) => is_int($value) ? (new DateTime)->setTimestamp($value) : new DateTime($value))
: $converter->resolve($nativeType);
}


/********************* SQL ****************d*g**/


Expand Down Expand Up @@ -238,6 +230,14 @@ public function getForeignKeys(string $table): array
}


public function resolveColumnConverter(array $meta, TypeConverter $converter): ?\Closure
{
return $converter->convertDateTime && in_array($meta['nativeType'], ['DATE', 'DATETIME'], true)
? (fn($value): DateTime => is_int($value) ? (new DateTime)->setTimestamp($value) : new DateTime($value))
: $converter->resolve($meta['nativeType']);
}


public function isSupported(string $item): bool
{
return $item === self::SupportMultiInsertAsSelect || $item === self::SupportSubselect || $item === self::SupportMultiColumnAsOrCond;
Expand Down
14 changes: 2 additions & 12 deletions src/Database/Drivers/PDO/Connection.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@

use Nette;
use Nette\Database\Drivers;
use Nette\Database\TypeConverter;
use PDO;
use PDOException;

Expand All @@ -32,13 +31,6 @@ public function __construct(
) {
$this->engine = $this->getDatabaseEngine();

$this->typeConverter = new TypeConverter;
foreach (['convertBoolean', 'convertDateTime', 'convertDecimal'] as $opt) {
if (isset($options[$opt])) {
$this->typeConverter->$opt = (bool) $options[$opt];
}
}

try {
$this->pdo = new PDO($dsn, $username, $password, $options);
$this->initialize($options);
Expand Down Expand Up @@ -162,10 +154,8 @@ public function getNativeConnection(): PDO
}


public function resolveColumnConverter(array $meta): ?\Closure
public function getMetaTypeKey(): string
{
return isset($meta['native_type'])
? $this->typeConverter->resolve($meta['native_type'])
: null;
return 'native_type';
}
}
12 changes: 0 additions & 12 deletions src/Database/Drivers/PDO/MySQL/Connection.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,16 +40,4 @@ protected function initialize(array $options): void
$this->query('SET sql_mode=' . $this->quote($options['sqlmode']));
}
}


public function resolveColumnConverter(array $meta): ?\Closure
{
$type = $meta['native_type'] ?? null;
return match (true) {
!$type => null,
$type === 'NEWDECIMAL' && $meta['precision'] === 0 => fn($value) => is_float($tmp = $value * 1) ? $value : $tmp,
$type === 'TINY' && $meta['len'] === 1 && $this->typeConverter->convertBoolean => fn($value) => (bool) $value,
default => $this->engine->resolveTypeConverter($type, $this->typeConverter),
};
}
}
8 changes: 0 additions & 8 deletions src/Database/Drivers/PDO/PgSQL/Connection.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,4 @@ public function query(string $sql, array $params = []): Result
throw new ($this->convertException($e, $args, null, $sql, $params))(...$args);
}
}


public function resolveColumnConverter(array $meta): ?\Closure
{
return isset($meta['native_type'])
? $this->engine->resolveTypeConverter($meta['native_type'], $this->typeConverter)
: null;
}
}
6 changes: 3 additions & 3 deletions src/Database/Drivers/PDO/PgSQL/Result.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@

class Result extends Drivers\PDO\Result
{
private static array $metaCache = [];
private static array $columnsCache = [];


protected function collectMeta(): array
protected function collectColumnsInfo(): array
{
return self::$metaCache[$this->result->queryString] ??= parent::collectMeta();
return self::$columnsCache[$this->result->queryString] ??= parent::collectColumnsInfo();
}
}
Loading

0 comments on commit 8811567

Please sign in to comment.