Last active
May 5, 2020 19:05
-
-
Save someniatko/ae8ac64419d7ce28e1b092384714b404 to your computer and use it in GitHub Desktop.
DBAL wrapper draft
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
use MyCLabs\Enum\Enum; | |
use Doctrine\DBAL\Driver\Connection; | |
interface QueryExecutorInterface | |
{ | |
/** | |
* @psalm-template T | |
* @psalm-param Query<T> | |
* @psalm-return T | |
*/ | |
public function execute(Query $query); | |
} | |
/** | |
* @method static self ALL_ROWS() | |
* @method static self ROW() | |
* @method static self COLUMN() | |
* @method static self NOTHING() | |
* @psalm-immutable | |
* @psalm-extends Enum<int> | |
*/ | |
final class FetchScope extends Enum | |
{ | |
public const ALL_ROWS = 1; | |
public const COLUMN = 2; | |
public const ROW = 3; | |
public const NOTHING = 4; | |
} | |
/** | |
* @psalm-immutable | |
* @psalm-template T | |
*/ | |
final class Query | |
{ | |
public string $sql; | |
/** @var array<string, mixed> */ | |
public array $params; | |
public FetchScope $scope; | |
public int $fetchMode; | |
public ?string $fetchModeParam; | |
/** @param array<string, mixed> $params */ | |
public function __construct( | |
string $sql, | |
array $params, | |
FetchScope $scope, | |
int $fetchMode = FetchMode::MIXED, | |
?string $fetchModeParam = null | |
) { | |
$this->sql = $sql; | |
$this->params = $params; | |
$this->scope = $scope; | |
$this->fetchMode = $fetchMode; | |
$this->fetchModeParam = $fetchModeParam; | |
} | |
} | |
final class QueryExecutor implements QueryExecutorInterface | |
{ | |
private Connection $dbConnection; | |
public function __construct(Connection $dbConnection) | |
{ | |
$this->dbConnection = $dbConnection; | |
} | |
public function execute(Query $query) | |
{ | |
$statement = $this->dbConnection->prepare($query->sql); | |
foreach ($query->params as $paramName => $paramValue) { | |
$statement->bindValue($paramName, $paramValue); | |
} | |
$statement->setFetchMode($query->fetchMode, $query->fetchModeParam); | |
$statement->execute(); | |
switch ($query->scope->getValue()) { | |
case FetchScope::ALL_ROWS: | |
return $statement->fetchAll(); | |
case FetchScope::ROW: | |
return $statement->fetch(); | |
case FetchScope::COLUMN: | |
return $statement->fetchColumn(); | |
case FetchScope::NOTHING: | |
return null; | |
} | |
throw new \LogicException('should never happen'); | |
} | |
} | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* @psalm-immutable | |
*/ | |
interface LogQueryBuilderInterface | |
{ | |
/** @return Query<LogDbRecord> */ | |
public function selectLog(string $id, string $type): Query; | |
/** @return Query<null> */ | |
public function insertOrUpdateLog(LogDbRecord $record): Query; | |
/** @psalm-return Query<list<LogDbRecord>> */ | |
public function selectLogsChunkByType(string $type, int $limit, int $offset): Query; | |
/** @return Query<int> */ | |
public function countLogsByType(string $type): Query; | |
} | |
/** | |
* @psalm-immutable | |
*/ | |
interface LogDbRecordMapperInterface | |
{ | |
public function toDbRecord(ImportType $type, ImportLog $log): LogDbRecord; | |
public function fromDbRecord(LogDbRecord $record): ImportLog; | |
} | |
final class PersistenceLayer implements PersistenceLayerInterface | |
{ | |
private QueryExecutorInterface $executor; | |
private LogQueryBuilderInterface $queries; | |
private LogDbRecordMapperInterface $mapper; | |
public function __construct( | |
QueryExecutorInterface $executor, | |
LogQueryBuilderInterface $queries, | |
LogDbRecordMapperInterface $mapper | |
) { | |
$this->executor = $executor; | |
$this->queries = $queries; | |
$this->mapper = $mapper; | |
} | |
public function readLog(ImportType $type, LogId $id): ImportLog | |
{ | |
return $this->mapper->fromDbRecord( | |
$this->executor->execute( | |
$this->queries->selectLog( | |
$id->value->getBytes(), | |
$type->getValue() | |
) | |
) | |
); | |
} | |
public function saveLog(ImportType $type, ImportLog $log): void | |
{ | |
$this->executor->execute( | |
$this->queries->insertOrUpdateLog( | |
$this->mapper->toDbRecord($type, $log) | |
) | |
); | |
} | |
public function readLogsChunk(ImportType $type, ChunkSpec $chunkSpec): array | |
{ | |
return $this->executor->execute( | |
$this->queries->selectLogsChunkByType((string) $type, $chunkSpec->limit, $chunkSpec->offset) | |
); | |
} | |
public function countLogs(ImportType $type): int | |
{ | |
return $this->executor->execute( | |
$this->queries->countLogsByType((string) $type) | |
); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment