diff --git a/src/Swoole/PgSQL/Connection.php b/src/Swoole/PgSQL/Connection.php index 0ba0429..1f875a8 100644 --- a/src/Swoole/PgSQL/Connection.php +++ b/src/Swoole/PgSQL/Connection.php @@ -6,9 +6,11 @@ use Doctrine\DBAL\Driver\Connection as ConnectionInterface; use Doctrine\DBAL\ParameterType; -use Exception; use OpsWay\Doctrine\DBAL\SQLParserUtils; +use OpsWay\Doctrine\DBAL\Swoole\PgSQL\Exception\ConnectionException; +use OpsWay\Doctrine\DBAL\Swoole\PgSQL\Exception\DriverException as SwooleDriverException; +use function is_resource; use function strlen; use function substr; @@ -21,7 +23,7 @@ public function __construct(private ConnectionWrapperInterface $connection) /** * {@inheritdoc} * - * @throws Exception + * @throws SwooleDriverException */ public function prepare(string $sql) : Statement { @@ -46,9 +48,12 @@ public function prepare(string $sql) : Statement */ public function query(string $sql) : Result { - /** @var resource $resource */ $resource = $this->connection->query($sql); + if (! is_resource($resource)) { + throw ConnectionException::fromConnection($this->connection); + } + return new Result($this->connection, $resource); } @@ -69,11 +74,12 @@ public function quote($value, $type = ParameterType::STRING) : string public function exec(string $sql) : int { $query = $this->connection->query($sql); - if ($query !== false) { - return $this->connection->affectedRows($query); + + if (! is_resource($query)) { + throw ConnectionException::fromConnection($this->connection); } - return 0; + return $this->connection->affectedRows($query); } /** diff --git a/src/Swoole/PgSQL/ConnectionPullFactory.php b/src/Swoole/PgSQL/ConnectionPullFactory.php index c9373b8..c7d1cfd 100644 --- a/src/Swoole/PgSQL/ConnectionPullFactory.php +++ b/src/Swoole/PgSQL/ConnectionPullFactory.php @@ -20,6 +20,7 @@ * delay: 1, * }, * } + * @psalm-suppress MissingDependency, UndefinedClass */ class ConnectionPullFactory { @@ -30,9 +31,8 @@ class ConnectionPullFactory /** * @psalm-param ConnectionPullFactoryConfig $params - * @return mixed */ - public function __invoke(array $params) + public function __invoke(array $params) : DownscaleableConnectionPool { /** * @var int|null $pullSize diff --git a/src/Swoole/PgSQL/Exception/ConnectionException.php b/src/Swoole/PgSQL/Exception/ConnectionException.php index 8b3507d..7211996 100644 --- a/src/Swoole/PgSQL/Exception/ConnectionException.php +++ b/src/Swoole/PgSQL/Exception/ConnectionException.php @@ -11,6 +11,8 @@ /** @psalm-immutable */ class ConnectionException extends Exception implements DBALDriverException { + use ExceptionFromConnectionTrait; + public function __construct( string $message = '', private ?string $errorCode = null, diff --git a/src/Swoole/PgSQL/Exception/DriverException.php b/src/Swoole/PgSQL/Exception/DriverException.php index 73bc618..e8fadb2 100644 --- a/src/Swoole/PgSQL/Exception/DriverException.php +++ b/src/Swoole/PgSQL/Exception/DriverException.php @@ -11,6 +11,8 @@ /** @psalm-immutable */ class DriverException extends Exception implements DBALDriverException { + use ExceptionFromConnectionTrait; + public function __construct( string $message = '', private ?string $errorCode = null, diff --git a/src/Swoole/PgSQL/Exception/ExceptionFromConnectionTrait.php b/src/Swoole/PgSQL/Exception/ExceptionFromConnectionTrait.php new file mode 100644 index 0000000..2bedc79 --- /dev/null +++ b/src/Swoole/PgSQL/Exception/ExceptionFromConnectionTrait.php @@ -0,0 +1,26 @@ +resultDiag() ?? []; + $sqlstate = (string) ($resultDiag['sqlstate'] ?? ''); + + return new self( + $connection->error(), + (string) $connection->errorCode(), + $sqlstate, + $connection->errorCode(), + ); + } +} diff --git a/src/Swoole/PgSQL/PsqlConnectionWrapper.php b/src/Swoole/PgSQL/PsqlConnectionWrapper.php index be5bacf..6c1192a 100644 --- a/src/Swoole/PgSQL/PsqlConnectionWrapper.php +++ b/src/Swoole/PgSQL/PsqlConnectionWrapper.php @@ -7,6 +7,9 @@ use ArrayAccess; use Swoole\Coroutine\PostgreSQL; +use function count; +use function is_array; +use function is_resource; use function mt_rand; use function time; use function uniqid; @@ -60,8 +63,13 @@ public function isReusable() : bool public function query(string $sql) { $this->usedTimes++; + $result = $this->connection->query($sql); - return $this->connection->query($sql); + if (! is_resource($result)) { + $result = false; + } + + return $result; } /** @param resource $queryResult */ @@ -73,7 +81,13 @@ public function affectedRows($queryResult) : int /** @param resource $queryResult */ public function fetchAssoc($queryResult) : array|bool { - return $this->connection->fetchAssoc($queryResult); + $result = $this->connection->fetchAssoc($queryResult); + + if (is_array($result) && count($result) === 0) { + $result = false; + } + + return $result; } /** @param resource $queryResult*/ diff --git a/src/Swoole/PgSQL/Result.php b/src/Swoole/PgSQL/Result.php index f87c1db..ac9cee0 100644 --- a/src/Swoole/PgSQL/Result.php +++ b/src/Swoole/PgSQL/Result.php @@ -5,7 +5,9 @@ namespace OpsWay\Doctrine\DBAL\Swoole\PgSQL; use Doctrine\DBAL\Driver\Result as ResultInterface; -use Exception; +use OpsWay\Doctrine\DBAL\Swoole\PgSQL\Exception\DriverException as SwooleDriverException; + +use function is_resource; use const OPENSWOOLE_PGSQL_NUM; @@ -19,8 +21,8 @@ public function __construct(private ConnectionWrapperInterface $connection, priv /** {@inheritdoc} */ public function fetchNumeric() : array|bool { - if (! $this->result) { - throw new Exception('Result expecting been resource here'); + if (! is_resource($this->result)) { + throw SwooleDriverException::fromConnection($this->connection); } /** * @psalm-var list|false $result @@ -34,8 +36,8 @@ public function fetchNumeric() : array|bool /** {@inheritdoc} */ public function fetchAssociative() : array|bool { - if (! $this->result) { - throw new Exception('Result expecting been resource here'); + if (! is_resource($this->result)) { + throw SwooleDriverException::fromConnection($this->connection); } /** @psalm-var array|false $result */ $result = $this->connection->fetchAssoc($this->result); @@ -91,8 +93,8 @@ public function fetchFirstColumn() : array /** {@inheritdoc} */ public function rowCount() : int { - if (! $this->result) { - throw new Exception('Result expecting been resource here'); + if (! is_resource($this->result)) { + throw SwooleDriverException::fromConnection($this->connection); } return $this->connection->affectedRows($this->result); @@ -101,8 +103,8 @@ public function rowCount() : int /** {@inheritdoc} */ public function columnCount() : int { - if (! $this->result) { - throw new Exception('Result expecting been resource here'); + if (! is_resource($this->result)) { + throw SwooleDriverException::fromConnection($this->connection); } return $this->connection->fieldCount($this->result); diff --git a/src/Swoole/PgSQL/Statement.php b/src/Swoole/PgSQL/Statement.php index cdd8b57..be78c44 100644 --- a/src/Swoole/PgSQL/Statement.php +++ b/src/Swoole/PgSQL/Statement.php @@ -4,11 +4,9 @@ namespace OpsWay\Doctrine\DBAL\Swoole\PgSQL; -use ArrayAccess; use Doctrine\DBAL\Driver\Result as ResultInterface; use Doctrine\DBAL\Driver\Statement as StatementInterface; use Doctrine\DBAL\ParameterType; -use Exception; use OpsWay\Doctrine\DBAL\Swoole\PgSQL\Exception\DriverException as SwooleDriverException; use function is_array; @@ -25,7 +23,7 @@ public function __construct(private ConnectionWrapperInterface $connection, stri { $this->key = uniqid('stmt_', true); if ($this->connection->prepare($this->key, $sql) === false) { - throw new Exception($this->errorInfo()); + throw SwooleDriverException::fromConnection($this->connection); } } @@ -58,7 +56,7 @@ public function bindParam($param, &$variable, $type = ParameterType::STRING, $le /** * @param mixed|null $params - * @throws Exception + * @throws SwooleDriverException * @psalm-suppress ImplementedReturnTypeMismatch */ public function execute($params = []) : ResultInterface @@ -75,16 +73,7 @@ public function execute($params = []) : ResultInterface $result = $this->connection->execute($this->key, $mergedParams); if (! is_resource($result)) { - /** @var ArrayAccess $resultDiag */ - $resultDiag = $this->connection->resultDiag() ?? []; - $sqlstate = (string) ($resultDiag['sqlstate'] ?? ''); - - throw new SwooleDriverException( - $this->errorInfo(), - (string) $this->errorCode(), - $sqlstate, - $this->errorCode(), - ); + throw SwooleDriverException::fromConnection($this->connection); } return new Result($this->connection, $result);