From 95eceb6272cf37e9687a4338d462d26ec55a496e Mon Sep 17 00:00:00 2001 From: David Grudl Date: Tue, 27 Aug 2024 19:30:18 +0200 Subject: [PATCH] try/catch checking and converting of PDOException moved to drivers --- src/Bridges/DatabaseTracy/ConnectionPanel.php | 21 ++--- src/Database/Connection.php | 20 +---- src/Database/DriverException.php | 39 ++++------ src/Database/Drivers/Engine.php | 5 +- src/Database/Drivers/Engines/MSSQLEngine.php | 4 +- src/Database/Drivers/Engines/MySQLEngine.php | 25 ++---- src/Database/Drivers/Engines/ODBCEngine.php | 4 +- src/Database/Drivers/Engines/OracleEngine.php | 21 ++--- .../Drivers/Engines/PostgreSQLEngine.php | 29 +++---- .../Drivers/Engines/SQLServerEngine.php | 4 +- src/Database/Drivers/Engines/SQLiteEngine.php | 28 ++++--- src/Database/Drivers/PDO/Connection.php | 78 +++++++++++++++---- src/Database/Drivers/PDO/MSSQL/Driver.php | 2 +- src/Database/Drivers/PDO/MySQL/Driver.php | 2 +- src/Database/Drivers/PDO/OCI/Driver.php | 2 +- src/Database/Drivers/PDO/ODBC/Driver.php | 2 +- src/Database/Drivers/PDO/PgSQL/Driver.php | 2 +- src/Database/Drivers/PDO/Result.php | 28 +++++-- src/Database/Drivers/PDO/SQLSrv/Driver.php | 2 +- src/Database/Drivers/PDO/SQLite/Driver.php | 2 +- src/Database/Result.php | 18 +---- tests/Database.Tracy/panel.html | 2 +- .../Database/Connection.exceptions.mysql.phpt | 1 - .../Connection.exceptions.postgre.phpt | 1 - .../Connection.exceptions.sqlite.phpt | 1 - .../Database/Explorer/Selection.insert().phpt | 4 +- tests/Database/connection.option.lazy.phpt | 2 +- tests/bootstrap.php | 2 +- 28 files changed, 173 insertions(+), 178 deletions(-) diff --git a/src/Bridges/DatabaseTracy/ConnectionPanel.php b/src/Bridges/DatabaseTracy/ConnectionPanel.php index 3c2ffdfdc..30d17fba3 100644 --- a/src/Bridges/DatabaseTracy/ConnectionPanel.php +++ b/src/Bridges/DatabaseTracy/ConnectionPanel.php @@ -11,6 +11,7 @@ use Nette; use Nette\Database\Connection; +use Nette\Database\DriverException; use Nette\Database\Helpers; use Nette\Database\Result; use Tracy; @@ -72,7 +73,7 @@ private function logQuery(Connection $connection, $result): void $this->count++; $source = null; - $trace = $result instanceof \PDOException + $trace = $result instanceof DriverException ? $result->getTrace() : debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS); foreach ($trace as $row) { @@ -93,26 +94,20 @@ private function logQuery(Connection $connection, $result): void if ($this->count < $this->maxQueries) { $this->events[] = [$connection, $result->getQueryString(), $result->getParameters(), $source, $result->getTime(), $result->getRowCount(), null]; } - } elseif ($result instanceof \PDOException && $this->count < $this->maxQueries) { - $this->events[] = [$connection, $result->queryString, null, $source, null, null, $result->getMessage()]; + } elseif ($result instanceof DriverException && $this->count < $this->maxQueries) { + $this->events[] = [$connection, $result->getQueryString(), null, $source, null, null, $result->getMessage()]; } } public static function renderException(?\Throwable $e): ?array { - if (!$e instanceof \PDOException) { + if (!$e instanceof DriverException) { return null; } - if (isset($e->queryString)) { - $sql = $e->queryString; - - } elseif ($item = Tracy\Helpers::findTrace($e->getTrace(), 'PDO::prepare')) { - $sql = $item['args'][0]; - } - - return isset($sql) ? [ + $sql = $e->getQueryString(); + return $sql ? [ 'tab' => 'SQL', 'panel' => Helpers::dumpSql($sql, $e->params ?? []), ] : null; @@ -150,7 +145,7 @@ public function getPanel(): ?string : 'EXPLAIN'; $rows = $connection->getConnection()->query("$cmd $sql", $params); for ($explain = []; $row = $rows->fetch(); $explain[] = $row); - } catch (\PDOException) { + } catch (DriverException) { } } diff --git a/src/Database/Connection.php b/src/Database/Connection.php index a47507b79..cb23fffb0 100644 --- a/src/Database/Connection.php +++ b/src/Database/Connection.php @@ -12,7 +12,6 @@ use JetBrains\PhpStorm\Language; use Nette; use Nette\Utils\Arrays; -use PDOException; /** @@ -54,17 +53,10 @@ public function __construct( public function connect(): void { - if ($this->connection) { - return; - } - - try { + if (!$this->connection) { $this->connection = $this->driver->connect(); - } catch (PDOException $e) { - throw ConnectionException::from($e); + Arrays::invoke($this->onConnect, $this); } - - Arrays::invoke($this->onConnect, $this); } @@ -143,11 +135,7 @@ public function setRowNormalizer(?callable $normalizer): static public function getInsertId(?string $sequence = null): string { - try { - return $this->getConnection()->getInsertId($sequence); - } catch (PDOException $e) { - throw $this->getDatabaseEngine()->convertException($e); - } + return $this->getConnection()->getInsertId($sequence); } @@ -223,7 +211,7 @@ public function query(#[Language('SQL')] string $sql, #[Language('GenericSQL')] [$this->sql, $params] = $this->preprocess($sql, ...$params); try { $result = new Result($this, $this->sql, $params); - } catch (PDOException $e) { + } catch (DriverException $e) { Arrays::invoke($this->onQuery, $this, $e); throw $e; } diff --git a/src/Database/DriverException.php b/src/Database/DriverException.php index aad02cd6e..1ab98d27c 100644 --- a/src/Database/DriverException.php +++ b/src/Database/DriverException.php @@ -13,51 +13,40 @@ /** * Base class for all errors in the driver or SQL server. */ -class DriverException extends \PDOException +class DriverException extends \Exception { - public ?string $queryString = null; - public ?array $params = null; - - - public static function from(\PDOException $src): static - { - $e = new static($src->message, 0, $src); - $e->file = $src->file; - $e->line = $src->line; - if (!$src->errorInfo && preg_match('#SQLSTATE\[(.*?)\] \[(.*?)\] (.*)#A', $src->message, $m)) { - $m[2] = (int) $m[2]; - $e->errorInfo = array_slice($m, 1); - $e->code = $m[1]; - } else { - $e->errorInfo = $src->errorInfo; - $e->code = $src->code; - $e->code = $e->errorInfo[0] ?? $src->code; - } - - return $e; + public function __construct( + string $message, + private readonly ?string $sqlState = null, + private int $driverCode = 0, + private readonly ?SqlLiteral $query = null, + ?\Throwable $previous = null, + ) { + parent::__construct($message, 0, $previous); + $this->code = $sqlState ?: null; } public function getDriverCode(): int|string|null { - return $this->errorInfo[1] ?? null; + return $this->driverCode ?: null; } public function getSqlState(): ?string { - return $this->errorInfo[0] ?? null; + return $this->sqlState; } public function getQueryString(): ?string { - return $this->queryString; + return $this->query?->getSql(); } public function getParameters(): ?array { - return $this->params; + return $this->query?->getParameters(); } } diff --git a/src/Database/Drivers/Engine.php b/src/Database/Drivers/Engine.php index 6ca92c3b9..2d3b78cdb 100644 --- a/src/Database/Drivers/Engine.php +++ b/src/Database/Drivers/Engine.php @@ -9,7 +9,6 @@ namespace Nette\Database\Drivers; -use Nette\Database; use Nette\Database\TypeConverter; @@ -27,9 +26,9 @@ interface Engine SupportSchema = 'schema'; /** - * Converts PDOException to DriverException or its descendant. + * Suggests an appropriate class for the exception. */ - function convertException(\PDOException $e): Database\DriverException; + static function determineExceptionClass(int $code, ?string $sqlState, string $message): ?string; /** * Delimites identifier for use in a SQL statement. diff --git a/src/Database/Drivers/Engines/MSSQLEngine.php b/src/Database/Drivers/Engines/MSSQLEngine.php index 37ffd8646..49a806f63 100644 --- a/src/Database/Drivers/Engines/MSSQLEngine.php +++ b/src/Database/Drivers/Engines/MSSQLEngine.php @@ -26,9 +26,9 @@ public function __construct( } - public function convertException(\PDOException $e): Nette\Database\DriverException + public static function determineExceptionClass(int $code, ?string $sqlState, string $message): ?string { - return Nette\Database\DriverException::from($e); + return null; } diff --git a/src/Database/Drivers/Engines/MySQLEngine.php b/src/Database/Drivers/Engines/MySQLEngine.php index 668bdb442..88e9a5af6 100644 --- a/src/Database/Drivers/Engines/MySQLEngine.php +++ b/src/Database/Drivers/Engines/MySQLEngine.php @@ -26,24 +26,15 @@ public function __construct( } - public function convertException(\PDOException $e): Nette\Database\DriverException + public static function determineExceptionClass(int $code, ?string $sqlState, string $message): ?string { - $code = $e->errorInfo[1] ?? null; - if (in_array($code, [1216, 1217, 1451, 1452, 1701], strict: true)) { - return Nette\Database\ForeignKeyConstraintViolationException::from($e); - - } elseif (in_array($code, [1062, 1557, 1569, 1586], strict: true)) { - return Nette\Database\UniqueConstraintViolationException::from($e); - - } elseif ($code >= 2001 && $code <= 2028) { - return Nette\Database\ConnectionException::from($e); - - } elseif (in_array($code, [1048, 1121, 1138, 1171, 1252, 1263, 1566], strict: true)) { - return Nette\Database\NotNullConstraintViolationException::from($e); - - } else { - return Nette\Database\DriverException::from($e); - } + return match (true) { + in_array($code, [1216, 1217, 1451, 1452, 1701], strict: true) => Nette\Database\ForeignKeyConstraintViolationException::class, + in_array($code, [1062, 1557, 1569, 1586], strict: true) => Nette\Database\UniqueConstraintViolationException::class, + $code >= 2001 && $code <= 2028 => Nette\Database\ConnectionException::class, + in_array($code, [1048, 1121, 1138, 1171, 1252, 1263, 1566], strict: true) => Nette\Database\NotNullConstraintViolationException::class, + default => null, + }; } diff --git a/src/Database/Drivers/Engines/ODBCEngine.php b/src/Database/Drivers/Engines/ODBCEngine.php index ebff18ced..eb475f035 100644 --- a/src/Database/Drivers/Engines/ODBCEngine.php +++ b/src/Database/Drivers/Engines/ODBCEngine.php @@ -19,9 +19,9 @@ */ class ODBCEngine implements Engine { - public function convertException(\PDOException $e): Nette\Database\DriverException + public static function determineExceptionClass(int $code, ?string $sqlState, string $message): ?string { - return Nette\Database\DriverException::from($e); + return null; } diff --git a/src/Database/Drivers/Engines/OracleEngine.php b/src/Database/Drivers/Engines/OracleEngine.php index f6bd450b4..87ba6be1e 100644 --- a/src/Database/Drivers/Engines/OracleEngine.php +++ b/src/Database/Drivers/Engines/OracleEngine.php @@ -29,21 +29,14 @@ public function __construct( } - public function convertException(\PDOException $e): Nette\Database\DriverException + public static function determineExceptionClass(int $code, ?string $sqlState, string $message): ?string { - $code = $e->errorInfo[1] ?? null; - if (in_array($code, [1, 2299, 38911], strict: true)) { - return Nette\Database\UniqueConstraintViolationException::from($e); - - } elseif (in_array($code, [1400], strict: true)) { - return Nette\Database\NotNullConstraintViolationException::from($e); - - } elseif (in_array($code, [2266, 2291, 2292], strict: true)) { - return Nette\Database\ForeignKeyConstraintViolationException::from($e); - - } else { - return Nette\Database\DriverException::from($e); - } + return match (true) { + in_array($code, [1, 2299, 38911], strict: true) => Nette\Database\UniqueConstraintViolationException::class, + in_array($code, [1400], strict: true) => Nette\Database\NotNullConstraintViolationException::class, + in_array($code, [2266, 2291, 2292], strict: true) => Nette\Database\ForeignKeyConstraintViolationException::class, + default => null, + }; } diff --git a/src/Database/Drivers/Engines/PostgreSQLEngine.php b/src/Database/Drivers/Engines/PostgreSQLEngine.php index 35ad3566b..8c20816e7 100644 --- a/src/Database/Drivers/Engines/PostgreSQLEngine.php +++ b/src/Database/Drivers/Engines/PostgreSQLEngine.php @@ -26,27 +26,16 @@ public function __construct( } - public function convertException(\PDOException $e): Nette\Database\DriverException + public static function determineExceptionClass(int $code, ?string $sqlState, string $message): ?string { - $code = $e->errorInfo[0] ?? null; - if ($code === '0A000' && str_contains($e->getMessage(), 'truncate')) { - return Nette\Database\ForeignKeyConstraintViolationException::from($e); - - } elseif ($code === '23502') { - return Nette\Database\NotNullConstraintViolationException::from($e); - - } elseif ($code === '23503') { - return Nette\Database\ForeignKeyConstraintViolationException::from($e); - - } elseif ($code === '23505') { - return Nette\Database\UniqueConstraintViolationException::from($e); - - } elseif ($code === '08006') { - return Nette\Database\ConnectionException::from($e); - - } else { - return Nette\Database\DriverException::from($e); - } + return match ($sqlState) { + '0A000' => str_contains($message, 'truncate') ? Nette\Database\ForeignKeyConstraintViolationException::class : null, + '23502' => Nette\Database\NotNullConstraintViolationException::class, + '23503' => Nette\Database\ForeignKeyConstraintViolationException::class, + '23505' => Nette\Database\UniqueConstraintViolationException::class, + '08006' => Nette\Database\ConnectionException::class, + default => null, + }; } diff --git a/src/Database/Drivers/Engines/SQLServerEngine.php b/src/Database/Drivers/Engines/SQLServerEngine.php index 7430a5811..91523fb5b 100644 --- a/src/Database/Drivers/Engines/SQLServerEngine.php +++ b/src/Database/Drivers/Engines/SQLServerEngine.php @@ -26,9 +26,9 @@ public function __construct( } - public function convertException(\PDOException $e): Nette\Database\DriverException + public static function determineExceptionClass(int $code, ?string $sqlState, string $message): ?string { - return Nette\Database\DriverException::from($e); + return null; } diff --git a/src/Database/Drivers/Engines/SQLiteEngine.php b/src/Database/Drivers/Engines/SQLiteEngine.php index 7d80b4d05..7c3e787a8 100644 --- a/src/Database/Drivers/Engines/SQLiteEngine.php +++ b/src/Database/Drivers/Engines/SQLiteEngine.php @@ -30,34 +30,32 @@ public function __construct( } - public function convertException(\PDOException $e): Nette\Database\DriverException + public static function determineExceptionClass(int $code, ?string $sqlState, string $message): ?string { - $code = $e->errorInfo[1] ?? null; - $msg = $e->getMessage(); if ($code !== 19) { - return Nette\Database\DriverException::from($e); + return null; } elseif ( - str_contains($msg, 'must be unique') - || str_contains($msg, 'is not unique') - || str_contains($msg, 'UNIQUE constraint failed') + str_contains($message, 'must be unique') + || str_contains($message, 'is not unique') + || str_contains($message, 'UNIQUE constraint failed') ) { - return Nette\Database\UniqueConstraintViolationException::from($e); + return Nette\Database\UniqueConstraintViolationException::class; } elseif ( - str_contains($msg, 'may not be null') - || str_contains($msg, 'NOT NULL constraint failed') + str_contains($message, 'may not be null') + || str_contains($message, 'NOT NULL constraint failed') ) { - return Nette\Database\NotNullConstraintViolationException::from($e); + return Nette\Database\NotNullConstraintViolationException::class; } elseif ( - str_contains($msg, 'foreign key constraint failed') - || str_contains($msg, 'FOREIGN KEY constraint failed') + str_contains($message, 'foreign key constraint failed') + || str_contains($message, 'FOREIGN KEY constraint failed') ) { - return Nette\Database\ForeignKeyConstraintViolationException::from($e); + return Nette\Database\ForeignKeyConstraintViolationException::class; } else { - return Nette\Database\ConstraintViolationException::from($e); + return Nette\Database\ConstraintViolationException::class; } } diff --git a/src/Database/Drivers/PDO/Connection.php b/src/Database/Drivers/PDO/Connection.php index 2d6afc675..c39175bb3 100644 --- a/src/Database/Drivers/PDO/Connection.php +++ b/src/Database/Drivers/PDO/Connection.php @@ -9,8 +9,11 @@ namespace Nette\Database\Drivers\PDO; +use Nette; use Nette\Database\Drivers; +use Nette\Database\SqlLiteral; use PDO; +use PDOException; class Connection implements Drivers\Connection @@ -21,13 +24,43 @@ class Connection implements Drivers\Connection public function __construct( + private string $exceptionClass, string $dsn, ?string $username = null, #[\SensitiveParameter] ?string $password = null, array $options = [], ) { - $this->pdo = new PDO($dsn, $username, $password, $options); + try { + $this->pdo = new PDO($dsn, $username, $password, $options); + } catch (PDOException $e) { + throw new ($this->convertException($e, $args, Nette\Database\ConnectionException::class))(...$args); + } + } + + + public function convertException( + PDOException $e, + ?array &$args, + ?string $class = null, + ?SqlLiteral $query = null, + ): string + { + if ($e->errorInfo !== null) { + [$sqlState, $code] = $e->errorInfo; + $code ??= 0; + } elseif (preg_match('#SQLSTATE\[(.*?)\] \[(.*?)\] (.*)#A', $e->getMessage(), $m)) { + $sqlState = $m[1]; + $code = (int) $m[2]; + } else { + $code = $e->getCode(); + $sqlState = null; + } + + $args = [$e->getMessage(), $sqlState, $code, $query, $e]; + return $this->exceptionClass::determineExceptionClass($code, $sqlState, $e->getMessage()) + ?? $class + ?? Nette\Database\DriverException::class; } @@ -35,9 +68,16 @@ public function query(string $sql, array $params = []): Result { $types = ['boolean' => PDO::PARAM_BOOL, 'integer' => PDO::PARAM_INT, 'resource' => PDO::PARAM_LOB, 'NULL' => PDO::PARAM_NULL]; - $statement = $this->pdo->prepare($sql); - foreach ($params as $key => $value) { - $statement->bindValue(is_int($key) ? $key + 1 : $key, $value, $types[gettype($value)] ?? PDO::PARAM_STR); + try { + $statement = $this->pdo->prepare($sql); + foreach ($params as $key => $value) { + $statement->bindValue(is_int($key) ? $key + 1 : $key, $value, $types[gettype($value)] ?? PDO::PARAM_STR); + } + $statement->execute(); + return new ($this->resultClass)($statement, $this); + + } catch (PDOException $e) { + throw new ($this->convertException($e, $args, null, new SqlLiteral($sql, $params)))(...$args); } $statement->execute(); @@ -47,30 +87,42 @@ public function query(string $sql, array $params = []): Result public function beginTransaction(): void { - $this->pdo->beginTransaction(); - + try { + $this->pdo->beginTransaction(); + } catch (PDOException $e) { + throw new ($this->convertException($e, $args))(...$args); + } } public function commit(): void { - $this->pdo->commit(); - + try { + $this->pdo->commit(); + } catch (PDOException $e) { + throw new ($this->convertException($e, $args))(...$args); + } } public function rollBack(): void { - $this->pdo->rollBack(); - + try { + $this->pdo->rollBack(); + } catch (PDOException $e) { + throw new ($this->convertException($e, $args))(...$args); + } } public function getInsertId(?string $sequence = null): string { - $res = $this->pdo->lastInsertId($sequence); - return $res === false ? '0' : $res; - + try { + $res = $this->pdo->lastInsertId($sequence); + return $res === false ? '0' : $res; + } catch (PDOException $e) { + throw new ($this->convertException($e, $args))(...$args); + } } diff --git a/src/Database/Drivers/PDO/MSSQL/Driver.php b/src/Database/Drivers/PDO/MSSQL/Driver.php index efddee0df..c1d9c4b29 100644 --- a/src/Database/Drivers/PDO/MSSQL/Driver.php +++ b/src/Database/Drivers/PDO/MSSQL/Driver.php @@ -29,7 +29,7 @@ public function __construct( public function connect(): Drivers\Connection { - return new Drivers\PDO\Connection(...$this->params); + return new Drivers\PDO\Connection(self::EngineClass, ...$this->params); } diff --git a/src/Database/Drivers/PDO/MySQL/Driver.php b/src/Database/Drivers/PDO/MySQL/Driver.php index 9174f77df..9a5a93235 100644 --- a/src/Database/Drivers/PDO/MySQL/Driver.php +++ b/src/Database/Drivers/PDO/MySQL/Driver.php @@ -34,7 +34,7 @@ public function __construct( public function connect(): Drivers\Connection { - $connection = new Drivers\PDO\Connection(...$this->params); + $connection = new Drivers\PDO\Connection(self::EngineClass, ...$this->params); $options = $this->params['options']; if ($charset = $options['charset'] ?? self::DefaultCharset) { $connection->query('SET NAMES ' . $connection->quote($charset)); diff --git a/src/Database/Drivers/PDO/OCI/Driver.php b/src/Database/Drivers/PDO/OCI/Driver.php index 47f9deb39..142db82d5 100644 --- a/src/Database/Drivers/PDO/OCI/Driver.php +++ b/src/Database/Drivers/PDO/OCI/Driver.php @@ -31,7 +31,7 @@ public function __construct( public function connect(): Drivers\Connection { - return new Drivers\PDO\Connection(...$this->params); + return new Drivers\PDO\Connection(self::EngineClass, ...$this->params); } diff --git a/src/Database/Drivers/PDO/ODBC/Driver.php b/src/Database/Drivers/PDO/ODBC/Driver.php index d5afc44ca..00aaad2d1 100644 --- a/src/Database/Drivers/PDO/ODBC/Driver.php +++ b/src/Database/Drivers/PDO/ODBC/Driver.php @@ -29,7 +29,7 @@ public function __construct( public function connect(): Drivers\Connection { - return new Drivers\PDO\Connection(...$this->params); + return new Drivers\PDO\Connection(self::EngineClass, ...$this->params); } diff --git a/src/Database/Drivers/PDO/PgSQL/Driver.php b/src/Database/Drivers/PDO/PgSQL/Driver.php index e294cb517..972ac035b 100644 --- a/src/Database/Drivers/PDO/PgSQL/Driver.php +++ b/src/Database/Drivers/PDO/PgSQL/Driver.php @@ -29,7 +29,7 @@ public function __construct( public function connect(): Drivers\Connection { - $connection = new Drivers\PDO\Connection(...$this->params); + $connection = new Drivers\PDO\Connection(self::EngineClass, ...$this->params); $connection->resultClass = Result::class; return $connection; } diff --git a/src/Database/Drivers/PDO/Result.php b/src/Database/Drivers/PDO/Result.php index f62a885ea..575e09af8 100644 --- a/src/Database/Drivers/PDO/Result.php +++ b/src/Database/Drivers/PDO/Result.php @@ -11,6 +11,7 @@ use Nette\Database\DriverException; use Nette\Database\Drivers; +use PDOException; class Result implements Drivers\Result @@ -42,24 +43,37 @@ public function fetch(): ?array public function fetchList(): ?array { - $row = $this->result->fetch(\PDO::FETCH_NUM); - if (!$row) { - $this->free(); - return null; + try { + $row = $this->result->fetch(\PDO::FETCH_NUM); + if (!$row) { + $this->free(); + return null; + } + return $row; + + } catch (PDOException $e) { + throw new ($this->connection->convertException($e, $args))(...$args); } - return $row; } public function getColumnCount(): int { - return $this->result->columnCount(); + try { + return $this->result->columnCount(); + } catch (PDOException $e) { + throw new ($this->connection->convertException($e, $args))(...$args); + } } public function getRowCount(): int { - return $this->result->rowCount(); + try { + return $this->result->rowCount(); + } catch (PDOException $e) { + throw new ($this->connection->convertException($e, $args))(...$args); + } } diff --git a/src/Database/Drivers/PDO/SQLSrv/Driver.php b/src/Database/Drivers/PDO/SQLSrv/Driver.php index 1709d8bad..7f5d856e6 100644 --- a/src/Database/Drivers/PDO/SQLSrv/Driver.php +++ b/src/Database/Drivers/PDO/SQLSrv/Driver.php @@ -31,7 +31,7 @@ public function __construct( public function connect(): Drivers\Connection { - $connection = new Drivers\PDO\Connection(...$this->params); + $connection = new Drivers\PDO\Connection(self::EngineClass, ...$this->params); $connection->metaTypeKey = 'sqlsrv:decl_type'; return $connection; } diff --git a/src/Database/Drivers/PDO/SQLite/Driver.php b/src/Database/Drivers/PDO/SQLite/Driver.php index 645f09d91..f98c00468 100644 --- a/src/Database/Drivers/PDO/SQLite/Driver.php +++ b/src/Database/Drivers/PDO/SQLite/Driver.php @@ -31,7 +31,7 @@ public function __construct( public function connect(): Drivers\Connection { - $connection = new Drivers\PDO\Connection(...$this->params); + $connection = new Drivers\PDO\Connection(self::EngineClass, ...$this->params); $connection->metaTypeKey = 'sqlite:decl_type'; return $connection; } diff --git a/src/Database/Result.php b/src/Database/Result.php index 47a2adcbd..9e8358130 100644 --- a/src/Database/Result.php +++ b/src/Database/Result.php @@ -34,21 +34,11 @@ public function __construct( private readonly array $params, ) { $time = microtime(true); - - - try { - if (str_starts_with($queryString, '::')) { - $connection->getConnection()->{substr($queryString, 2)}(); - } else { - $this->result = $connection->getConnection()->query($queryString, $params); - } - } catch (\PDOException $e) { - $e = $connection->getDatabaseEngine()->convertException($e); - $e->queryString = $queryString; - $e->params = $params; - throw $e; + if (str_starts_with($queryString, '::')) { + $connection->getConnection()->{substr($queryString, 2)}(); + } else { + $this->result = $connection->getConnection()->query($queryString, $params); } - $this->time = microtime(true) - $time; } diff --git a/tests/Database.Tracy/panel.html b/tests/Database.Tracy/panel.html index b6274a51a..7bb0c3ecd 100644 --- a/tests/Database.Tracy/panel.html +++ b/tests/Database.Tracy/panel.html @@ -28,7 +28,7 @@

Queries: 4, time: %a% ms, foo

ERROR
SELECT
- %a%SQLiteEngine.php:%d% + %a%Result.php:%d% diff --git a/tests/Database/Connection.exceptions.mysql.phpt b/tests/Database/Connection.exceptions.mysql.phpt index 1d60d5adc..7671df70f 100644 --- a/tests/Database/Connection.exceptions.mysql.phpt +++ b/tests/Database/Connection.exceptions.mysql.phpt @@ -33,7 +33,6 @@ test('Exception thrown when calling rollback with no active transaction', functi fn() => $connection->rollback(), Nette\Database\DriverException::class, 'There is no active transaction', - 0, ); Assert::same(null, $e->getDriverCode()); }); diff --git a/tests/Database/Connection.exceptions.postgre.phpt b/tests/Database/Connection.exceptions.postgre.phpt index 717245d38..5ab217c01 100644 --- a/tests/Database/Connection.exceptions.postgre.phpt +++ b/tests/Database/Connection.exceptions.postgre.phpt @@ -34,7 +34,6 @@ test('Exception thrown when calling rollback with no active transaction', functi fn() => $connection->rollback(), Nette\Database\DriverException::class, 'There is no active transaction', - 0, ); Assert::same(null, $e->getDriverCode()); diff --git a/tests/Database/Connection.exceptions.sqlite.phpt b/tests/Database/Connection.exceptions.sqlite.phpt index dbd66d5cb..4dcf395c9 100644 --- a/tests/Database/Connection.exceptions.sqlite.phpt +++ b/tests/Database/Connection.exceptions.sqlite.phpt @@ -33,7 +33,6 @@ test('Exception thrown when calling rollback with no active transaction', functi fn() => $connection->rollback(), Nette\Database\DriverException::class, 'There is no active transaction', - 0, ); Assert::same(null, $e->getDriverCode()); diff --git a/tests/Database/Explorer/Selection.insert().phpt b/tests/Database/Explorer/Selection.insert().phpt index f96e6f88c..69e219c90 100644 --- a/tests/Database/Explorer/Selection.insert().phpt +++ b/tests/Database/Explorer/Selection.insert().phpt @@ -41,7 +41,7 @@ $book2 = $books->insert([ Assert::same('eddard stark', $book2->author->name); // SELECT * FROM `author` WHERE (`author`.`id` IN (11, 15)) -// SQL Server throw PDOException because does not allow insert explicit value for IDENTITY column. +// SQL Server throw exception because does not allow insert explicit value for IDENTITY column. // This exception is about primary key violation. if ($driverName !== 'sqlsrv') { Assert::exception( @@ -50,7 +50,7 @@ if ($driverName !== 'sqlsrv') { 'name' => 'Jon Snow', 'web' => 'http://example.com', ]), - PDOException::class, + Nette\Database\UniqueConstraintViolationException::class, ); } diff --git a/tests/Database/connection.option.lazy.phpt b/tests/Database/connection.option.lazy.phpt index 56fee8c52..c7d599e6c 100644 --- a/tests/Database/connection.option.lazy.phpt +++ b/tests/Database/connection.option.lazy.phpt @@ -48,7 +48,7 @@ test('connect & disconnect', function () { try { $connection = new Nette\Database\Connection($options['dsn'], $options['username'], $options['password']); - } catch (PDOException $e) { + } catch (Nette\Database\DriverException $e) { Tester\Environment::skip("Connection to '$options[dsn]' failed. Reason: " . $e->getMessage()); } diff --git a/tests/bootstrap.php b/tests/bootstrap.php index efbbef0e4..85c608a76 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -36,7 +36,7 @@ function connectToDB(array $options = []): Nette\Database\Explorer try { $connection = new Nette\Database\Connection($args['dsn'], $args['username'], $args['password'], $args['options']); - } catch (PDOException $e) { + } catch (Nette\Database\ConnectionException $e) { Tester\Environment::skip("Connection to '$args[dsn]' failed. Reason: " . $e->getMessage()); }