mirror of
https://github.com/nextcloud/server.git
synced 2026-03-01 21:10:36 -05:00
feat(DB): Add ITypedQueryBuilder
Signed-off-by: provokateurin <kate@provokateurin.de>
This commit is contained in:
parent
b41569d80c
commit
161c91e1fd
18 changed files with 216 additions and 13 deletions
|
|
@ -3404,6 +3404,12 @@
|
|||
<code><![CDATA[$string]]></code>
|
||||
</NullableReturnStatement>
|
||||
</file>
|
||||
<file src="lib/private/DB/QueryBuilder/TypedQueryBuilder.php">
|
||||
<InternalMethod>
|
||||
<code><![CDATA[select]]></code>
|
||||
<code><![CDATA[selectDistinct]]></code>
|
||||
</InternalMethod>
|
||||
</file>
|
||||
<file src="lib/private/DateTimeFormatter.php">
|
||||
<FalsableReturnStatement>
|
||||
<code><![CDATA[$l->l($type, $timestamp, [
|
||||
|
|
|
|||
37
build/psalm/ITypedQueryBuilderTest.php
Normal file
37
build/psalm/ITypedQueryBuilderTest.php
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use OCP\IDBConnection;
|
||||
use OCP\Server;
|
||||
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
$qb = Server::get(IDBConnection::class)->getTypedQueryBuilder();
|
||||
|
||||
$qb->selectColumns('a', 'b');
|
||||
$qb->selectColumns('c');
|
||||
|
||||
$qb->selectColumnsDistinct('d', 'e');
|
||||
$qb->selectColumnsDistinct('f');
|
||||
|
||||
$qb->selectAlias('g', 'h');
|
||||
$qb->selectAlias($qb->func()->lower('i'), 'j');
|
||||
|
||||
/** @psalm-check-type-exact $result = \OCP\DB\IResult<'a'|'b'|'c'|'d'|'e'|'f'|'h'|'j'> */
|
||||
$result = $qb->executeQuery();
|
||||
|
||||
/** @psalm-check-type-exact $rows = array<'a'|'b'|'c'|'d'|'e'|'f'|'h'|'j', mixed>|false */
|
||||
$rows = $result->fetch(\PDO::FETCH_ASSOC);
|
||||
|
||||
/** @psalm-check-type-exact $rows = array<'a'|'b'|'c'|'d'|'e'|'f'|'h'|'j', mixed>|false */
|
||||
$rows = $result->fetchAssociative();
|
||||
|
||||
/** @psalm-check-type-exact $rows = list<array<'a'|'b'|'c'|'d'|'e'|'f'|'h'|'j', mixed>> */
|
||||
$rows = $result->fetchAll(\PDO::FETCH_ASSOC);
|
||||
|
||||
/** @psalm-check-type-exact $rows = list<array<'a'|'b'|'c'|'d'|'e'|'f'|'h'|'j', mixed>> */
|
||||
$rows = $result->fetchAllAssociative();
|
||||
|
|
@ -19,6 +19,9 @@ return (require __DIR__ . '/rector-shared.php')
|
|||
$nextcloudDir . '/apps/settings/lib/Service/AuthorizedGroupService.php',
|
||||
$nextcloudDir . '/lib/private/Files/Storage/Storage.php',
|
||||
$nextcloudDir . '/lib/private/Files/Storage/Wrapper/Wrapper.php',
|
||||
$nextcloudDir . '/build/psalm/ITypedQueryBuilderTest.php',
|
||||
$nextcloudDir . '/lib/private/DB/QueryBuilder/TypedQueryBuilder.php',
|
||||
$nextcloudDir . '/lib/public/DB/QueryBuilder/ITypedQueryBuilder.php',
|
||||
])
|
||||
->withPreparedSets(
|
||||
deadCode: true,
|
||||
|
|
|
|||
|
|
@ -327,6 +327,7 @@ return array(
|
|||
'OCP\\DB\\QueryBuilder\\IParameter' => $baseDir . '/lib/public/DB/QueryBuilder/IParameter.php',
|
||||
'OCP\\DB\\QueryBuilder\\IQueryBuilder' => $baseDir . '/lib/public/DB/QueryBuilder/IQueryBuilder.php',
|
||||
'OCP\\DB\\QueryBuilder\\IQueryFunction' => $baseDir . '/lib/public/DB/QueryBuilder/IQueryFunction.php',
|
||||
'OCP\\DB\\QueryBuilder\\ITypedQueryBuilder' => $baseDir . '/lib/public/DB/QueryBuilder/ITypedQueryBuilder.php',
|
||||
'OCP\\DB\\QueryBuilder\\Sharded\\IShardMapper' => $baseDir . '/lib/public/DB/QueryBuilder/Sharded/IShardMapper.php',
|
||||
'OCP\\DB\\Types' => $baseDir . '/lib/public/DB/Types.php',
|
||||
'OCP\\Dashboard\\IAPIWidget' => $baseDir . '/lib/public/Dashboard/IAPIWidget.php',
|
||||
|
|
@ -1657,6 +1658,7 @@ return array(
|
|||
'OC\\DB\\QueryBuilder\\Sharded\\ShardDefinition' => $baseDir . '/lib/private/DB/QueryBuilder/Sharded/ShardDefinition.php',
|
||||
'OC\\DB\\QueryBuilder\\Sharded\\ShardQueryRunner' => $baseDir . '/lib/private/DB/QueryBuilder/Sharded/ShardQueryRunner.php',
|
||||
'OC\\DB\\QueryBuilder\\Sharded\\ShardedQueryBuilder' => $baseDir . '/lib/private/DB/QueryBuilder/Sharded/ShardedQueryBuilder.php',
|
||||
'OC\\DB\\QueryBuilder\\TypedQueryBuilder' => $baseDir . '/lib/private/DB/QueryBuilder/TypedQueryBuilder.php',
|
||||
'OC\\DB\\ResultAdapter' => $baseDir . '/lib/private/DB/ResultAdapter.php',
|
||||
'OC\\DB\\SQLiteMigrator' => $baseDir . '/lib/private/DB/SQLiteMigrator.php',
|
||||
'OC\\DB\\SQLiteSessionInit' => $baseDir . '/lib/private/DB/SQLiteSessionInit.php',
|
||||
|
|
|
|||
|
|
@ -368,6 +368,7 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2
|
|||
'OCP\\DB\\QueryBuilder\\IParameter' => __DIR__ . '/../../..' . '/lib/public/DB/QueryBuilder/IParameter.php',
|
||||
'OCP\\DB\\QueryBuilder\\IQueryBuilder' => __DIR__ . '/../../..' . '/lib/public/DB/QueryBuilder/IQueryBuilder.php',
|
||||
'OCP\\DB\\QueryBuilder\\IQueryFunction' => __DIR__ . '/../../..' . '/lib/public/DB/QueryBuilder/IQueryFunction.php',
|
||||
'OCP\\DB\\QueryBuilder\\ITypedQueryBuilder' => __DIR__ . '/../../..' . '/lib/public/DB/QueryBuilder/ITypedQueryBuilder.php',
|
||||
'OCP\\DB\\QueryBuilder\\Sharded\\IShardMapper' => __DIR__ . '/../../..' . '/lib/public/DB/QueryBuilder/Sharded/IShardMapper.php',
|
||||
'OCP\\DB\\Types' => __DIR__ . '/../../..' . '/lib/public/DB/Types.php',
|
||||
'OCP\\Dashboard\\IAPIWidget' => __DIR__ . '/../../..' . '/lib/public/Dashboard/IAPIWidget.php',
|
||||
|
|
@ -1698,6 +1699,7 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2
|
|||
'OC\\DB\\QueryBuilder\\Sharded\\ShardDefinition' => __DIR__ . '/../../..' . '/lib/private/DB/QueryBuilder/Sharded/ShardDefinition.php',
|
||||
'OC\\DB\\QueryBuilder\\Sharded\\ShardQueryRunner' => __DIR__ . '/../../..' . '/lib/private/DB/QueryBuilder/Sharded/ShardQueryRunner.php',
|
||||
'OC\\DB\\QueryBuilder\\Sharded\\ShardedQueryBuilder' => __DIR__ . '/../../..' . '/lib/private/DB/QueryBuilder/Sharded/ShardedQueryBuilder.php',
|
||||
'OC\\DB\\QueryBuilder\\TypedQueryBuilder' => __DIR__ . '/../../..' . '/lib/private/DB/QueryBuilder/TypedQueryBuilder.php',
|
||||
'OC\\DB\\ResultAdapter' => __DIR__ . '/../../..' . '/lib/private/DB/ResultAdapter.php',
|
||||
'OC\\DB\\SQLiteMigrator' => __DIR__ . '/../../..' . '/lib/private/DB/SQLiteMigrator.php',
|
||||
'OC\\DB\\SQLiteSessionInit' => __DIR__ . '/../../..' . '/lib/private/DB/SQLiteSessionInit.php',
|
||||
|
|
|
|||
|
|
@ -14,6 +14,8 @@ use PDO;
|
|||
|
||||
/**
|
||||
* Wrap an array or rows into a result interface
|
||||
*
|
||||
* @template-implements IResult<string>
|
||||
*/
|
||||
class ArrayResult implements IResult {
|
||||
protected int $count;
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ use OC\DB\QueryBuilder\Sharded\ShardConnectionManager;
|
|||
use OC\DB\QueryBuilder\Sharded\ShardDefinition;
|
||||
use OC\SystemConfig;
|
||||
use OCP\DB\QueryBuilder\IQueryBuilder;
|
||||
use OCP\DB\QueryBuilder\ITypedQueryBuilder;
|
||||
use OCP\DB\QueryBuilder\Sharded\IShardMapper;
|
||||
use OCP\Diagnostics\IEventLogger;
|
||||
use OCP\EventDispatcher\IEventDispatcher;
|
||||
|
|
@ -247,6 +248,14 @@ class Connection extends PrimaryReadReplicaConnection {
|
|||
* Returns a QueryBuilder for the connection.
|
||||
*/
|
||||
public function getQueryBuilder(): IQueryBuilder {
|
||||
return $this->getInnerQueryBuilder();
|
||||
}
|
||||
|
||||
public function getTypedQueryBuilder(): ITypedQueryBuilder {
|
||||
return $this->getInnerQueryBuilder();
|
||||
}
|
||||
|
||||
private function getInnerQueryBuilder(): IQueryBuilder&ITypedQueryBuilder {
|
||||
$this->queriesBuilt++;
|
||||
|
||||
$builder = new QueryBuilder(
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ use OC\DB\QueryBuilder\Sharded\ShardDefinition;
|
|||
use OCP\DB\IPreparedStatement;
|
||||
use OCP\DB\IResult;
|
||||
use OCP\DB\QueryBuilder\IQueryBuilder;
|
||||
use OCP\DB\QueryBuilder\ITypedQueryBuilder;
|
||||
use OCP\IDBConnection;
|
||||
|
||||
/**
|
||||
|
|
@ -32,6 +33,10 @@ class ConnectionAdapter implements IDBConnection {
|
|||
return $this->inner->getQueryBuilder();
|
||||
}
|
||||
|
||||
public function getTypedQueryBuilder(): ITypedQueryBuilder {
|
||||
return $this->inner->getTypedQueryBuilder();
|
||||
}
|
||||
|
||||
public function prepare($sql, $limit = null, $offset = null): IPreparedStatement {
|
||||
try {
|
||||
return new PreparedStatement(
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ use OCP\IDBConnection;
|
|||
/**
|
||||
* Base class for creating classes that extend the builtin query builder
|
||||
*/
|
||||
abstract class ExtendedQueryBuilder implements IQueryBuilder {
|
||||
abstract class ExtendedQueryBuilder extends TypedQueryBuilder {
|
||||
public function __construct(
|
||||
protected IQueryBuilder $builder,
|
||||
) {
|
||||
|
|
@ -100,7 +100,7 @@ abstract class ExtendedQueryBuilder implements IQueryBuilder {
|
|||
return $this;
|
||||
}
|
||||
|
||||
public function selectAlias($select, $alias) {
|
||||
public function selectAlias($select, $alias): self {
|
||||
$this->builder->selectAlias($select, $alias);
|
||||
return $this;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -92,7 +92,7 @@ class PartitionedQueryBuilder extends ShardedQueryBuilder {
|
|||
return $this;
|
||||
}
|
||||
|
||||
public function selectAlias($select, $alias) {
|
||||
public function selectAlias($select, $alias): self {
|
||||
$this->selects[] = ['select' => $select, 'alias' => $alias];
|
||||
return $this;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,8 +30,9 @@ use OCP\DB\QueryBuilder\IQueryFunction;
|
|||
use OCP\IDBConnection;
|
||||
use Override;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use RuntimeException;
|
||||
|
||||
class QueryBuilder implements IQueryBuilder {
|
||||
class QueryBuilder extends TypedQueryBuilder {
|
||||
private \Doctrine\DBAL\Query\QueryBuilder $queryBuilder;
|
||||
private QuoteHelper $helper;
|
||||
private bool $automaticTablePrefix = true;
|
||||
|
|
@ -242,7 +243,7 @@ class QueryBuilder implements IQueryBuilder {
|
|||
|
||||
public function executeQuery(?IDBConnection $connection = null): IResult {
|
||||
if ($this->getType() !== \Doctrine\DBAL\Query\QueryBuilder::SELECT) {
|
||||
throw new \RuntimeException('Invalid query type, expected SELECT query');
|
||||
throw new RuntimeException('Invalid query type, expected SELECT query');
|
||||
}
|
||||
|
||||
$this->prepareForExecute();
|
||||
|
|
@ -259,7 +260,7 @@ class QueryBuilder implements IQueryBuilder {
|
|||
|
||||
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');
|
||||
throw new RuntimeException('Invalid query type, expected INSERT, DELETE or UPDATE statement');
|
||||
}
|
||||
|
||||
$this->prepareForExecute();
|
||||
|
|
@ -476,7 +477,7 @@ class QueryBuilder implements IQueryBuilder {
|
|||
*
|
||||
* @return $this This QueryBuilder instance.
|
||||
*/
|
||||
public function selectAlias($select, $alias) {
|
||||
public function selectAlias($select, $alias): self {
|
||||
$this->queryBuilder->addSelect(
|
||||
$this->helper->quoteColumnName($select) . ' AS ' . $this->helper->quoteColumnName($alias)
|
||||
);
|
||||
|
|
|
|||
40
lib/private/DB/QueryBuilder/TypedQueryBuilder.php
Normal file
40
lib/private/DB/QueryBuilder/TypedQueryBuilder.php
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
namespace OC\DB\QueryBuilder;
|
||||
|
||||
use OCP\DB\QueryBuilder\ITypedQueryBuilder;
|
||||
use RuntimeException;
|
||||
|
||||
/**
|
||||
* @psalm-suppress InvalidTemplateParam
|
||||
* @template-implements ITypedQueryBuilder<string>
|
||||
*/
|
||||
abstract class TypedQueryBuilder implements ITypedQueryBuilder {
|
||||
private function validateColumn(string $column): void {
|
||||
if (str_contains($column, '.') || trim($column) === '*') {
|
||||
throw new RuntimeException('Only column names are allowed, got: ' . $column);
|
||||
}
|
||||
}
|
||||
|
||||
public function selectColumns(string ...$columns): static {
|
||||
foreach ($columns as $column) {
|
||||
$this->validateColumn($column);
|
||||
}
|
||||
|
||||
return $this->select(...$columns);
|
||||
}
|
||||
|
||||
public function selectColumnsDistinct(string ...$columns): static {
|
||||
foreach ($columns as $column) {
|
||||
$this->validateColumn($column);
|
||||
}
|
||||
|
||||
return $this->selectDistinct($columns);
|
||||
}
|
||||
}
|
||||
|
|
@ -15,6 +15,8 @@ use PDO;
|
|||
|
||||
/**
|
||||
* Adapts DBAL 2.6 API for DBAL 3.x for backwards compatibility of a leaked type
|
||||
*
|
||||
* @template-implements IResult<string>
|
||||
*/
|
||||
class ResultAdapter implements IResult {
|
||||
public function __construct(
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ use Traversable;
|
|||
* }
|
||||
* ```
|
||||
*
|
||||
* @template-covariant S of string
|
||||
* @since 21.0.0
|
||||
*/
|
||||
#[Consumable(since: '21.0.0')]
|
||||
|
|
@ -41,7 +42,7 @@ interface IResult {
|
|||
/**
|
||||
* @param PDO::FETCH_* $fetchMode
|
||||
*
|
||||
* @return ($fetchMode is PDO::FETCH_ASSOC ? array<string, mixed> : ($fetchMode is PDO::FETCH_NUM ? list<mixed> : mixed))|false
|
||||
* @return ($fetchMode is PDO::FETCH_ASSOC ? array<S, mixed> : ($fetchMode is PDO::FETCH_NUM ? list<mixed> : mixed))|false
|
||||
*
|
||||
* @since 21.0.0
|
||||
* @note Since 33.0.0, prefer using fetchAssociative/fetchNumeric/fetchOne or iterateAssociate/iterateNumeric instead.
|
||||
|
|
@ -51,7 +52,7 @@ interface IResult {
|
|||
/**
|
||||
* Returns the next row of the result as an associative array or FALSE if there are no more rows.
|
||||
*
|
||||
* @return array<string, mixed>|false
|
||||
* @return array<S, mixed>|false
|
||||
*
|
||||
* @since 33.0.0
|
||||
*/
|
||||
|
|
@ -78,7 +79,7 @@ interface IResult {
|
|||
/**
|
||||
* @param PDO::FETCH_* $fetchMode
|
||||
*
|
||||
* @return list<($fetchMode is PDO::FETCH_ASSOC ? array<string, mixed> : ($fetchMode is PDO::FETCH_NUM ? list<mixed> : mixed))>
|
||||
* @return list<($fetchMode is PDO::FETCH_ASSOC ? array<S, mixed> : ($fetchMode is PDO::FETCH_NUM ? list<mixed> : mixed))>
|
||||
*
|
||||
* @since 21.0.0
|
||||
* @note Since 33.0.0, prefer using fetchAllAssociative/fetchAllNumeric/fetchFirstColumn or iterateAssociate/iterateNumeric instead.
|
||||
|
|
@ -88,7 +89,7 @@ interface IResult {
|
|||
/**
|
||||
* Returns an array containing all the result rows represented as associative arrays.
|
||||
*
|
||||
* @return list<array<string,mixed>>
|
||||
* @return list<array<S, mixed>>
|
||||
* @since 33.0.0
|
||||
*/
|
||||
public function fetchAllAssociative(): array;
|
||||
|
|
@ -136,7 +137,7 @@ interface IResult {
|
|||
/**
|
||||
* Returns an iterator over rows represented as associative arrays.
|
||||
*
|
||||
* @return Traversable<array<string,mixed>>
|
||||
* @return Traversable<array<S, mixed>>
|
||||
*
|
||||
* @since 33.0.0
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -386,7 +386,7 @@ interface IQueryBuilder {
|
|||
* @psalm-taint-sink sql $select
|
||||
* @psalm-taint-sink sql $alias
|
||||
*/
|
||||
public function selectAlias($select, $alias);
|
||||
public function selectAlias($select, $alias): self;
|
||||
|
||||
/**
|
||||
* Specifies an item that is to be returned uniquely in the query result.
|
||||
|
|
|
|||
76
lib/public/DB/QueryBuilder/ITypedQueryBuilder.php
Normal file
76
lib/public/DB/QueryBuilder/ITypedQueryBuilder.php
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
namespace OCP\DB\QueryBuilder;
|
||||
|
||||
use OCP\AppFramework\Attribute\Consumable;
|
||||
use OCP\DB\IResult;
|
||||
use OCP\IDBConnection;
|
||||
use Override;
|
||||
|
||||
/**
|
||||
* @template-covariant S of never
|
||||
* @since 34.0.0
|
||||
*/
|
||||
#[Consumable(since: '34.0.0')]
|
||||
interface ITypedQueryBuilder extends IQueryBuilder {
|
||||
/**
|
||||
* @inheritDoc
|
||||
* @return IResult<S>
|
||||
*/
|
||||
#[Override]
|
||||
public function executeQuery(?IDBConnection $connection = null): IResult;
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
* @internal This method does not work with {@see self}. Use {@see self::selectColumns()} or {@see self::selectAlias()} instead.
|
||||
*/
|
||||
#[Override]
|
||||
public function select(...$selects);
|
||||
|
||||
/**
|
||||
* @template NewS of string
|
||||
* @param NewS ...$columns The columns to select. They are not allowed to contain table names or aliases, or asterisks. Use {@see self::selectAlias()} for that.
|
||||
* @psalm-this-out self<S|NewS>
|
||||
* @since 34.0.0
|
||||
*/
|
||||
public function selectColumns(string ...$columns): self;
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
* @internal This method does not work with {@see self}. Use {@see self::selectColumnDistinct()} or {@see self::selectAlias()} instead.
|
||||
*/
|
||||
#[Override]
|
||||
public function selectDistinct($select);
|
||||
|
||||
/**
|
||||
* @template NewS of string
|
||||
* @param NewS ...$columns The columns to select distinct. They are not allowed to contain table names or aliases, or asterisks. Use {@see self::selectAlias()} for that.
|
||||
* @psalm-this-out self<S|NewS>
|
||||
* @since 34.0.0
|
||||
*/
|
||||
public function selectColumnsDistinct(string ...$columns): self;
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
* @internal This method does not work with {@see self}. Use {@see self::selectColumns()} or {@see self::selectAlias()} instead.
|
||||
*/
|
||||
#[Override]
|
||||
public function addSelect(...$select);
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
* @param mixed $select
|
||||
* @template NewS of string
|
||||
* @param NewS $alias
|
||||
* @psalm-this-out self<S|NewS>
|
||||
* @psalm-suppress LessSpecificImplementedReturnType
|
||||
*/
|
||||
#[Override]
|
||||
public function selectAlias($select, $alias): self;
|
||||
}
|
||||
|
|
@ -17,6 +17,7 @@ use OCP\DB\Exception;
|
|||
use OCP\DB\IPreparedStatement;
|
||||
use OCP\DB\IResult;
|
||||
use OCP\DB\QueryBuilder\IQueryBuilder;
|
||||
use OCP\DB\QueryBuilder\ITypedQueryBuilder;
|
||||
|
||||
/**
|
||||
* Interface IDBConnection
|
||||
|
|
@ -54,9 +55,17 @@ interface IDBConnection {
|
|||
*
|
||||
* @return \OCP\DB\QueryBuilder\IQueryBuilder
|
||||
* @since 8.2.0
|
||||
* @note Since 34.0.0 prefer using {@see self::getTypedQueryBuilder()} instead.
|
||||
*/
|
||||
public function getQueryBuilder();
|
||||
|
||||
/**
|
||||
* Gets the ITypedQueryBuilder for the connection.
|
||||
*
|
||||
* @since 34.0.0
|
||||
*/
|
||||
public function getTypedQueryBuilder(): ITypedQueryBuilder;
|
||||
|
||||
/**
|
||||
* Used to abstract the Nextcloud database access away
|
||||
* @param string $sql the sql query with ? placeholder for params
|
||||
|
|
|
|||
|
|
@ -25,6 +25,9 @@
|
|||
<file name="apps/settings/lib/Service/AuthorizedGroupService.php"/>
|
||||
<file name="lib/private/Files/Storage/Storage.php"/>
|
||||
<file name="lib/private/Files/Storage/Wrapper/Wrapper.php"/>
|
||||
<file name="build/psalm/ITypedQueryBuilderTest.php"/>
|
||||
<file name="lib/private/DB/QueryBuilder/TypedQueryBuilder.php"/>
|
||||
<file name="lib/public/DB/QueryBuilder/ITypedQueryBuilder.php"/>
|
||||
<ignoreFiles>
|
||||
<directory name="apps/**/composer"/>
|
||||
<directory name="apps/**/tests"/>
|
||||
|
|
@ -58,5 +61,10 @@
|
|||
<directory name="."/>
|
||||
</errorLevel>
|
||||
</InternalProperty>
|
||||
<UnusedVariable>
|
||||
<errorLevel type="suppress">
|
||||
<file name="build/psalm/ITypedQueryBuilderTest.php"/>
|
||||
</errorLevel>
|
||||
</UnusedVariable>
|
||||
</issueHandlers>
|
||||
</psalm>
|
||||
|
|
|
|||
Loading…
Reference in a new issue