From c78506cd76cb81c8e3cc7396fac91753af416e6f Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Thu, 4 Jul 2024 19:20:46 +0200 Subject: [PATCH] feat: add base class for extending the query builder Signed-off-by: Robin Appelman --- apps/files_trashbin/lib/Trashbin.php | 8 +- lib/composer/composer/autoload_classmap.php | 1 + lib/composer/composer/autoload_static.php | 1 + .../DB/QueryBuilder/ExtendedQueryBuilder.php | 290 ++++++++++++++++++ lib/private/Files/Cache/Cache.php | 4 +- lib/private/Files/Cache/CacheQueryBuilder.php | 13 +- lib/private/Files/Cache/FileAccess.php | 4 +- lib/private/Files/Cache/QuerySearchHelper.php | 4 +- 8 files changed, 303 insertions(+), 22 deletions(-) create mode 100644 lib/private/DB/QueryBuilder/ExtendedQueryBuilder.php diff --git a/apps/files_trashbin/lib/Trashbin.php b/apps/files_trashbin/lib/Trashbin.php index 831bf0686ced8..99fe35bca5fdd 100644 --- a/apps/files_trashbin/lib/Trashbin.php +++ b/apps/files_trashbin/lib/Trashbin.php @@ -31,8 +31,10 @@ use OCP\Files\NotPermittedException; use OCP\FilesMetadata\IFilesMetadataManager; use OCP\IConfig; +use OCP\IDBConnection; use OCP\Lock\ILockingProvider; use OCP\Lock\LockedException; +use OCP\Server; use Psr\Log\LoggerInterface; class Trashbin { @@ -983,10 +985,8 @@ private static function getVersionsFromTrash($filename, $timestamp, string $user // Manually fetch all versions from the file cache to be able to filter them by their parent $cache = $storage->getCache(''); $query = new CacheQueryBuilder( - \OC::$server->getDatabaseConnection(), - \OC::$server->getSystemConfig(), - \OC::$server->get(LoggerInterface::class), - \OC::$server->get(IFilesMetadataManager::class), + Server::get(IDBConnection::class)->getQueryBuilder(), + Server::get(IFilesMetadataManager::class), ); $normalizedParentPath = ltrim(Filesystem::normalizePath(dirname('files_trashbin/versions/'. $filename)), '/'); $parentId = $cache->getId($normalizedParentPath); diff --git a/lib/composer/composer/autoload_classmap.php b/lib/composer/composer/autoload_classmap.php index 6bee8c52568bc..4871764bd6364 100644 --- a/lib/composer/composer/autoload_classmap.php +++ b/lib/composer/composer/autoload_classmap.php @@ -1350,6 +1350,7 @@ 'OC\\DB\\QueryBuilder\\ExpressionBuilder\\OCIExpressionBuilder' => $baseDir . '/lib/private/DB/QueryBuilder/ExpressionBuilder/OCIExpressionBuilder.php', 'OC\\DB\\QueryBuilder\\ExpressionBuilder\\PgSqlExpressionBuilder' => $baseDir . '/lib/private/DB/QueryBuilder/ExpressionBuilder/PgSqlExpressionBuilder.php', 'OC\\DB\\QueryBuilder\\ExpressionBuilder\\SqliteExpressionBuilder' => $baseDir . '/lib/private/DB/QueryBuilder/ExpressionBuilder/SqliteExpressionBuilder.php', + 'OC\\DB\\QueryBuilder\\ExtendedQueryBuilder' => $baseDir . '/lib/private/DB/QueryBuilder/ExtendedQueryBuilder.php', 'OC\\DB\\QueryBuilder\\FunctionBuilder\\FunctionBuilder' => $baseDir . '/lib/private/DB/QueryBuilder/FunctionBuilder/FunctionBuilder.php', 'OC\\DB\\QueryBuilder\\FunctionBuilder\\OCIFunctionBuilder' => $baseDir . '/lib/private/DB/QueryBuilder/FunctionBuilder/OCIFunctionBuilder.php', 'OC\\DB\\QueryBuilder\\FunctionBuilder\\PgSqlFunctionBuilder' => $baseDir . '/lib/private/DB/QueryBuilder/FunctionBuilder/PgSqlFunctionBuilder.php', diff --git a/lib/composer/composer/autoload_static.php b/lib/composer/composer/autoload_static.php index 31191f982ff0f..6e663c344bb4a 100644 --- a/lib/composer/composer/autoload_static.php +++ b/lib/composer/composer/autoload_static.php @@ -1383,6 +1383,7 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2 'OC\\DB\\QueryBuilder\\ExpressionBuilder\\OCIExpressionBuilder' => __DIR__ . '/../../..' . '/lib/private/DB/QueryBuilder/ExpressionBuilder/OCIExpressionBuilder.php', 'OC\\DB\\QueryBuilder\\ExpressionBuilder\\PgSqlExpressionBuilder' => __DIR__ . '/../../..' . '/lib/private/DB/QueryBuilder/ExpressionBuilder/PgSqlExpressionBuilder.php', 'OC\\DB\\QueryBuilder\\ExpressionBuilder\\SqliteExpressionBuilder' => __DIR__ . '/../../..' . '/lib/private/DB/QueryBuilder/ExpressionBuilder/SqliteExpressionBuilder.php', + 'OC\\DB\\QueryBuilder\\ExtendedQueryBuilder' => __DIR__ . '/../../..' . '/lib/private/DB/QueryBuilder/ExtendedQueryBuilder.php', 'OC\\DB\\QueryBuilder\\FunctionBuilder\\FunctionBuilder' => __DIR__ . '/../../..' . '/lib/private/DB/QueryBuilder/FunctionBuilder/FunctionBuilder.php', 'OC\\DB\\QueryBuilder\\FunctionBuilder\\OCIFunctionBuilder' => __DIR__ . '/../../..' . '/lib/private/DB/QueryBuilder/FunctionBuilder/OCIFunctionBuilder.php', 'OC\\DB\\QueryBuilder\\FunctionBuilder\\PgSqlFunctionBuilder' => __DIR__ . '/../../..' . '/lib/private/DB/QueryBuilder/FunctionBuilder/PgSqlFunctionBuilder.php', diff --git a/lib/private/DB/QueryBuilder/ExtendedQueryBuilder.php b/lib/private/DB/QueryBuilder/ExtendedQueryBuilder.php new file mode 100644 index 0000000000000..d4dca66778c62 --- /dev/null +++ b/lib/private/DB/QueryBuilder/ExtendedQueryBuilder.php @@ -0,0 +1,290 @@ + + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +namespace OC\DB\QueryBuilder; + +use OC\DB\Exceptions\DbalException; +use OCP\DB\IResult; +use OCP\DB\QueryBuilder\IQueryBuilder; + +/** + * Base class for creating classes that extend the builtin query builder + */ +abstract class ExtendedQueryBuilder implements IQueryBuilder { + public function __construct( + protected IQueryBuilder $builder, + ) { + } + + public function automaticTablePrefix($enabled) { + $this->builder->automaticTablePrefix($enabled); + return $this; + } + + public function expr() { + return $this->builder->expr(); + } + + public function func() { + return $this->builder->func(); + } + + public function getType() { + return $this->builder->getType(); + } + + public function getConnection() { + return $this->builder->getConnection(); + } + + public function getState() { + return $this->builder->getState(); + } + + public function execute() { + try { + if ($this->getType() === \Doctrine\DBAL\Query\QueryBuilder::SELECT) { + return $this->executeQuery(); + } else { + return $this->executeStatement(); + } + } catch (DBALException $e) { + // `IQueryBuilder->execute` never wrapped the exception, but `executeQuery` and `executeStatement` do + /** @var \Doctrine\DBAL\Exception $previous */ + $previous = $e->getPrevious(); + throw $previous; + } + } + + public function getSQL() { + return $this->builder->getSQL(); + } + + public function setParameter($key, $value, $type = null) { + $this->builder->setParameter($key, $value, $type); + return $this; + } + + public function setParameters(array $params, array $types = []) { + $this->builder->setParameters($params, $types); + return $this; + } + + public function getParameters() { + return $this->builder->getParameters(); + } + + public function getParameter($key) { + return $this->builder->getParameter($key); + } + + public function getParameterTypes() { + return $this->builder->getParameterTypes(); + } + + public function getParameterType($key) { + return $this->builder->getParameterType($key); + } + + public function setFirstResult($firstResult) { + $this->builder->setFirstResult($firstResult); + return $this; + } + + public function getFirstResult() { + return $this->builder->getFirstResult(); + } + + public function setMaxResults($maxResults) { + $this->builder->setMaxResults($maxResults); + return $this; + } + + public function getMaxResults() { + return $this->builder->getMaxResults(); + } + + public function select(...$selects) { + $this->builder->select(...$selects); + return $this; + } + + public function selectAlias($select, $alias) { + $this->builder->selectAlias($select, $alias); + return $this; + } + + public function selectDistinct($select) { + $this->builder->selectDistinct($select); + return $this; + } + + public function addSelect(...$select) { + $this->builder->addSelect(...$select); + return $this; + } + + public function delete($delete = null, $alias = null) { + $this->builder->delete($delete, $alias); + return $this; + } + + public function update($update = null, $alias = null) { + $this->builder->update($update, $alias); + return $this; + } + + public function insert($insert = null) { + $this->builder->insert($insert); + return $this; + } + + public function from($from, $alias = null) { + $this->builder->from($from, $alias); + return $this; + } + + public function join($fromAlias, $join, $alias, $condition = null) { + $this->builder->join($fromAlias, $join, $alias, $condition); + return $this; + } + + public function innerJoin($fromAlias, $join, $alias, $condition = null) { + $this->builder->innerJoin($fromAlias, $join, $alias, $condition); + return $this; + } + + public function leftJoin($fromAlias, $join, $alias, $condition = null) { + $this->builder->leftJoin($fromAlias, $join, $alias, $condition); + return $this; + } + + public function rightJoin($fromAlias, $join, $alias, $condition = null) { + $this->builder->rightJoin($fromAlias, $join, $alias, $condition); + return $this; + } + + public function set($key, $value) { + $this->builder->set($key, $value); + return $this; + } + + public function where(...$predicates) { + $this->builder->where(...$predicates); + return $this; + } + + public function andWhere(...$where) { + $this->builder->andWhere(...$where); + return $this; + } + + public function orWhere(...$where) { + $this->builder->orWhere(...$where); + return $this; + } + + public function groupBy(...$groupBy) { + $this->builder->groupBy(...$groupBy); + return $this; + } + + public function addGroupBy(...$groupBy) { + $this->builder->addGroupBy(...$groupBy); + return $this; + } + + public function setValue($column, $value) { + $this->builder->setValue($column, $value); + return $this; + } + + public function values(array $values) { + $this->builder->values($values); + return $this; + } + + public function having(...$having) { + $this->builder->having(...$having); + return $this; + } + + public function andHaving(...$having) { + $this->builder->andHaving(...$having); + return $this; + } + + public function orHaving(...$having) { + $this->builder->orHaving(...$having); + return $this; + } + + public function orderBy($sort, $order = null) { + $this->builder->orderBy($sort, $order); + return $this; + } + + public function addOrderBy($sort, $order = null) { + $this->builder->addOrderBy($sort, $order); + return $this; + } + + public function getQueryPart($queryPartName) { + return $this->builder->getQueryPart($queryPartName); + } + + public function getQueryParts() { + return $this->builder->getQueryParts(); + } + + public function resetQueryParts($queryPartNames = null) { + $this->builder->resetQueryParts($queryPartNames); + return $this; + } + + public function resetQueryPart($queryPartName) { + $this->builder->resetQueryPart($queryPartName); + return $this; + } + + public function createNamedParameter($value, $type = self::PARAM_STR, $placeHolder = null) { + return $this->builder->createNamedParameter($value, $type, $placeHolder); + } + + public function createPositionalParameter($value, $type = self::PARAM_STR) { + return $this->builder->createPositionalParameter($value, $type); + } + + public function createParameter($name) { + return $this->builder->createParameter($name); + } + + public function createFunction($call) { + return $this->builder->createFunction($call); + } + + public function getLastInsertId(): int { + return $this->builder->getLastInsertId(); + } + + public function getTableName($table) { + return $this->builder->getTableName($table); + } + + public function getColumnName($column, $tableAlias = '') { + return $this->builder->getColumnName($column, $tableAlias); + } + + public function executeQuery(): IResult { + return $this->builder->executeQuery(); + } + + public function executeStatement(): int { + return $this->builder->executeStatement(); + } +} diff --git a/lib/private/Files/Cache/Cache.php b/lib/private/Files/Cache/Cache.php index 3c871fdf4dc23..c132ac1f03408 100644 --- a/lib/private/Files/Cache/Cache.php +++ b/lib/private/Files/Cache/Cache.php @@ -87,9 +87,7 @@ public function __construct( protected function getQueryBuilder() { return new CacheQueryBuilder( - $this->connection, - $this->systemConfig, - $this->logger, + $this->connection->getQueryBuilder(), $this->metadataManager, ); } diff --git a/lib/private/Files/Cache/CacheQueryBuilder.php b/lib/private/Files/Cache/CacheQueryBuilder.php index 9bf5f97045843..76eb2bfa5ca89 100644 --- a/lib/private/Files/Cache/CacheQueryBuilder.php +++ b/lib/private/Files/Cache/CacheQueryBuilder.php @@ -8,27 +8,22 @@ */ namespace OC\Files\Cache; -use OC\DB\QueryBuilder\QueryBuilder; -use OC\SystemConfig; +use OC\DB\QueryBuilder\ExtendedQueryBuilder; use OCP\DB\QueryBuilder\IQueryBuilder; use OCP\FilesMetadata\IFilesMetadataManager; use OCP\FilesMetadata\IMetadataQuery; -use OCP\IDBConnection; -use Psr\Log\LoggerInterface; /** * Query builder with commonly used helpers for filecache queries */ -class CacheQueryBuilder extends QueryBuilder { +class CacheQueryBuilder extends ExtendedQueryBuilder { private ?string $alias = null; public function __construct( - IDBConnection $connection, - SystemConfig $systemConfig, - LoggerInterface $logger, + IQueryBuilder $queryBuilder, private IFilesMetadataManager $filesMetadataManager, ) { - parent::__construct($connection, $systemConfig, $logger); + parent::__construct($queryBuilder); } public function selectTagUsage(): self { diff --git a/lib/private/Files/Cache/FileAccess.php b/lib/private/Files/Cache/FileAccess.php index 5818017bd6683..11a95b5d89771 100644 --- a/lib/private/Files/Cache/FileAccess.php +++ b/lib/private/Files/Cache/FileAccess.php @@ -31,9 +31,7 @@ public function __construct( private function getQuery(): CacheQueryBuilder { return new CacheQueryBuilder( - $this->connection, - $this->systemConfig, - $this->logger, + $this->connection->getQueryBuilder(), $this->metadataManager, ); } diff --git a/lib/private/Files/Cache/QuerySearchHelper.php b/lib/private/Files/Cache/QuerySearchHelper.php index c31d62e1a8611..5af43455ea385 100644 --- a/lib/private/Files/Cache/QuerySearchHelper.php +++ b/lib/private/Files/Cache/QuerySearchHelper.php @@ -39,9 +39,7 @@ public function __construct( protected function getQueryBuilder() { return new CacheQueryBuilder( - $this->connection, - $this->systemConfig, - $this->logger, + $this->connection->getQueryBuilder(), $this->filesMetadataManager, ); }