ConstructingAggregateRootRepositoryWithSnapshotting   A
last analyzed

Complexity

Total Complexity 9

Size/Duplication

Total Lines 61
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 7
Bugs 0 Features 0
Metric Value
eloc 16
dl 0
loc 61
ccs 22
cts 22
cp 1
rs 10
c 7
b 0
f 0
wmc 9

7 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 6 1
A retrieve() 0 3 1
A retrieveAllEventsAfterVersion() 0 10 2
A persist() 0 3 1
A persistEvents() 0 3 1
A storeSnapshot() 0 4 1
A retrieveFromSnapshot() 0 14 2
1
<?php
2
3
declare(strict_types=1);
4
5
namespace EventSauce\EventSourcing\Snapshotting;
6
7
use EventSauce\EventSourcing\AggregateRootId;
8
use EventSauce\EventSourcing\AggregateRootRepository;
9
use EventSauce\EventSourcing\Message;
10
use EventSauce\EventSourcing\MessageRepository;
11
use Generator;
12
13
/**
14
 * @template T of AggregateRootWithSnapshotting
15
 *
16
 * @template-implements AggregateRootRepositoryWithSnapshotting<T>
17
 */
18
final class ConstructingAggregateRootRepositoryWithSnapshotting implements AggregateRootRepositoryWithSnapshotting
19
{
20
    /**
21
     * @phpstan-param class-string<T> $regularRepository
22
     * @phpstan-param AggregateRootRepository<T> $regularRepository
23
     */
24
    public function __construct(
25
        private string $aggregateRootClassName,
26
        private MessageRepository $messageRepository,
27
        private SnapshotRepository $snapshotRepository,
28
        private AggregateRootRepository $regularRepository
29
    ) {
30
    }
31
32
    public function retrieveFromSnapshot(AggregateRootId $aggregateRootId): object
33
    {
34
        $snapshot = $this->snapshotRepository->retrieve($aggregateRootId);
35 1
36
        if ( ! $snapshot instanceof Snapshot) {
37
            return $this->retrieve($aggregateRootId);
38
        }
39
40
        /** @phpstan-var T $className */
41 1
        /** @var AggregateRootWithSnapshotting $className */
42 1
        $className = $this->aggregateRootClassName;
43 1
        $events = $this->retrieveAllEventsAfterVersion($aggregateRootId, $snapshot->aggregateRootVersion());
44 1
45 1
        return $className::reconstituteFromSnapshotAndEvents($snapshot, $events);
46
    }
47 1
48
    public function storeSnapshot(AggregateRootWithSnapshotting $aggregateRoot): void
49 1
    {
50
        $snapshot = $aggregateRoot->createSnapshot();
51 1
        $this->snapshotRepository->persist($snapshot);
52 1
    }
53
54
    private function retrieveAllEventsAfterVersion(AggregateRootId $aggregateRootId, int $version): Generator
55
    {
56 1
        /** @var Message[]|Generator $messages */
57 1
        $messages = $this->messageRepository->retrieveAllAfterVersion($aggregateRootId, $version);
58
59 1
        foreach ($messages as $message) {
60
            yield $message->event();
61
        }
62 1
63
        return $messages->getReturn();
64 1
    }
65 1
66 1
    public function retrieve(AggregateRootId $aggregateRootId): object
67
    {
68 1
        return $this->regularRepository->retrieve($aggregateRootId);
69
    }
70
71 1
    public function persist(object $aggregateRoot): void
72
    {
73 1
        $this->regularRepository->persist($aggregateRoot);
74 1
    }
75
76
    public function persistEvents(AggregateRootId $aggregateRootId, int $aggregateRootVersion, object ...$events): void
77 1
    {
78
        $this->regularRepository->persistEvents($aggregateRootId, $aggregateRootVersion, ...$events);
79
    }
80
}
81