-
Notifications
You must be signed in to change notification settings - Fork 11
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Populate Projection with multiple tables #59
Comments
Solution 1: A single Manager and Read Model for Projection "audience" Both tables are managed by a single read model. // ...
final class PgsqlAudienceProjection implements ReadModelProjection
{
public function project(ReadModelProjector $projector): ReadModelProjector
{
$projector->fromStreams('guest_profile_stream', 'visit_stream', 'guest_preference_stream')
->when([
GuestProfileCreated::class => function ($state, GuestProfileCreated $event) {
/** @var PgsqlAudienceReadModel $readModel */
$readModel = $this->readModel();
$readModel->stack('insertGuest', [/*...*/]);
},
GuestSelfCheckedIn::class => function ($state, GuestSelfCheckedIn $event) {
/** @var PgsqlAudienceReadModel $readModel */
$readModel = $this->readModel();
$readModel->stack('insert', [/*...*/]);
}
]);
return $projector;
}
} final class PgsqlAudienceReadModel extends AbstractReadModel
{
private \PDO $connection;
public function __construct(\PDO $connection)
{
$this->connection = $connection;
}
public function init() : void
{
$this->connection->exec(sprintf('create table %1$s (
visit_id uuid not null,
guest_id uuid not null,
// ...
primary key (visit_id)
);', ProjectionName::AUDIENCE));
$this->connection->exec(sprintf('create table %1$s (
guest_id uuid not null,
// ...
primary key (guest_id)
);', ProjectionName::GUEST_DATA));
}
public function reset() : void
{
$this->connection->exec(sprintf('TRUNCATE TABLE %s', ProjectionName::AUDIENCE));
$this->connection->exec(sprintf('TRUNCATE TABLE %s', ProjectionName::GUEST_DATA));
}
public function delete() : void
{
$this->connection->exec(sprintf('DROP TABLE %s', ProjectionName::AUDIENCE));
$this->connection->exec(sprintf('DROP TABLE %s', ProjectionName::GUEST_DATA));
}
protected function insertGuest(array $data): void
{
// ...
}
protected function insert(array $data): void
{
// ...
}
// ...
} Solution 2: A single Manager and separate Read Models for Projection "audience" // ...
final class PgsqlAudienceProjection implements ReadModelProjection
{
public function project(ReadModelProjector $projector): ReadModelProjector
{
$projector->fromStreams('guest_profile_stream', 'visit_stream', 'guest_preference_stream')
->when([
GuestProfileCreated::class => function ($state, GuestProfileCreated $event) {
/** @var PgsqlGuestDataReadModel $readModel */
$readModel = $this->readModel();
$readModel->stack('insert', [/*...*/]);
},
GuestSelfCheckedIn::class => function ($state, GuestSelfCheckedIn $event) {
$guest = $state['guests'][$event->guestId()->toString()];
/** @var PgsqlAudienceReadModel $readModel */
$readModel = $this->readModel();
$readModel->stack('insert', [/*...*/]);
}
]);
return $projector;
}
} Which one would you prefer @codeliner @prolic? |
I have projectors per use case, not per table. It could be however, that your use case involves one projector per table. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Came from:
As suggested by @prooph and @gquemener for SQL projections:
I will post two possible solutions for this in Prooph soon.
The text was updated successfully, but these errors were encountered: