diff --git a/CHANGELOG.md b/CHANGELOG.md index 34e983ff2..e92f048da 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ - Bug #756: Fix `Quoter::quoteTableName()` for sub-query with alias (@Tigrov) - Bug #761: Quote aliases of CTE in `WITH` queries (@Tigrov) - Chg #765: Deprecate `SchemaInterface::TYPE_JSONB` (@Tigrov) +- Enh #770: Move methods from concrete `Command` class to `AbstractPdoCommand` class (@Tigrov) ## 1.1.1 August 16, 2023 diff --git a/src/Driver/Pdo/AbstractPdoCommand.php b/src/Driver/Pdo/AbstractPdoCommand.php index bce283a53..c8348f832 100644 --- a/src/Driver/Pdo/AbstractPdoCommand.php +++ b/src/Driver/Pdo/AbstractPdoCommand.php @@ -14,12 +14,14 @@ use Yiisoft\Db\Command\AbstractCommand; use Yiisoft\Db\Command\Param; use Yiisoft\Db\Command\ParamInterface; +use Yiisoft\Db\Exception\ConvertException; use Yiisoft\Db\Exception\Exception; use Yiisoft\Db\Exception\InvalidParamException; use Yiisoft\Db\Profiler\Context\CommandContext; use Yiisoft\Db\Profiler\ProfilerAwareInterface; use Yiisoft\Db\Profiler\ProfilerAwareTrait; use Yiisoft\Db\Query\Data\DataReader; +use Yiisoft\Db\QueryBuilder\QueryBuilderInterface; /** * Represents a database command that can be executed using a PDO (PHP Data Object) database connection. @@ -161,6 +163,11 @@ protected function bindPendingParams(): void } } + protected function getQueryBuilder(): QueryBuilderInterface + { + return $this->db->getQueryBuilder(); + } + protected function getQueryMode(int $queryMode): string { return match ($queryMode) { @@ -184,7 +191,35 @@ protected function getQueryMode(int $queryMode): string * @throws Exception * @throws Throwable */ - abstract protected function internalExecute(string|null $rawSql): void; + protected function internalExecute(string|null $rawSql): void + { + $attempt = 0; + + while (true) { + try { + if ( + ++$attempt === 1 + && $this->isolationLevel !== null + && $this->db->getTransaction() === null + ) { + $this->db->transaction( + fn () => $this->internalExecute($rawSql), + $this->isolationLevel + ); + } else { + $this->pdoStatement?->execute(); + } + break; + } catch (PDOException $e) { + $rawSql = $rawSql ?: $this->getRawSql(); + $e = (new ConvertException($e, $rawSql))->run(); + + if ($this->retryHandler === null || !($this->retryHandler)($e, $attempt)) { + throw $e; + } + } + } + } /** * @throws InvalidParamException