Skip to content

Commit

Permalink
Merge pull request #215 from patchlevel/improve-snapshot-store-apis
Browse files Browse the repository at this point in the history
improve snapshot store related apis
  • Loading branch information
DanielBadura authored Apr 21, 2022
2 parents 7f6c5e3 + 520fbc8 commit d3d011a
Show file tree
Hide file tree
Showing 8 changed files with 88 additions and 16 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ psalm-baseline: vendor

.PHONY: phpunit
phpunit: vendor ## run phpunit tests
vendor/bin/phpunit --testdox --colors=always -v $(OPTIONS)
vendor/bin/phpunit --colors=always -v $(OPTIONS)

.PHONY: infection
infection: vendor ## run infection
Expand Down
1 change: 0 additions & 1 deletion phpunit.xml.dist
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
</include>
<report>
<html outputDirectory="./coverage"/>
<text outputFile="php://stdout"/>
</report>
</coverage>

Expand Down
13 changes: 7 additions & 6 deletions src/Aggregate/AggregateRoot.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ abstract public function aggregateRootId(): string;

protected function apply(object $event): void
{
$metadata = self::metadata(static::class);
$metadata = self::metadata();

if (!array_key_exists($event::class, $metadata->applyMethods)) {
if (!$metadata->suppressAll && !array_key_exists($event::class, $metadata->suppressEvents)) {
Expand Down Expand Up @@ -93,16 +93,17 @@ final public function playhead(): int
return $this->playhead;
}

/**
* @param class-string<self> $aggregateClass
*/
public static function metadata(string $aggregateClass): AggregateRootMetadata
public static function metadata(): AggregateRootMetadata
{
if (static::class === self::class) {
throw new MetadataNotPossible();
}

if (!self::$metadataFactory) {
self::$metadataFactory = new AttributeAggregateRootMetadataFactory();
}

return self::$metadataFactory->metadata($aggregateClass);
return self::$metadataFactory->metadata(static::class);
}

public static function setMetadataFactory(AggregateRootMetadataFactory $metadataFactory): void
Expand Down
13 changes: 13 additions & 0 deletions src/Aggregate/MetadataNotPossible.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php

declare(strict_types=1);

namespace Patchlevel\EventSourcing\Aggregate;

class MetadataNotPossible extends AggregateException
{
public function __construct()
{
parent::__construct('Metadata method must be called on the concrete implementation');
}
}
20 changes: 20 additions & 0 deletions src/Snapshot/AdapterNotFound.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

declare(strict_types=1);

namespace Patchlevel\EventSourcing\Snapshot;

use function sprintf;

final class AdapterNotFound extends SnapshotException
{
public function __construct(string $adapterName)
{
parent::__construct(
sprintf(
'adapter with the name "%s" not found',
$adapterName,
)
);
}
}
21 changes: 13 additions & 8 deletions src/Snapshot/DefaultSnapshotStore.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use Patchlevel\EventSourcing\Snapshot\Adapter\SnapshotAdapter;
use Throwable;

use function array_key_exists;
use function sprintf;

final class DefaultSnapshotStore implements SnapshotStore
Expand Down Expand Up @@ -35,7 +36,7 @@ public function save(Snapshot $snapshot): void
return;
}

$adapter = $this->getAdapter($aggregateClass);
$adapter = $this->adapter($aggregateClass);

$adapter->save(
$key,
Expand All @@ -53,7 +54,7 @@ public function save(Snapshot $snapshot): void
*/
public function load(string $aggregateClass, string $id): Snapshot
{
$adapter = $this->getAdapter($aggregateClass);
$adapter = $this->adapter($aggregateClass);
$key = $this->key($aggregateClass, $id);

try {
Expand All @@ -80,31 +81,35 @@ public function freeMemory(): void
/**
* @param class-string<AggregateRoot> $aggregateClass
*/
private function getAdapter(string $aggregateClass): SnapshotAdapter
public function adapter(string $aggregateClass): SnapshotAdapter
{
$snapshotName = $aggregateClass::metadata($aggregateClass)->snapshotStore;
$adapterName = $aggregateClass::metadata()->snapshotStore;

if (!$snapshotName) {
if (!$adapterName) {
throw new SnapshotNotConfigured($aggregateClass);
}

return $this->snapshotAdapters[$snapshotName];
if (!array_key_exists($adapterName, $this->snapshotAdapters)) {
throw new AdapterNotFound($adapterName);
}

return $this->snapshotAdapters[$adapterName];
}

/**
* @param class-string<AggregateRoot> $aggregateClass
*/
private function key(string $aggregateClass, string $aggregateId): string
{
$aggregateName = $aggregateClass::metadata($aggregateClass)->name;
$aggregateName = $aggregateClass::metadata()->name;

return sprintf('%s-%s', $aggregateName, $aggregateId);
}

private function shouldBeSaved(Snapshot $snapshot, string $key): bool
{
$aggregateClass = $snapshot->aggregate();
$batchSize = $aggregateClass::metadata($snapshot->aggregate())->snapshotBatch;
$batchSize = $aggregateClass::metadata()->snapshotBatch;

if (!$batchSize) {
return true;
Expand Down
17 changes: 17 additions & 0 deletions tests/Unit/Aggregate/AggregateRootTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,12 @@
namespace Patchlevel\EventSourcing\Tests\Unit\Aggregate;

use DateTimeImmutable;
use Patchlevel\EventSourcing\Aggregate\AggregateRoot;
use Patchlevel\EventSourcing\Aggregate\ApplyMethodNotFound;
use Patchlevel\EventSourcing\Aggregate\MetadataNotPossible;
use Patchlevel\EventSourcing\Clock;
use Patchlevel\EventSourcing\EventBus\Message as EventBusMessage;
use Patchlevel\EventSourcing\Metadata\AggregateRoot\AggregateRootMetadata;
use Patchlevel\EventSourcing\Metadata\AggregateRoot\DuplicateApplyMethod;
use Patchlevel\EventSourcing\Tests\Unit\Fixture\Email;
use Patchlevel\EventSourcing\Tests\Unit\Fixture\Message;
Expand Down Expand Up @@ -183,4 +186,18 @@ public function testDuplicateApplyMethods(): void

ProfileInvalid::createProfile($profileId, $email);
}

public function testMetadata(): void
{
$metadata = Profile::metadata();

self::assertInstanceOf(AggregateRootMetadata::class, $metadata);
}

public function testMetadataNotPossible(): void
{
$this->expectException(MetadataNotPossible::class);

AggregateRoot::metadata();
}
}
17 changes: 17 additions & 0 deletions tests/Unit/Snapshot/DefaultSnapshotStoreTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
namespace Patchlevel\EventSourcing\Tests\Unit\Snapshot;

use Patchlevel\EventSourcing\Snapshot\Adapter\SnapshotAdapter;
use Patchlevel\EventSourcing\Snapshot\AdapterNotFound;
use Patchlevel\EventSourcing\Snapshot\DefaultSnapshotStore;
use Patchlevel\EventSourcing\Snapshot\Snapshot;
use Patchlevel\EventSourcing\Tests\Unit\Fixture\ProfileWithSnapshot;
Expand Down Expand Up @@ -157,4 +158,20 @@ public function testFreeMemory(): void
$store->freeMemory();
$store->save($newSnapshot);
}

public function testAdapterIsMissing(): void
{
$this->expectException(AdapterNotFound::class);

$store = new DefaultSnapshotStore([]);
$store->load(ProfileWithSnapshot::class, '1');
}

public function testGetAdapter(): void
{
$adapter = $this->prophesize(SnapshotAdapter::class)->reveal();
$store = new DefaultSnapshotStore(['memory' => $adapter]);

self::assertSame($adapter, $store->adapter(ProfileWithSnapshot::class));
}
}

0 comments on commit d3d011a

Please sign in to comment.