Skip to content

Instantly share code, notes, and snippets.

@SelrahcD
Last active October 2, 2024 19:09
Show Gist options
  • Save SelrahcD/7317010d0d8d4b1b10befa5c347e9e71 to your computer and use it in GitHub Desktop.
Save SelrahcD/7317010d0d8d4b1b10befa5c347e9e71 to your computer and use it in GitHub Desktop.
Storing aggregates using Postgres Json Column
<?php
final readonly class DatabaseLots implements Lots
{
public function __construct(
private EventDispatcherInterface $eventDispatcher,
private PDO $connection
) {
}
public function enregistrer(Lot $lot): void
{
$statement = $this->connection->prepare(
'INSERT INTO lots (id, data) VALUES (:id, :data)
ON CONFLICT (id) DO UPDATE
SET data = EXCLUDED.data, version = lots.version + 1
WHERE lots.version = :version AND lots.id = :id
RETURNING id, version'
);
$statement->execute(
['data' => json_encode($lot->toArray()), 'version' => $lot->version, 'id' => $lot->id->toString()]
);
/**
* @var array{id: string, version: int} | false $updatedData
*/
$updatedData = $statement->fetch(PDO::FETCH_ASSOC);
if (!$updatedData) {
throw new \Exception('Concurrency exception.');
}
foreach ($lot->releaseEvents() as $event) {
$this->eventDispatcher->dispatch($event);
}
$lot->version = $updatedData['version'];
}
public function avecId(LotId $lotId): Lot
{
$statement = $this->connection->prepare(
'SELECT id, data, version FROM lots WHERE id = :id LIMIT 1'
);
$statement->execute(['id' => $lotId->toString()]);
$dataLot = $statement->fetch(PDO::FETCH_ASSOC);
assert(is_array($dataLot));
return Lot::fromSerializedData($dataLot['id'], $dataLot['version'], $dataLot['data']);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment