Skip to content

Commit

Permalink
Replace fetch mode with explicit API
Browse files Browse the repository at this point in the history
  • Loading branch information
morozov committed May 15, 2020
1 parent fd0c14e commit 80c43f5
Show file tree
Hide file tree
Showing 66 changed files with 1,434 additions and 1,012 deletions.
107 changes: 67 additions & 40 deletions src/Cache/ArrayStatement.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,14 @@

namespace Doctrine\DBAL\Cache;

use ArrayIterator;
use Doctrine\DBAL\Driver\FetchUtils;
use Doctrine\DBAL\Driver\ResultStatement;
use Doctrine\DBAL\FetchMode;
use InvalidArgumentException;
use IteratorAggregate;
use function array_merge;
use Traversable;
use function array_values;
use function count;
use function reset;
use function sprintf;

final class ArrayStatement implements IteratorAggregate, ResultStatement
final class ArrayStatement implements ResultStatement
{
/** @var mixed[] */
private $data;
Expand Down Expand Up @@ -57,69 +53,100 @@ public function rowCount() : int
/**
* {@inheritdoc}
*/
public function getIterator()
public function fetchNumeric()
{
$data = $this->fetchAll();
$row = $this->fetch();

return new ArrayIterator($data);
if ($row === false) {
return false;
}

return array_values($row);
}

/**
* {@inheritdoc}
*/
public function fetch(int $fetchMode = FetchMode::ASSOCIATIVE)
public function fetchAssociative()
{
if (! isset($this->data[$this->num])) {
return false;
}

$row = $this->data[$this->num++];
return $this->fetch();
}

if ($fetchMode === FetchMode::ASSOCIATIVE) {
return $row;
}
/**
* {@inheritdoc}
*/
public function fetchOne()
{
$row = $this->fetch();

if ($fetchMode === FetchMode::NUMERIC) {
return array_values($row);
if ($row === false) {
return false;
}

if ($fetchMode === FetchMode::MIXED) {
return array_merge($row, array_values($row));
}
return reset($row);
}

if ($fetchMode === FetchMode::COLUMN) {
return reset($row);
}
/**
* {@inheritdoc}
*/
public function fetchAllNumeric() : array
{
return FetchUtils::fetchAllNumeric($this);
}

throw new InvalidArgumentException(
sprintf('Invalid fetch mode given for fetching result, %d given.', $fetchMode)
);
/**
* {@inheritdoc}
*/
public function fetchAllAssociative() : array
{
return FetchUtils::fetchAllAssociative($this);
}

/**
* {@inheritdoc}
*/
public function fetchAll(int $fetchMode = FetchMode::ASSOCIATIVE) : array
public function fetchColumn() : array
{
$rows = [];
while ($row = $this->fetch($fetchMode)) {
$rows[] = $row;
return FetchUtils::fetchColumn($this);
}

/**
* @return Traversable<int,array<int,mixed>>
*/
public function iterateNumeric() : Traversable
{
foreach ($this->data as $row) {
yield array_values($row);
}
}

return $rows;
/**
* @return Traversable<int,array<string,mixed>>
*/
public function iterateAssociative() : Traversable
{
yield from $this->data;
}

/**
* {@inheritdoc}
* @return Traversable<int,mixed>
*/
public function fetchColumn()
public function iterateColumn() : Traversable
{
$row = $this->fetch(FetchMode::NUMERIC);
foreach ($this->data as $row) {
yield reset($row);
}
}

if ($row === false) {
/**
* @return mixed|false
*/
private function fetch()
{
if (! isset($this->data[$this->num])) {
return false;
}

return $row[0];
return $this->data[$this->num++];
}
}
172 changes: 112 additions & 60 deletions src/Cache/ResultCacheStatement.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,12 @@

namespace Doctrine\DBAL\Cache;

use ArrayIterator;
use Doctrine\Common\Cache\Cache;
use Doctrine\DBAL\Driver\DriverException;
use Doctrine\DBAL\Driver\FetchUtils;
use Doctrine\DBAL\Driver\ResultStatement;
use Doctrine\DBAL\FetchMode;
use InvalidArgumentException;
use IteratorAggregate;
use function array_merge;
use Traversable;
use function array_values;
use function reset;

/**
* Cache statement for SQL results.
Expand All @@ -27,7 +24,7 @@
* Also you have to realize that the cache will load the whole result into memory at once to ensure 2.
* This means that the memory usage for cached results might increase by using this feature.
*/
final class ResultCacheStatement implements IteratorAggregate, ResultStatement
final class ResultCacheStatement implements ResultStatement
{
/** @var Cache */
private $resultCache;
Expand All @@ -51,7 +48,7 @@ final class ResultCacheStatement implements IteratorAggregate, ResultStatement
*/
private $emptied = false;

/** @var mixed[] */
/** @var array<int,array<mixed>> */
private $data;

public function __construct(ResultStatement $stmt, Cache $resultCache, string $cacheKey, string $realKey, int $lifetime)
Expand Down Expand Up @@ -90,82 +87,94 @@ public function columnCount() : int
/**
* {@inheritdoc}
*/
public function getIterator()
public function fetchNumeric()
{
$data = $this->fetchAll();
$row = $this->fetch();

return new ArrayIterator($data);
if ($row === false) {
return false;
}

return array_values($row);
}

/**
* {@inheritdoc}
*/
public function fetch(int $fetchMode = FetchMode::ASSOCIATIVE)
public function fetchAssociative()
{
if ($this->data === null) {
$this->data = [];
}

$row = $this->statement->fetch(FetchMode::ASSOCIATIVE);

if ($row !== false) {
$this->data[] = $row;

if ($fetchMode === FetchMode::ASSOCIATIVE) {
return $row;
}

if ($fetchMode === FetchMode::NUMERIC) {
return array_values($row);
}

if ($fetchMode === FetchMode::MIXED) {
return array_merge($row, array_values($row));
}

if ($fetchMode === FetchMode::COLUMN) {
return reset($row);
}

throw new InvalidArgumentException('Invalid fetch-style given for caching result.');
}

$this->emptied = true;

return false;
return $this->fetch();
}

/**
* {@inheritdoc}
*/
public function fetchAll(int $fetchMode = FetchMode::ASSOCIATIVE) : array
public function fetchOne()
{
$data = $this->statement->fetchAll($fetchMode);

if ($fetchMode === FetchMode::COLUMN) {
foreach ($data as $key => $value) {
$data[$key] = [$value];
}
}
return FetchUtils::fetchOne($this);
}

$this->data = $data;
$this->emptied = true;
/**
* {@inheritdoc}
*/
public function fetchAllNumeric() : array
{
return $this->store(
$this->statement->fetchAllAssociative(),
true
);
}

return $this->data;
/**
* {@inheritdoc}
*/
public function fetchAllAssociative() : array
{
return $this->store(
$this->statement->fetchAllAssociative(),
true
);
}

/**
* {@inheritdoc}
*/
public function fetchColumn()
public function fetchColumn() : array
{
$row = $this->fetch(FetchMode::NUMERIC);
return $this->store(
$this->statement->fetchAllAssociative(),
true
);
}

if ($row === false) {
return false;
}
/**
* @return Traversable<int,array<int,mixed>>
*
* @throws DriverException
*/
public function iterateNumeric() : Traversable
{
return FetchUtils::iterateNumeric($this);
}

/**
* @return Traversable<int,array<string,mixed>>
*
* @throws DriverException
*/
public function iterateAssociative() : Traversable
{
return FetchUtils::iterateAssociative($this);
}

return $row[0];
/**
* @return Traversable<int,mixed>
*
* @throws DriverException
*/
public function iterateColumn() : Traversable
{
return FetchUtils::iterateColumn($this);
}

/**
Expand All @@ -183,4 +192,47 @@ public function rowCount() : int
{
return $this->statement->rowCount();
}

/**
* @return array<string,mixed>|false
*
* @throws DriverException
*/
private function fetch()
{
if ($this->data === null) {
$this->data = [];
}

$row = $this->statement->fetchAssociative();

if ($row !== false) {
$this->data[] = $row;

return $row;
}

$this->emptied = true;

return false;
}

/**
* @param array<int,array<mixed>> $data
*
* @return array<int,array<mixed>>
*/
private function store(array $data, bool $isArray) : array
{
if (! $isArray) {
foreach ($data as $key => $value) {
$data[$key] = [$value];
}
}

$this->data = $data;
$this->emptied = true;

return $this->data;
}
}
Loading

0 comments on commit 80c43f5

Please sign in to comment.