Passed
Push — v3.3 ( 1e1106...84677f )
by Masiukevich
03:38 queued 10s
created

SqlSnapshotStore::load()   A

Complexity

Conditions 5
Paths 1

Size

Total Lines 53
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 18
CRAP Score 5

Importance

Changes 6
Bugs 1 Features 0
Metric Value
cc 5
eloc 18
c 6
b 1
f 0
nc 1
nop 1
dl 0
loc 53
ccs 18
cts 18
cp 1
crap 5
rs 9.3554

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/**
4
 * Event Sourcing implementation.
5
 *
6
 * @author  Maksim Masiukevich <[email protected]>
7
 * @license MIT
8
 * @license https://opensource.org/licenses/MIT
9
 */
10
11
declare(strict_types = 1);
12
13
namespace ServiceBus\EventSourcing\Snapshots\Store;
14
15
use function Amp\call;
16
use function ServiceBus\Common\datetimeToString;
17
use function ServiceBus\Storage\Sql\equalsCriteria;
18
use function ServiceBus\Storage\Sql\fetchOne;
19
use function ServiceBus\Storage\Sql\find;
20
use function ServiceBus\Storage\Sql\insertQuery;
21
use function ServiceBus\Storage\Sql\remove;
22
use Amp\Promise;
23
use ServiceBus\EventSourcing\AggregateId;
24
use ServiceBus\EventSourcing\Snapshots\Snapshot;
25
use ServiceBus\Storage\Common\BinaryDataDecoder;
26
use ServiceBus\Storage\Common\DatabaseAdapter;
27
28
/**
29
 *
30
 */
31
final class SqlSnapshotStore implements SnapshotStore
32
{
33
    private const TABLE_NAME = 'event_store_snapshots';
34
35
    /**
36
     * @var DatabaseAdapter
37
     */
38
    private $adapter;
39
40
    /**
41
     * @param DatabaseAdapter $adapter
42
     */
43 8
    public function __construct(DatabaseAdapter $adapter)
44
    {
45 8
        $this->adapter = $adapter;
46 8
    }
47
48
    /**
49
     * {@inheritdoc}
50
     */
51 7
    public function save(Snapshot $snapshot): Promise
52
    {
53 7
        $adapter = $this->adapter;
54
55
        /** @psalm-suppress InvalidArgument Incorrect psalm unpack parameters (...$args) */
56 7
        return call(
57
            static function(Snapshot $snapshot) use ($adapter): \Generator
58
            {
59 7
                $insertQuery = insertQuery(self::TABLE_NAME, [
60 7
                    'id'                 => $snapshot->aggregate->id()->toString(),
61 7
                    'aggregate_id_class' => \get_class($snapshot->aggregate->id()),
62 7
                    'aggregate_class'    => \get_class($snapshot->aggregate),
63 7
                    'version'            => $snapshot->aggregate->version(),
64 7
                    'payload'            => \base64_encode(\serialize($snapshot)),
65 7
                    'created_at'         => datetimeToString($snapshot->aggregate->getCreatedAt()),
66
                ]);
67
68 7
                $compiledQuery = $insertQuery->compile();
69
70
                /** @psalm-suppress MixedTypeCoercion Invalid params() docblock */
71 7
                yield $adapter->execute($compiledQuery->sql(), $compiledQuery->params());
72 7
            },
73 7
            $snapshot
74
        );
75
    }
76
77
    /**
78
     * @psalm-suppress MixedTypeCoercion Incorrect resolving the value of the promise
79
     *
80
     * {@inheritdoc}
81
     */
82 7
    public function load(AggregateId $id): Promise
83
    {
84 7
        $adapter = $this->adapter;
85
86
        /** @psalm-suppress InvalidArgument Incorrect psalm unpack parameters (...$args) */
87 7
        return call(
88
            static function(AggregateId $id) use ($adapter): \Generator
89
            {
90 7
                $storedSnapshot = null;
91
92
                $criteria = [
93 7
                    equalsCriteria('id', $id->toString()),
94 7
                    equalsCriteria('aggregate_id_class', \get_class($id)),
95
                ];
96
97
                /** @var \ServiceBus\Storage\Common\ResultSet $resultSet */
98 7
                $resultSet = yield find($adapter, self::TABLE_NAME, $criteria);
99
100
                /**
101
                 * @psalm-var      array{
102
                 *   id: string,
103
                 *   aggregate_id_class: string,
104
                 *   aggregate_class: string,
105
                 *   version: int,
106
                 *   payload:string,
107
                 *   created_at: string
108
                 * }|null $data
109
                 *
110
                 * @var array<string, string>|null $data
111
                 */
112 7
                $data = yield fetchOne($resultSet);
113
114 7
                if (true === \is_array($data) && 0 !== \count($data))
115
                {
116 5
                    $payload = $data['payload'];
117
118 5
                    if ($adapter instanceof BinaryDataDecoder)
0 ignored issues
show
introduced by
$adapter is always a sub-type of ServiceBus\Storage\Common\BinaryDataDecoder.
Loading history...
119
                    {
120 5
                        $payload = $adapter->unescapeBinary($payload);
121
                    }
122
123 5
                    $snapshotContent = (string) \base64_decode($payload);
124
125 5
                    if ('' !== $snapshotContent)
126
                    {
127
                        /** @var Snapshot $storedSnapshot */
128 5
                        $storedSnapshot = \unserialize($snapshotContent, ['allowed_classes' => true]);
129
                    }
130
                }
131
132 7
                return $storedSnapshot;
133 7
            },
134 7
            $id
135
        );
136
    }
137
138
    /**
139
     * {@inheritdoc}
140
     */
141 7
    public function remove(AggregateId $id): Promise
142
    {
143 7
        $adapter = $this->adapter;
144
145
        /** @psalm-suppress InvalidArgument Incorrect psalm unpack parameters (...$args) */
146 7
        return call(
147
            static function(AggregateId $id) use ($adapter): \Generator
148
            {
149
                $criteria = [
150 7
                    equalsCriteria('id', $id->toString()),
151 7
                    equalsCriteria('aggregate_id_class', \get_class($id)),
152
                ];
153
154 7
                yield remove($adapter, self::TABLE_NAME, $criteria);
155 7
            },
156 7
            $id
157
        );
158
    }
159
}
160