Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 30 additions & 6 deletions phpstan-baseline.neon
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,6 @@ parameters:
count: 1
path: src/Message/Serializer/DefaultHeadersSerializer.php

-
message: '#^Call to an undefined method Patchlevel\\EventSourcing\\Store\\Store\:\:archive\(\)\.$#'
identifier: method.notFound
count: 1
path: src/Repository/DefaultRepository.php

-
message: '#^Parameter \#1 \.\.\.\$streamName of class Patchlevel\\EventSourcing\\Store\\Criteria\\StreamCriterion constructor expects string, string\|null given\.$#'
identifier: argument.type
Expand Down Expand Up @@ -168,6 +162,24 @@ parameters:
count: 3
path: src/Subscription/ThrowableToErrorContextTransformer.php

-
message: '#^Property Patchlevel\\EventSourcing\\Tests\\Benchmark\\BasicImplementation\\ProfileWithCommands\:\:\$id is never read, only written\.$#'
identifier: property.onlyWritten
count: 1
path: tests/Benchmark/BasicImplementation/ProfileWithCommands.php

-
message: '#^Cannot access offset ''name'' on array\<string, mixed\>\|false\.$#'
identifier: offsetAccess.nonOffsetAccessible
count: 1
path: tests/Benchmark/BasicImplementation/Projection/ProfileProjector.php

-
message: '#^Method Patchlevel\\EventSourcing\\Tests\\Benchmark\\BasicImplementation\\Projection\\ProfileProjector\:\:getProfileName\(\) should return string but returns mixed\.$#'
identifier: return.type
count: 1
path: tests/Benchmark/BasicImplementation/Projection/ProfileProjector.php

-
message: '#^Parameter \#1 \$id of static method Patchlevel\\EventSourcing\\Tests\\Benchmark\\BasicImplementation\\Profile\:\:create\(\) expects Patchlevel\\EventSourcing\\Tests\\Benchmark\\BasicImplementation\\ProfileId, Patchlevel\\EventSourcing\\Aggregate\\AggregateRootId given\.$#'
identifier: argument.type
Expand Down Expand Up @@ -234,6 +246,18 @@ parameters:
count: 1
path: tests/Integration/BasicImplementation/ProfileWithCommands.php

-
message: '#^Cannot access offset ''name'' on array\<string, mixed\>\|false\.$#'
identifier: offsetAccess.nonOffsetAccessible
count: 1
path: tests/Integration/BasicImplementation/Projection/ProfileProjector.php

-
message: '#^Method Patchlevel\\EventSourcing\\Tests\\Integration\\BasicImplementation\\Projection\\ProfileProjector\:\:getProfileName\(\) should return string but returns mixed\.$#'
identifier: return.type
count: 1
path: tests/Integration/BasicImplementation/Projection/ProfileProjector.php

-
message: '#^Call to static method PHPUnit\\Framework\\Assert\:\:assertInstanceOf\(\) with ''Patchlevel\\\\EventSourcing\\\\Tests\\\\Integration\\\\ChildAggregate\\\\Profile'' and Patchlevel\\EventSourcing\\Tests\\Integration\\ChildAggregate\\Profile will always evaluate to true\.$#'
identifier: staticMethod.alreadyNarrowedType
Expand Down
14 changes: 7 additions & 7 deletions src/Subscription/Engine/SubscriptionManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -77,48 +77,48 @@ public function find(SubscriptionCriteria $criteria): array
public function add(Subscription ...$subscriptions): void
{
foreach ($subscriptions as $sub) {
$this->forAdd->attach($sub);
$this->forAdd->offsetSet($sub);
}
}

public function update(Subscription ...$subscriptions): void
{
foreach ($subscriptions as $sub) {
$this->forUpdate->attach($sub);
$this->forUpdate->offsetSet($sub);
}
}

public function remove(Subscription ...$subscriptions): void
{
foreach ($subscriptions as $sub) {
$this->forRemove->attach($sub);
$this->forRemove->offsetSet($sub);
}
}

public function flush(): void
{
foreach ($this->forAdd as $subscription) {
if ($this->forRemove->contains($subscription)) {
if ($this->forRemove->offsetExists($subscription)) {
continue;
}

$this->subscriptionStore->add($subscription);
}

foreach ($this->forUpdate as $subscription) {
if ($this->forAdd->contains($subscription)) {
if ($this->forAdd->offsetExists($subscription)) {
continue;
}

if ($this->forRemove->contains($subscription)) {
if ($this->forRemove->offsetExists($subscription)) {
continue;
}

$this->subscriptionStore->update($subscription);
}

foreach ($this->forRemove as $subscription) {
if ($this->forAdd->contains($subscription)) {
if ($this->forAdd->offsetExists($subscription)) {
continue;
}

Expand Down
18 changes: 18 additions & 0 deletions tests/Benchmark/BasicImplementation/Command/ChangeProfileName.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

declare(strict_types=1);

namespace Patchlevel\EventSourcing\Tests\Benchmark\BasicImplementation\Command;

use Patchlevel\EventSourcing\Attribute\Id;
use Patchlevel\EventSourcing\Tests\Benchmark\BasicImplementation\ProfileId;

final class ChangeProfileName
{
public function __construct(
#[Id]
public readonly ProfileId $id,
public readonly string $name,
) {
}
}
16 changes: 16 additions & 0 deletions tests/Benchmark/BasicImplementation/Command/CreateProfile.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php

declare(strict_types=1);

namespace Patchlevel\EventSourcing\Tests\Benchmark\BasicImplementation\Command;

use Patchlevel\EventSourcing\Tests\Benchmark\BasicImplementation\ProfileId;

final class CreateProfile
{
public function __construct(
public readonly ProfileId $id,
public readonly string $name,
) {
}
}
4 changes: 3 additions & 1 deletion tests/Benchmark/BasicImplementation/Events/NameChanged.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@
namespace Patchlevel\EventSourcing\Tests\Benchmark\BasicImplementation\Events;

use Patchlevel\EventSourcing\Attribute\Event;
use Patchlevel\EventSourcing\Tests\Benchmark\BasicImplementation\ProfileId;

#[Event('profile.name_changed')]
final class NameChanged
final readonly class NameChanged
{
public function __construct(
public ProfileId $profileId,
public string $name,
) {
}
Expand Down
2 changes: 1 addition & 1 deletion tests/Benchmark/BasicImplementation/Profile.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public static function create(ProfileId $id, string $name, string|null $email =

public function changeName(string $name): void
{
$this->recordThat(new NameChanged($name));
$this->recordThat(new NameChanged($this->id, $name));
}

public function changeEmail(string $email): void
Expand Down
68 changes: 68 additions & 0 deletions tests/Benchmark/BasicImplementation/ProfileWithCommands.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
<?php

declare(strict_types=1);

namespace Patchlevel\EventSourcing\Tests\Benchmark\BasicImplementation;

use Patchlevel\EventSourcing\Aggregate\BasicAggregateRoot;
use Patchlevel\EventSourcing\Attribute\Aggregate;
use Patchlevel\EventSourcing\Attribute\Apply;
use Patchlevel\EventSourcing\Attribute\Handle;
use Patchlevel\EventSourcing\Attribute\Id;
use Patchlevel\EventSourcing\Attribute\Inject;
use Patchlevel\EventSourcing\Attribute\Snapshot;
use Patchlevel\EventSourcing\Tests\Benchmark\BasicImplementation\Command\ChangeProfileName;
use Patchlevel\EventSourcing\Tests\Benchmark\BasicImplementation\Command\CreateProfile;
use Patchlevel\EventSourcing\Tests\Benchmark\BasicImplementation\Events\NameChanged;
use Patchlevel\EventSourcing\Tests\Benchmark\BasicImplementation\Events\ProfileCreated;
use Psr\Clock\ClockInterface;

#[Aggregate('profile_with_commands')]
#[Snapshot('default', 100)]
final class ProfileWithCommands extends BasicAggregateRoot
{
#[Id]
private ProfileId $id;
private string $name;

#[Handle]
public static function create(
CreateProfile $command,
ClockInterface $clock,
#[Inject('env')]
string $env,
): self {
$self = new self();
$self->recordThat(new ProfileCreated($command->id, $command->name, null));

return $self;
}

#[Handle]
public function changeName(
ChangeProfileName $command,
ClockInterface $clock,
#[Inject('env')]
string $env,
): void {
$this->recordThat(new NameChanged($this->id, $command->name));
}

#[Apply]
protected function applyProfileCreated(ProfileCreated $event): void
{
$this->id = $event->profileId;
$this->name = $event->name;
}

#[Apply]
protected function applyNameChanged(NameChanged $event): void
{
$this->name = $event->name;
}

public function name(): string
{
return $this->name;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
use Patchlevel\EventSourcing\Subscription\Subscriber\SubscriberUtil;
use Patchlevel\EventSourcing\Tests\Benchmark\BasicImplementation\Events\NameChanged;
use Patchlevel\EventSourcing\Tests\Benchmark\BasicImplementation\Events\ProfileCreated;
use Patchlevel\EventSourcing\Tests\Benchmark\BasicImplementation\ProfileId;

#[Projector('profile')]
final class BatchProfileProjector implements BatchableSubscriber
Expand Down Expand Up @@ -53,9 +52,9 @@ public function onProfileCreated(ProfileCreated $profileCreated): void
}

#[Subscribe(NameChanged::class)]
public function onNameChanged(NameChanged $nameChanged, ProfileId $profileId): void
public function onNameChanged(NameChanged $nameChanged): void
{
$this->nameChanged[$profileId->toString()] = $nameChanged->name;
$this->nameChanged[$nameChanged->profileId->toString()] = $nameChanged->name;
}

public function table(): string
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,15 @@
namespace Patchlevel\EventSourcing\Tests\Benchmark\BasicImplementation\Projection;

use Doctrine\DBAL\Connection;
use Patchlevel\EventSourcing\Attribute\Answer;
use Patchlevel\EventSourcing\Attribute\Projector;
use Patchlevel\EventSourcing\Attribute\Setup;
use Patchlevel\EventSourcing\Attribute\Subscribe;
use Patchlevel\EventSourcing\Attribute\Teardown;
use Patchlevel\EventSourcing\Subscription\Subscriber\SubscriberUtil;
use Patchlevel\EventSourcing\Tests\Benchmark\BasicImplementation\Events\NameChanged;
use Patchlevel\EventSourcing\Tests\Benchmark\BasicImplementation\Events\ProfileCreated;
use Patchlevel\EventSourcing\Tests\Benchmark\BasicImplementation\ProfileId;
use Patchlevel\EventSourcing\Tests\Benchmark\BasicImplementation\Query\QueryProfileName;

#[Projector('profile')]
final class ProfileProjector
Expand Down Expand Up @@ -49,15 +50,24 @@ public function onProfileCreated(ProfileCreated $profileCreated): void
}

#[Subscribe(NameChanged::class)]
public function onNameChanged(NameChanged $nameChanged, ProfileId $profileId): void
public function onNameChanged(NameChanged $nameChanged): void
{
$this->connection->update(
$this->table(),
['name' => $nameChanged->name],
['id' => $profileId->toString()],
['id' => $nameChanged->profileId->toString()],
);
}

#[Answer]
public function getProfileName(QueryProfileName $queryProfileName): string
{
return $this->connection->fetchAssociative(
"SELECT name FROM {$this->table()} WHERE id = :id;",
['id' => $queryProfileName->id->toString()],
)['name'];
}

public function table(): string
{
return 'projection_' . $this->subscriberId();
Expand Down
14 changes: 14 additions & 0 deletions tests/Benchmark/BasicImplementation/Query/QueryProfileName.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php

declare(strict_types=1);

namespace Patchlevel\EventSourcing\Tests\Benchmark\BasicImplementation\Query;

use Patchlevel\EventSourcing\Tests\Benchmark\BasicImplementation\ProfileId;

final readonly class QueryProfileName
{
public function __construct(public ProfileId $id)
{
}
}
Loading
Loading