Signed-off-by: provokateurin <kate@provokateurin.de>pull/58373/head
parent
b41569d80c
commit
161c91e1fd
@ -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(); |
||||
@ -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); |
||||
} |
||||
} |
||||
@ -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; |
||||
} |
||||
Loading…
Reference in new issue