Skip to content

Commit

Permalink
Merge pull request #362 from soarecostin/replay_command
Browse files Browse the repository at this point in the history
Update event-sourcing:replay command to work with just one aggregate uuid
  • Loading branch information
freekmurze authored Aug 22, 2022
2 parents 33c7700 + c4eaa1f commit 522ce18
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 8 deletions.
6 changes: 6 additions & 0 deletions docs/advanced-usage/replaying-events.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,12 @@ If you are [using your own event storage model](/laravel-event-sourcing/v4/advan
php artisan event-sourcing:replay --stored-event-model=App\\Models\\AccountStoredEvent
```

If you only want to reply events for a specific aggregate only, you can use the `--aggregate-uuid` option.

```bash
php artisan event-sourcing:replay --aggregate-uuid=12345678-1234-1234-1234-1234567890ab
```

## Detecting event replays

If your projector contains an `onStartingEventReplay` method, we'll call it right before the first event is replayed.
Expand Down
11 changes: 6 additions & 5 deletions src/Console/ReplayCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ class ReplayCommand extends Command
{
protected $signature = 'event-sourcing:replay {projector?*}
{--from=0 : Replay events starting from this event number}
{--stored-event-model= : Replay events from this store}';
{--stored-event-model= : Replay events from this store}
{--aggregate-uuid= : Replay events for this aggregate only}';

protected $description = 'Replay stored events';

Expand All @@ -30,7 +31,7 @@ public function handle(Projectionist $projectionist): void
return;
}

$this->replay($projectors, (int)$this->option('from'));
$this->replay($projectors, (int)$this->option('from'), $this->option('aggregate-uuid'));
}

public function selectProjectors(array $projectorClassNames): ?Collection
Expand All @@ -54,10 +55,10 @@ public function selectProjectors(array $projectorClassNames): ?Collection
});
}

public function replay(Collection $projectors, int $startingFrom): void
public function replay(Collection $projectors, int $startingFrom, ?string $aggregateUuid = null): void
{
$repository = app(StoredEventRepository::class);
$replayCount = $repository->countAllStartingFrom($startingFrom);
$replayCount = $repository->countAllStartingFrom($startingFrom, $aggregateUuid);

if ($replayCount === 0) {
$this->warn('There are no events to replay');
Expand All @@ -72,7 +73,7 @@ public function replay(Collection $projectors, int $startingFrom): void
$bar->advance();
};

$this->projectionist->replay($projectors, $startingFrom, $onEventReplayed);
$this->projectionist->replay($projectors, $startingFrom, $onEventReplayed, $aggregateUuid);

$bar->finish();

Expand Down
5 changes: 3 additions & 2 deletions src/Projectionist.php
Original file line number Diff line number Diff line change
Expand Up @@ -319,7 +319,8 @@ public function isReplaying(): bool
public function replay(
Collection $projectors,
int $startingFromEventId = 0,
callable $onEventReplayed = null
callable $onEventReplayed = null,
?string $aggregateUuid = null
): void {
$projectors = new EventHandlerCollection($projectors);

Expand All @@ -338,7 +339,7 @@ public function replay(
$projectors->call('onStartingEventReplay');

app(StoredEventRepository::class)
->retrieveAllStartingFrom($startingFromEventId)
->retrieveAllStartingFrom($startingFromEventId, $aggregateUuid)
->each(function (StoredEvent $storedEvent) use ($projectors, $onEventReplayed) {
$this->applyStoredEventToProjectors(
$storedEvent,
Expand Down
32 changes: 31 additions & 1 deletion tests/Console/ReplayCommandTest.php
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
<?php

namespace Spatie\EventSourcing\Console;
namespace Spatie\EventSourcing\Tests\Console;

use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Facades\Event;
use Illuminate\Support\Facades\Mail;
use Ramsey\Uuid\Uuid;
use Spatie\EventSourcing\Events\FinishedEventReplay;
use Spatie\EventSourcing\Events\StartingEventReplay;
use Spatie\EventSourcing\Facades\Projectionist;
use Spatie\EventSourcing\StoredEvents\Models\EloquentStoredEvent;
use Spatie\EventSourcing\Tests\TestCase;
use Spatie\EventSourcing\Tests\TestClasses\AggregateRoots\AccountAggregateRoot;
use Spatie\EventSourcing\Tests\TestClasses\AggregateRoots\AccountAggregateRootWithStoredEventRepositorySpecified;
use Spatie\EventSourcing\Tests\TestClasses\AggregateRoots\Projectors\AccountProjector;
use Spatie\EventSourcing\Tests\TestClasses\Events\MoneyAddedEvent;
use Spatie\EventSourcing\Tests\TestClasses\Events\MoneySubtractedEvent;
use Spatie\EventSourcing\Tests\TestClasses\Mailables\AccountBroke;
Expand Down Expand Up @@ -131,4 +134,31 @@ public function it_will_replay_events_from_a_specific_store()
->expectsOutput('Replaying 5 events...')
->assertExitCode(0);
}

/** @test */
public function it_will_replay_events_for_a_specific_aggregate_root_uuid()
{
EloquentStoredEvent::truncate();

$uuid1 = Uuid::uuid4();
$account1 = AccountAggregateRoot::retrieve($uuid1);
$account1->addMoney(1000);
$account1->persist();

$uuid2 = Uuid::uuid4();
$account2 = AccountAggregateRoot::retrieve($uuid2);
$account2->addMoney(1000);
$account2->persist();

$projector = app(AccountProjector::class);

Projectionist::addProjector($projector);

$this->artisan('event-sourcing:replay', [
'projector' => [AccountProjector::class],
'--aggregate-uuid' => $uuid1
])
->expectsOutput('Replaying 1 events...')
->assertExitCode(0);
}
}

0 comments on commit 522ce18

Please sign in to comment.