diff options
author | Robin Appelman <robin@icewind.nl> | 2024-07-16 17:38:28 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-07-16 17:38:28 +0200 |
commit | decae5a45a93e0c16f748f38151575f8eb108d76 (patch) | |
tree | da3fcaff0784a222a4081f76a4d900e58a1ed3b6 /lib | |
parent | 6523cebf5dcde0b4cbca0f943ed7f0c29c4e10d0 (diff) | |
parent | 9de6190ec4cf48b8a79cd91f99723fb8cae882ee (diff) | |
download | nextcloud-server-decae5a45a93e0c16f748f38151575f8eb108d76.tar.gz nextcloud-server-decae5a45a93e0c16f748f38151575f8eb108d76.zip |
Merge pull request #46547 from nextcloud/query-builder-connection
feat: allow running QueryBuilder queries on different connections
Diffstat (limited to 'lib')
-rw-r--r-- | lib/private/DB/QueryBuilder/ExtendedQueryBuilder.php | 15 | ||||
-rw-r--r-- | lib/private/DB/QueryBuilder/QueryBuilder.php | 76 | ||||
-rw-r--r-- | lib/public/DB/QueryBuilder/IQueryBuilder.php | 10 |
3 files changed, 57 insertions, 44 deletions
diff --git a/lib/private/DB/QueryBuilder/ExtendedQueryBuilder.php b/lib/private/DB/QueryBuilder/ExtendedQueryBuilder.php index ab58773dfd3..bde6523567f 100644 --- a/lib/private/DB/QueryBuilder/ExtendedQueryBuilder.php +++ b/lib/private/DB/QueryBuilder/ExtendedQueryBuilder.php @@ -11,6 +11,7 @@ namespace OC\DB\QueryBuilder; use OC\DB\Exceptions\DbalException; use OCP\DB\IResult; use OCP\DB\QueryBuilder\IQueryBuilder; +use OCP\IDBConnection; /** * Base class for creating classes that extend the builtin query builder @@ -46,12 +47,12 @@ abstract class ExtendedQueryBuilder implements IQueryBuilder { return $this->builder->getState(); } - public function execute() { + public function execute(?IDBConnection $connection = null) { try { if ($this->getType() === \Doctrine\DBAL\Query\QueryBuilder::SELECT) { - return $this->executeQuery(); + return $this->executeQuery($connection); } else { - return $this->executeStatement(); + return $this->executeStatement($connection); } } catch (DBALException $e) { // `IQueryBuilder->execute` never wrapped the exception, but `executeQuery` and `executeStatement` do @@ -280,11 +281,11 @@ abstract class ExtendedQueryBuilder implements IQueryBuilder { return $this->builder->getColumnName($column, $tableAlias); } - public function executeQuery(): IResult { - return $this->builder->executeQuery(); + public function executeQuery(?IDBConnection $connection = null): IResult { + return $this->builder->executeQuery($connection); } - public function executeStatement(): int { - return $this->builder->executeStatement(); + public function executeStatement(?IDBConnection $connection = null): int { + return $this->builder->executeStatement($connection); } } diff --git a/lib/private/DB/QueryBuilder/QueryBuilder.php b/lib/private/DB/QueryBuilder/QueryBuilder.php index 0e7d8d2ff3e..82127078d06 100644 --- a/lib/private/DB/QueryBuilder/QueryBuilder.php +++ b/lib/private/DB/QueryBuilder/QueryBuilder.php @@ -13,6 +13,7 @@ use Doctrine\DBAL\Platforms\PostgreSQL94Platform; use Doctrine\DBAL\Platforms\SqlitePlatform; use Doctrine\DBAL\Query\QueryException; use OC\DB\ConnectionAdapter; +use OC\DB\Exceptions\DbalException; use OC\DB\QueryBuilder\ExpressionBuilder\ExpressionBuilder; use OC\DB\QueryBuilder\ExpressionBuilder\MySqlExpressionBuilder; use OC\DB\QueryBuilder\ExpressionBuilder\OCIExpressionBuilder; @@ -22,7 +23,6 @@ use OC\DB\QueryBuilder\FunctionBuilder\FunctionBuilder; use OC\DB\QueryBuilder\FunctionBuilder\OCIFunctionBuilder; use OC\DB\QueryBuilder\FunctionBuilder\PgSqlFunctionBuilder; use OC\DB\QueryBuilder\FunctionBuilder\SqliteFunctionBuilder; -use OC\DB\ResultAdapter; use OC\SystemConfig; use OCP\DB\IResult; use OCP\DB\QueryBuilder\ICompositeExpression; @@ -30,6 +30,7 @@ use OCP\DB\QueryBuilder\ILiteral; use OCP\DB\QueryBuilder\IParameter; use OCP\DB\QueryBuilder\IQueryBuilder; use OCP\DB\QueryBuilder\IQueryFunction; +use OCP\IDBConnection; use Psr\Log\LoggerInterface; class QueryBuilder implements IQueryBuilder { @@ -168,15 +169,7 @@ class QueryBuilder implements IQueryBuilder { return $this->queryBuilder->getState(); } - /** - * Executes this query using the bound parameters and their types. - * - * Uses {@see Connection::executeQuery} for select statements and {@see Connection::executeUpdate} - * for insert, update and delete statements. - * - * @return IResult|int - */ - public function execute() { + private function prepareForExecute() { if ($this->systemConfig->getValue('log_query', false)) { try { $params = []; @@ -253,48 +246,63 @@ class QueryBuilder implements IQueryBuilder { 'exception' => $exception, ]); } + } - $result = $this->queryBuilder->execute(); - if (is_int($result)) { - return $result; + /** + * Executes this query using the bound parameters and their types. + * + * Uses {@see Connection::executeQuery} for select statements and {@see Connection::executeUpdate} + * for insert, update and delete statements. + * + * @return IResult|int + */ + public function execute(?IDBConnection $connection = null) { + try { + if ($this->getType() === \Doctrine\DBAL\Query\QueryBuilder::SELECT) { + return $this->executeQuery($connection); + } else { + return $this->executeStatement($connection); + } + } catch (DBALException $e) { + // `IQueryBuilder->execute` never wrapped the exception, but `executeQuery` and `executeStatement` do + /** @var \Doctrine\DBAL\Exception $previous */ + $previous = $e->getPrevious(); + throw $previous; } - return new ResultAdapter($result); } - public function executeQuery(): IResult { + public function executeQuery(?IDBConnection $connection = null): IResult { if ($this->getType() !== \Doctrine\DBAL\Query\QueryBuilder::SELECT) { throw new \RuntimeException('Invalid query type, expected SELECT query'); } - try { - $result = $this->execute(); - } catch (\Doctrine\DBAL\Exception $e) { - throw \OC\DB\Exceptions\DbalException::wrap($e); + $this->prepareForExecute(); + if (!$connection) { + $connection = $this->connection; } - if ($result instanceof IResult) { - return $result; - } - - throw new \RuntimeException('Invalid return type for query'); + return $connection->executeQuery( + $this->getSQL(), + $this->getParameters(), + $this->getParameterTypes(), + ); } - public function executeStatement(): int { + public function executeStatement(?IDBConnection $connection = null): int { if ($this->getType() === \Doctrine\DBAL\Query\QueryBuilder::SELECT) { throw new \RuntimeException('Invalid query type, expected INSERT, DELETE or UPDATE statement'); } - try { - $result = $this->execute(); - } catch (\Doctrine\DBAL\Exception $e) { - throw \OC\DB\Exceptions\DbalException::wrap($e); - } - - if (!is_int($result)) { - throw new \RuntimeException('Invalid return type for statement'); + $this->prepareForExecute(); + if (!$connection) { + $connection = $this->connection; } - return $result; + return $connection->executeStatement( + $this->getSQL(), + $this->getParameters(), + $this->getParameterTypes(), + ); } diff --git a/lib/public/DB/QueryBuilder/IQueryBuilder.php b/lib/public/DB/QueryBuilder/IQueryBuilder.php index 94ab796adf4..c736d3094e5 100644 --- a/lib/public/DB/QueryBuilder/IQueryBuilder.php +++ b/lib/public/DB/QueryBuilder/IQueryBuilder.php @@ -12,6 +12,7 @@ use Doctrine\DBAL\Connection; use Doctrine\DBAL\ParameterType; use OCP\DB\Exception; use OCP\DB\IResult; +use OCP\IDBConnection; /** * This class provides a wrapper around Doctrine's QueryBuilder @@ -146,34 +147,37 @@ interface IQueryBuilder { * that interface changed in a breaking way the adapter \OCP\DB\QueryBuilder\IStatement is returned * to bridge old code to the new API * + * @param ?IDBConnection $connection (optional) the connection to run the query against. since 30.0 * @return IResult|int * @throws Exception since 21.0.0 * @since 8.2.0 * @deprecated 22.0.0 Use executeQuery or executeStatement */ - public function execute(); + public function execute(?IDBConnection $connection = null); /** * Execute for select statements * + * @param ?IDBConnection $connection (optional) the connection to run the query against. since 30.0 * @return IResult * @since 22.0.0 * * @throws Exception * @throws \RuntimeException in case of usage with non select query */ - public function executeQuery(): IResult; + public function executeQuery(?IDBConnection $connection = null): IResult; /** * Execute insert, update and delete statements * + * @param ?IDBConnection $connection (optional) the connection to run the query against. since 30.0 * @return int the number of affected rows * @since 22.0.0 * * @throws Exception * @throws \RuntimeException in case of usage with select query */ - public function executeStatement(): int; + public function executeStatement(?IDBConnection $connection = null): int; /** * Gets the complete SQL string formed by the current specifications of this QueryBuilder. |