recreate project
This commit is contained in:
+136
@@ -0,0 +1,136 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\DBAL\Cache;
|
||||
|
||||
use Doctrine\DBAL\Driver\FetchUtils;
|
||||
use Doctrine\DBAL\Driver\Result;
|
||||
use Doctrine\DBAL\Exception\InvalidColumnIndex;
|
||||
|
||||
use function array_combine;
|
||||
use function array_keys;
|
||||
use function array_map;
|
||||
use function array_values;
|
||||
use function count;
|
||||
|
||||
/** @internal The class is internal to the caching layer implementation. */
|
||||
final class ArrayResult implements Result
|
||||
{
|
||||
private int $num = 0;
|
||||
|
||||
/**
|
||||
* @param list<string> $columnNames The names of the result columns. Must be non-empty.
|
||||
* @param list<list<mixed>> $rows The rows of the result. Each row must have the same number of columns
|
||||
* as the number of column names.
|
||||
*/
|
||||
public function __construct(
|
||||
private readonly array $columnNames,
|
||||
private array $rows,
|
||||
) {
|
||||
}
|
||||
|
||||
public function fetchNumeric(): array|false
|
||||
{
|
||||
return $this->fetch();
|
||||
}
|
||||
|
||||
public function fetchAssociative(): array|false
|
||||
{
|
||||
$row = $this->fetch();
|
||||
|
||||
if ($row === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return array_combine($this->columnNames, $row);
|
||||
}
|
||||
|
||||
public function fetchOne(): mixed
|
||||
{
|
||||
$row = $this->fetch();
|
||||
|
||||
if ($row === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $row[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function fetchAllNumeric(): array
|
||||
{
|
||||
return FetchUtils::fetchAllNumeric($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function fetchAllAssociative(): array
|
||||
{
|
||||
return FetchUtils::fetchAllAssociative($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function fetchFirstColumn(): array
|
||||
{
|
||||
return FetchUtils::fetchFirstColumn($this);
|
||||
}
|
||||
|
||||
public function rowCount(): int
|
||||
{
|
||||
return count($this->rows);
|
||||
}
|
||||
|
||||
public function columnCount(): int
|
||||
{
|
||||
return count($this->columnNames);
|
||||
}
|
||||
|
||||
public function getColumnName(int $index): string
|
||||
{
|
||||
return $this->columnNames[$index] ?? throw InvalidColumnIndex::new($index);
|
||||
}
|
||||
|
||||
public function free(): void
|
||||
{
|
||||
$this->rows = [];
|
||||
}
|
||||
|
||||
/** @return array{list<string>, list<list<mixed>>} */
|
||||
public function __serialize(): array
|
||||
{
|
||||
return [$this->columnNames, $this->rows];
|
||||
}
|
||||
|
||||
/** @param mixed[] $data */
|
||||
public function __unserialize(array $data): void
|
||||
{
|
||||
// Handle objects serialized with DBAL 4.1 and earlier.
|
||||
if (isset($data["\0" . self::class . "\0data"])) {
|
||||
/** @var list<array<string, mixed>> $legacyData */
|
||||
$legacyData = $data["\0" . self::class . "\0data"];
|
||||
|
||||
$this->columnNames = array_keys($legacyData[0] ?? []);
|
||||
$this->rows = array_map(array_values(...), $legacyData);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
[$this->columnNames, $this->rows] = $data;
|
||||
}
|
||||
|
||||
/** @return list<mixed>|false */
|
||||
private function fetch(): array|false
|
||||
{
|
||||
if (! isset($this->rows[$this->num])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->rows[$this->num++];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\DBAL\Cache;
|
||||
|
||||
use Doctrine\DBAL\Exception;
|
||||
|
||||
class CacheException extends \Exception implements Exception
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\DBAL\Cache\Exception;
|
||||
|
||||
use Doctrine\DBAL\Cache\CacheException;
|
||||
|
||||
final class NoCacheKey extends CacheException
|
||||
{
|
||||
public static function new(): self
|
||||
{
|
||||
return new self('No cache key was set.');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\DBAL\Cache\Exception;
|
||||
|
||||
use Doctrine\DBAL\Cache\CacheException;
|
||||
|
||||
final class NoResultDriverConfigured extends CacheException
|
||||
{
|
||||
public static function new(): self
|
||||
{
|
||||
return new self('Trying to cache a query but no result driver is configured.');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\DBAL\Cache;
|
||||
|
||||
use Doctrine\DBAL\Cache\Exception\NoCacheKey;
|
||||
use Doctrine\DBAL\Connection;
|
||||
use Psr\Cache\CacheItemPoolInterface;
|
||||
|
||||
use function hash;
|
||||
use function serialize;
|
||||
use function sha1;
|
||||
|
||||
/**
|
||||
* Query Cache Profile handles the data relevant for query caching.
|
||||
*
|
||||
* It is a value object, setter methods return NEW instances.
|
||||
*
|
||||
* @phpstan-import-type WrapperParameterType from Connection
|
||||
* @final
|
||||
*/
|
||||
class QueryCacheProfile
|
||||
{
|
||||
public function __construct(
|
||||
private readonly int $lifetime = 0,
|
||||
private readonly ?string $cacheKey = null,
|
||||
private readonly ?CacheItemPoolInterface $resultCache = null,
|
||||
) {
|
||||
}
|
||||
|
||||
public function getResultCache(): ?CacheItemPoolInterface
|
||||
{
|
||||
return $this->resultCache;
|
||||
}
|
||||
|
||||
public function getLifetime(): int
|
||||
{
|
||||
return $this->lifetime;
|
||||
}
|
||||
|
||||
/** @throws CacheException */
|
||||
public function getCacheKey(): string
|
||||
{
|
||||
if ($this->cacheKey === null) {
|
||||
throw NoCacheKey::new();
|
||||
}
|
||||
|
||||
return $this->cacheKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the real cache key from query, params, types and connection parameters.
|
||||
*
|
||||
* @param list<mixed>|array<string, mixed> $params
|
||||
* @param array<string, mixed> $connectionParams
|
||||
* @phpstan-param array<int, WrapperParameterType>|array<string, WrapperParameterType> $types
|
||||
*
|
||||
* @return array{string, string}
|
||||
*/
|
||||
public function generateCacheKeys(string $sql, array $params, array $types, array $connectionParams = []): array
|
||||
{
|
||||
if (isset($connectionParams['password'])) {
|
||||
unset($connectionParams['password']);
|
||||
}
|
||||
|
||||
$realCacheKey = 'query=' . $sql .
|
||||
'¶ms=' . serialize($params) .
|
||||
'&types=' . serialize($types) .
|
||||
'&connectionParams=' . hash('sha256', serialize($connectionParams));
|
||||
|
||||
// should the key be automatically generated using the inputs or is the cache key set?
|
||||
$cacheKey = $this->cacheKey ?? sha1($realCacheKey);
|
||||
|
||||
return [$cacheKey, $realCacheKey];
|
||||
}
|
||||
|
||||
public function setResultCache(CacheItemPoolInterface $cache): QueryCacheProfile
|
||||
{
|
||||
return new QueryCacheProfile($this->lifetime, $this->cacheKey, $cache);
|
||||
}
|
||||
|
||||
public function setCacheKey(?string $cacheKey): self
|
||||
{
|
||||
return new QueryCacheProfile($this->lifetime, $cacheKey, $this->resultCache);
|
||||
}
|
||||
|
||||
public function setLifetime(int $lifetime): self
|
||||
{
|
||||
return new QueryCacheProfile($lifetime, $this->cacheKey, $this->resultCache);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user