Last active
October 2, 2024 19:09
-
-
Save SelrahcD/7317010d0d8d4b1b10befa5c347e9e71 to your computer and use it in GitHub Desktop.
Storing aggregates using Postgres Json Column
This file contains 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 | |
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