mirror of
https://github.com/nextcloud/server.git
synced 2026-04-21 06:08:46 -04:00
feat(result): Update result wrapper with new doctrine methods
- fetch is replaced with fetchAssociative/fetchNumeric/fetchOne with
better type hinting
- Same with fetchAll
- And add iterateAssociative/iterateNumeric which are nicer to use than
a `while ($row = $result->fetch()) {}`
Signed-off-by: Carl Schwan <carl.schwan@nextcloud.com>
This commit is contained in:
parent
d843e03a34
commit
3682dbbf5e
3 changed files with 193 additions and 25 deletions
|
|
@ -9,6 +9,7 @@ declare(strict_types=1);
|
|||
namespace OC\DB;
|
||||
|
||||
use OCP\DB\IResult;
|
||||
use Override;
|
||||
use PDO;
|
||||
|
||||
/**
|
||||
|
|
@ -18,16 +19,19 @@ class ArrayResult implements IResult {
|
|||
protected int $count;
|
||||
|
||||
public function __construct(
|
||||
/** @var array<string, mixed> $rows */
|
||||
protected array $rows,
|
||||
) {
|
||||
$this->count = count($this->rows);
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function closeCursor(): bool {
|
||||
// noop
|
||||
return true;
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function fetch(int $fetchMode = PDO::FETCH_ASSOC) {
|
||||
$row = array_shift($this->rows);
|
||||
if (!$row) {
|
||||
|
|
@ -42,23 +46,22 @@ class ArrayResult implements IResult {
|
|||
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function fetchAll(int $fetchMode = PDO::FETCH_ASSOC): array {
|
||||
return match ($fetchMode) {
|
||||
PDO::FETCH_ASSOC => $this->rows,
|
||||
PDO::FETCH_NUM => array_map(function ($row) {
|
||||
return array_values($row);
|
||||
}, $this->rows),
|
||||
PDO::FETCH_COLUMN => array_map(function ($row) {
|
||||
return current($row);
|
||||
}, $this->rows),
|
||||
PDO::FETCH_NUM => array_map(static fn (array $row): array => array_values($row), $this->rows),
|
||||
PDO::FETCH_COLUMN => array_map(static fn (array $row): mixed => current($row), $this->rows),
|
||||
default => throw new \InvalidArgumentException('Fetch mode not supported for array result'),
|
||||
};
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function fetchColumn() {
|
||||
return $this->fetchOne();
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function fetchOne() {
|
||||
$row = $this->fetch();
|
||||
if ($row) {
|
||||
|
|
@ -68,7 +71,65 @@ class ArrayResult implements IResult {
|
|||
}
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function fetchAssociative(): array|false {
|
||||
$row = $this->fetch();
|
||||
if ($row) {
|
||||
/** @var array<string, mixed> $row */
|
||||
return $row;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function fetchNumeric(): array|false {
|
||||
$row = $this->fetch(PDO::FETCH_NUM);
|
||||
if ($row) {
|
||||
/** @var list<mixed> $row */
|
||||
return $row;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function fetchAllNumeric(): array {
|
||||
/** @var list<list<mixed>> $result */
|
||||
$result = $this->fetchAll(PDO::FETCH_NUM);
|
||||
return $result;
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function fetchAllAssociative(): array {
|
||||
/** @var list<array<string,mixed>> $result */
|
||||
$result = $this->fetchAll();
|
||||
return $result;
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function fetchFirstColumn(): array {
|
||||
/** @var list<mixed> $result */
|
||||
$result = $this->fetchAll(PDO::FETCH_COLUMN);
|
||||
return $result;
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function rowCount(): int {
|
||||
return $this->count;
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function iterateNumeric(): \Traversable {
|
||||
while (($row = $this->fetchNumeric()) !== false) {
|
||||
yield $row;
|
||||
}
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function iterateAssociative(): \Traversable {
|
||||
while (($row = $this->fetchAssociative()) !== false) {
|
||||
yield $row;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,25 +10,26 @@ namespace OC\DB;
|
|||
|
||||
use Doctrine\DBAL\Result;
|
||||
use OCP\DB\IResult;
|
||||
use Override;
|
||||
use PDO;
|
||||
|
||||
/**
|
||||
* Adapts DBAL 2.6 API for DBAL 3.x for backwards compatibility of a leaked type
|
||||
*/
|
||||
class ResultAdapter implements IResult {
|
||||
/** @var Result */
|
||||
private $inner;
|
||||
|
||||
public function __construct(Result $inner) {
|
||||
$this->inner = $inner;
|
||||
public function __construct(
|
||||
private readonly Result $inner,
|
||||
) {
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function closeCursor(): bool {
|
||||
$this->inner->free();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function fetch(int $fetchMode = PDO::FETCH_ASSOC) {
|
||||
return match ($fetchMode) {
|
||||
PDO::FETCH_ASSOC => $this->inner->fetchAssociative(),
|
||||
|
|
@ -38,6 +39,22 @@ class ResultAdapter implements IResult {
|
|||
};
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function fetchAssociative(): array|false {
|
||||
return $this->inner->fetchAssociative();
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function fetchNumeric(): array|false {
|
||||
return $this->inner->fetchNumeric();
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function fetchOne(): mixed {
|
||||
return $this->inner->fetchOne();
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function fetchAll(int $fetchMode = PDO::FETCH_ASSOC): array {
|
||||
return match ($fetchMode) {
|
||||
PDO::FETCH_ASSOC => $this->inner->fetchAllAssociative(),
|
||||
|
|
@ -47,15 +64,38 @@ class ResultAdapter implements IResult {
|
|||
};
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function fetchColumn($columnIndex = 0) {
|
||||
return $this->inner->fetchOne();
|
||||
}
|
||||
|
||||
public function fetchOne() {
|
||||
return $this->inner->fetchOne();
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function rowCount(): int {
|
||||
return $this->inner->rowCount();
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function fetchAllAssociative(): array {
|
||||
return $this->inner->fetchAllAssociative();
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function fetchAllNumeric(): array {
|
||||
return $this->inner->fetchAllNumeric();
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function fetchFirstColumn(): array {
|
||||
return $this->inner->fetchFirstColumn();
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function iterateNumeric(): \Traversable {
|
||||
yield from $this->inner->iterateNumeric();
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function iterateAssociative(): \Traversable {
|
||||
yield from $this->inner->iterateAssociative();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,9 @@ declare(strict_types=1);
|
|||
*/
|
||||
namespace OCP\DB;
|
||||
|
||||
use OCP\AppFramework\Attribute\Consumable;
|
||||
use PDO;
|
||||
use Traversable;
|
||||
|
||||
/**
|
||||
* This interface represents the result of a database query.
|
||||
|
|
@ -19,12 +21,15 @@ use PDO;
|
|||
* $qb = $this->db->getQueryBuilder();
|
||||
* $qb->select(...);
|
||||
* $result = $query->executeQuery();
|
||||
* ```
|
||||
*
|
||||
* This interface must not be implemented in your application.
|
||||
* foreach ($result->iterateAssociative() as $row) {
|
||||
* $id = $row['id'];
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* @since 21.0.0
|
||||
*/
|
||||
#[Consumable(since: '21.0.0')]
|
||||
interface IResult {
|
||||
/**
|
||||
* @return true
|
||||
|
|
@ -39,25 +44,27 @@ interface IResult {
|
|||
* @return mixed
|
||||
*
|
||||
* @since 21.0.0
|
||||
* @deprecated Since 33.0.0, use fetchAssociative/fetchNumeric/fetchOne or iterateAssociate/iterateNumeric instead.
|
||||
*/
|
||||
public function fetch(int $fetchMode = PDO::FETCH_ASSOC);
|
||||
|
||||
/**
|
||||
* @param int $fetchMode (one of PDO::FETCH_ASSOC, PDO::FETCH_NUM or PDO::FETCH_COLUMN (2, 3 or 7)
|
||||
* Returns the next row of the result as an associative array or FALSE if there are no more rows.
|
||||
*
|
||||
* @return mixed[]
|
||||
* @return array<string, mixed>|false
|
||||
*
|
||||
* @since 21.0.0
|
||||
* @since 33.0.0
|
||||
*/
|
||||
public function fetchAll(int $fetchMode = PDO::FETCH_ASSOC): array;
|
||||
public function fetchAssociative(): array|false;
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
* Returns the next row of the result as a numeric array or FALSE if there are no more rows.
|
||||
*
|
||||
* @since 21.0.0
|
||||
* @deprecated 21.0.0 use \OCP\DB\IResult::fetchOne
|
||||
* @return list<mixed>|false
|
||||
*
|
||||
* @since 33.0.0
|
||||
*/
|
||||
public function fetchColumn();
|
||||
public function fetchNumeric(): array|false;
|
||||
|
||||
/**
|
||||
* Returns the first value of the next row of the result or FALSE if there are no more rows.
|
||||
|
|
@ -68,10 +75,70 @@ interface IResult {
|
|||
*/
|
||||
public function fetchOne();
|
||||
|
||||
/**
|
||||
* @param int $fetchMode (one of PDO::FETCH_ASSOC, PDO::FETCH_NUM or PDO::FETCH_COLUMN (2, 3 or 7)
|
||||
*
|
||||
* @return mixed[]
|
||||
*
|
||||
* @since 21.0.0
|
||||
* @deprecated Since 33.0.0, use fetchAllAssociative/fetchAllNumeric/fetchFirstColumn or iterateAssociate/iterateNumeric instead.
|
||||
*/
|
||||
public function fetchAll(int $fetchMode = PDO::FETCH_ASSOC): array;
|
||||
|
||||
/**
|
||||
* Returns an array containing all the result rows represented as associative arrays.
|
||||
*
|
||||
* @return list<array<string,mixed>>
|
||||
* @since 33.0.0
|
||||
*/
|
||||
public function fetchAllAssociative(): array;
|
||||
|
||||
/**
|
||||
* Returns an array containing all the result rows represented as numeric arrays.
|
||||
*
|
||||
* @return list<list<mixed>>
|
||||
* @since 33.0.0
|
||||
*/
|
||||
public function fetchAllNumeric(): array;
|
||||
|
||||
/**
|
||||
* Returns the value of the first column of all rows.
|
||||
*
|
||||
* @return list<mixed>
|
||||
* @since 33.0.0
|
||||
*/
|
||||
public function fetchFirstColumn(): array;
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*
|
||||
* @since 21.0.0
|
||||
* @deprecated 21.0.0 use \OCP\DB\IResult::fetchOne
|
||||
*/
|
||||
public function fetchColumn();
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*
|
||||
* @since 21.0.0
|
||||
*/
|
||||
public function rowCount(): int;
|
||||
|
||||
/**
|
||||
* Returns the result as an iterator over rows represented as numeric arrays.
|
||||
*
|
||||
* @return Traversable<list<mixed>>
|
||||
*
|
||||
* @since 33.0.0
|
||||
*/
|
||||
public function iterateNumeric(): Traversable;
|
||||
|
||||
/**
|
||||
* Returns the result as an iterator over rows represented as associative arrays.
|
||||
*
|
||||
* @return Traversable<array<string,mixed>>
|
||||
*
|
||||
* @since 33.0.0
|
||||
*/
|
||||
public function iterateAssociative(): Traversable;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue