Skip to content

Commit

Permalink
feat: add base class for extending the query builder
Browse files Browse the repository at this point in the history
Signed-off-by: Robin Appelman <robin@icewind.nl>
  • Loading branch information
icewind1991 committed Jul 10, 2024
1 parent e31f474 commit 7a8a496
Show file tree
Hide file tree
Showing 8 changed files with 298 additions and 21 deletions.
4 changes: 1 addition & 3 deletions apps/files_trashbin/lib/Trashbin.php
Original file line number Diff line number Diff line change
Expand Up @@ -983,9 +983,7 @@ 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->getDatabaseConnection()->getQueryBuilder(),

Check notice

Code scanning / Psalm

DeprecatedMethod Note

The method OC\Server::getDatabaseConnection has been marked as deprecated
\OC::$server->get(IFilesMetadataManager::class),
);
$normalizedParentPath = ltrim(Filesystem::normalizePath(dirname('files_trashbin/versions/'. $filename)), '/');
Expand Down
1 change: 1 addition & 0 deletions lib/composer/composer/autoload_classmap.php
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand Down
1 change: 1 addition & 0 deletions lib/composer/composer/autoload_static.php
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand Down
288 changes: 288 additions & 0 deletions lib/private/DB/QueryBuilder/ExtendedQueryBuilder.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,288 @@
<?php

declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2024 Robin Appelman <robin@icewind.nl>
* 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
throw $e->getPrevious();

Check failure

Code scanning / Psalm

InvalidThrow Error

Cannot throw null as it does not extend Exception or implement Throwable

Check failure on line 58 in lib/private/DB/QueryBuilder/ExtendedQueryBuilder.php

View workflow job for this annotation

GitHub Actions / static-code-analysis

InvalidThrow

lib/private/DB/QueryBuilder/ExtendedQueryBuilder.php:58:4: InvalidThrow: Cannot throw null as it does not extend Exception or implement Throwable (see https://psalm.dev/133)
}
}

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(...$groupBys) {
$this->builder->groupBy(...$groupBys);
return $this;
}

public function addGroupBy(...$groupBys) {

Check failure

Code scanning / Psalm

ParamNameMismatch Error

Argument 1 of OC\DB\QueryBuilder\ExtendedQueryBuilder::addGroupBy has wrong name $groupBys, expecting $groupBy as defined by OCP\DB\QueryBuilder\IQueryBuilder::addGroupBy

Check failure on line 195 in lib/private/DB/QueryBuilder/ExtendedQueryBuilder.php

View workflow job for this annotation

GitHub Actions / static-code-analysis

ParamNameMismatch

lib/private/DB/QueryBuilder/ExtendedQueryBuilder.php:195:32: ParamNameMismatch: Argument 1 of OC\DB\QueryBuilder\ExtendedQueryBuilder::addGroupBy has wrong name $groupBys, expecting $groupBy as defined by OCP\DB\QueryBuilder\IQueryBuilder::addGroupBy (see https://psalm.dev/230)
$this->builder->addGroupBy(...$groupBys);
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();
}
}
4 changes: 1 addition & 3 deletions lib/private/Files/Cache/Cache.php
Original file line number Diff line number Diff line change
Expand Up @@ -87,9 +87,7 @@ public function __construct(

protected function getQueryBuilder() {
return new CacheQueryBuilder(
$this->connection,
$this->systemConfig,
$this->logger,
$this->connection->getQueryBuilder(),
$this->metadataManager,
);
}
Expand Down
13 changes: 4 additions & 9 deletions lib/private/Files/Cache/CacheQueryBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
4 changes: 1 addition & 3 deletions lib/private/Files/Cache/FileAccess.php
Original file line number Diff line number Diff line change
Expand Up @@ -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,
);
}
Expand Down
4 changes: 1 addition & 3 deletions lib/private/Files/Cache/QuerySearchHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,7 @@ public function __construct(

protected function getQueryBuilder() {
return new CacheQueryBuilder(
$this->connection,
$this->systemConfig,
$this->logger,
$this->connection->getQueryBuilder(),
$this->filesMetadataManager,
);
}
Expand Down

0 comments on commit 7a8a496

Please sign in to comment.