diff options
author | Robin Appelman <robin@icewind.nl> | 2024-07-04 17:18:22 +0200 |
---|---|---|
committer | Robin Appelman <robin@icewind.nl> | 2024-07-15 22:41:04 +0200 |
commit | 9de6190ec4cf48b8a79cd91f99723fb8cae882ee (patch) | |
tree | 92d41ea07d261df8901b9c14d91159336c2e608b /lib/private/DB | |
parent | f94b0c3f55f1a3f2b24a6f554cf5a67a4deae959 (diff) | |
download | nextcloud-server-9de6190ec4cf48b8a79cd91f99723fb8cae882ee.tar.gz nextcloud-server-9de6190ec4cf48b8a79cd91f99723fb8cae882ee.zip |
feat: allow running QueryBuilder queries on different connections
Signed-off-by: Robin Appelman <robin@icewind.nl>
Diffstat (limited to 'lib/private/DB')
-rw-r--r-- | lib/private/DB/QueryBuilder/ExtendedQueryBuilder.php | 15 | ||||
-rw-r--r-- | lib/private/DB/QueryBuilder/QueryBuilder.php | 76 |
2 files changed, 50 insertions, 41 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(), + ); } |