Completed
Push — master ( efb36f...19228d )
by David
02:15
created

InMemoryEventStore::getClassForKey()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 6
ccs 3
cts 3
cp 1
rs 9.4286
cc 1
eloc 3
nc 1
nop 1
crap 1
1
<?php
2
3
namespace Rawkode\Eidetic\EventStore\InMemoryEventStore;
4
5
use Rawkode\Eidetic\EventStore\InvalidEventException;
6
use Rawkode\Eidetic\EventStore\EventStore;
7
use Rawkode\Eidetic\EventStore\EventPublisherMixin;
8
use Rawkode\Eidetic\EventStore\NoEventsFoundForKeyException;
9
use Rawkode\Eidetic\EventStore\Subscriber;
10
use Rawkode\Eidetic\EventStore\VerifyEventIsAClassTrait;
11
use Rawkode\Eidetic\EventStore\InMemoryEventStore\TransactionAlreadyInProgressException;
12
use Rawkode\Eidetic\EventStore\EventPublisher;
13
use Doctrine\Common\EventSubscriber;
14
15
final class InMemoryEventStore implements EventStore
16
{
17
    use EventPublisherMixin;
18
    use VerifyEventIsAClassTrait;
19
20
    /**
21
     * @var int
22
     */
23
    private $serialNumber = 0;
24
25
    /**
26
     * @var array
27
     */
28
    private $events = [];
29
30
    /**
31
     * @var array
32
     */
33
    private $transactionBackup = [];
34
35
    /**
36
     * @var array
37
     */
38
    private $stagedEvents = [];
39
40
    /**
41
     * @param string $key
42
     *
43
     * @return array
44
     */
45 2
    public function retrieve($key)
46
    {
47 2
        $eventLogs = $this->eventLogs($key);
48
49 1
        return array_map(function ($eventLog) {
50 1
            return $eventLog['event'];
51 1
        }, $eventLogs);
52
    }
53
54
    /**
55
     * @param string $key
56
     *
57
     * @return array
58
     */
59 1
    public function retrieveLogs($key)
60
    {
61 1
        return $this->eventLogs($key);
62
    }
63
64
    /**
65
     * @param string $key
66
     *
67
     * @throws NoEventsFoundForKeyException
68
     *
69
     * @return array
70
     */
71 3
    private function eventLogs($key)
72
    {
73 3
        $this->verifyEventExistsForKey($key);
74
75 2
        return $this->events[$key];
76
    }
77
78
    /**
79
     * @param string $key
80
     * @param array $events
81
     *
82
     * @throws TransactionAlreadyInProgressException
83
     * @throws InvalidEventException
84
     */
85 5 View Code Duplication
    public function store($key, array $events)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
86
    {
87
        try {
88 5
            $this->startTransaction();
89
90 5
            foreach ($events as $event) {
91 5
                $this->persistEvent($key, $event);
92 5
            }
93 5
        } catch (InvalidEventException $invalidEventException) {
94 2
            $this->abortTransaction();
95
96 2
            throw $invalidEventException;
97
        }
98
99 4
        $this->completeTransaction();
100 4
    }
101
102
    /**
103
     * @throws TransactionAlreadyInProgressException
104
     */
105 5
    private function startTransaction()
106
    {
107 5
        $this->transactionBackup = $this->events;
108 5
        $this->stagedEvents = [];
109 5
    }
110
111
    /**
112
     */
113 2
    private function abortTransaction()
114
    {
115 2
        $this->events = $this->transactionBackup;
116 2
        $this->stagedEvents = [];
117 2
    }
118
119
    /**
120
     */
121 4
    private function completeTransaction()
122
    {
123 4
        $this->transactionBackup = [];
124
125 4
        foreach ($this->stagedEvents as $event) {
126 4
            $this->publish(self::EVENT_STORED, $event);
127 4
        }
128
129 4
        $this->stagedEvents = [];
130 4
    }
131
132
    /**
133
     * @param string $key
134
     * @param  $event
135
     *
136
     * @throws InvalidEventException
137
     */
138 5
    private function persistEvent($key, $event)
139
    {
140 5
        $this->verifyEventIsAClass($event);
141
142 5
        $this->events[$key][] = [
143 5
            'serial_number' => ++$this->serialNumber,
144 5
            'key' => $key,
145 5
            'recorded_at' => new \DateTime('now', new \DateTimeZone('UTC')),
146 5
            'event_class' => get_class($event),
147 5
            'event' => $event,
148
        ];
149
150 5
        array_push($this->stagedEvents, $event);
151 5
    }
152
153
    /**
154
     * @param $key
155
     * @throws NoEventsFoundForKeyException
156
     */
157 3
    private function verifyEventExistsForKey($key)
158
    {
159 3
        if (false === array_key_exists($key, $this->events)) {
160 1
            throw new NoEventsFoundForKeyException();
161
        }
162 2
    }
163
}
164