Completed
Push — master ( 59f7a1...075b21 )
by Daniel
03:25
created

MySqlJsonSnapshotStore   A

Complexity

Total Complexity 9

Size/Duplication

Total Lines 103
Duplicated Lines 8.74 %

Coupling/Cohesion

Components 1
Dependencies 2

Test Coverage

Coverage 100%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 9
lcom 1
cbo 2
dl 9
loc 103
ccs 41
cts 41
cp 1
rs 10
c 1
b 0
f 0

6 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 7 1
A addSnapshot() 0 11 1
A findLastSnapshot() 0 10 2
A findNearestSnapshotToVersion() 0 11 2
A initialize() 0 14 1
A initialized() 9 9 2

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
<?php
2
3
namespace DDDominio\EventSourcing\Snapshotting\Vendor;
4
5
use DDDominio\EventSourcing\EventStore\InitializableInterface;
6
use DDDominio\EventSourcing\Serialization\SerializerInterface;
7
use DDDominio\EventSourcing\Snapshotting\SnapshotInterface;
8
use DDDominio\EventSourcing\Snapshotting\SnapshotStoreInterface;
9
10
class MySqlJsonSnapshotStore implements SnapshotStoreInterface, InitializableInterface
11
{
12
    const SNAPSHOTS_TABLE = 'snapshots';
13
14
    /**
15
     * @var \PDO
16
     */
17
    private $connection;
18
19
    /**
20
     * @var SerializerInterface
21
     */
22
    private $serializer;
23
24
    /**
25
     * @param \PDO $connection
26
     * @param SerializerInterface $serializer
27
     */
28 7
    public function __construct(
29
        \PDO $connection,
30
        SerializerInterface $serializer
31
    ) {
32 7
        $this->connection = $connection;
33 7
        $this->serializer = $serializer;
34 7
    }
35
36
    /**
37
     * @param SnapshotInterface $snapshot
38
     */
39 4
    public function addSnapshot($snapshot)
40
    {
41 4
        $stmt = $this->connection
42 4
            ->prepare('INSERT INTO snapshots (aggregate_type, aggregate_id, type, version, snapshot) VALUES (:aggregateType, :aggregateId, :type, :version, :snapshot)');
43 4
        $stmt->bindValue(':aggregateType', $snapshot->aggregateClass());
44 4
        $stmt->bindValue(':aggregateId', $snapshot->aggregateId());
45 4
        $stmt->bindValue(':type', get_class($snapshot));
46 4
        $stmt->bindValue(':version', $snapshot->version());
47 4
        $stmt->bindValue(':snapshot', $this->serializer->serialize($snapshot));
48 4
        $stmt->execute();
49 4
    }
50
51
    /**
52
     * @param string $aggregateClass
53
     * @param string $aggregateId
54
     * @return SnapshotInterface|null
55
     */
56 2
    public function findLastSnapshot($aggregateClass, $aggregateId)
57
    {
58 2
        $stmt = $this->connection
59 2
            ->prepare('SELECT type, snapshot FROM snapshots WHERE aggregate_type = :aggregateType AND aggregate_id = :aggregateId ORDER BY id DESC LIMIT 1');
60 2
        $stmt->bindValue(':aggregateType', $aggregateClass);
61 2
        $stmt->bindValue(':aggregateId', $aggregateId);
62 2
        $stmt->execute();
63 2
        $snapshot = $stmt->fetch();
64 2
        return $snapshot ? $this->serializer->deserialize($snapshot['snapshot'], $snapshot['type']) : null;
0 ignored issues
show
Bug Compatibility introduced by
The expression $snapshot ? $this->seria...apshot['type']) : null; of type object|array|null adds the type array to the return on line 64 which is incompatible with the return type declared by the interface DDDominio\EventSourcing\...rface::findLastSnapshot of type DDDominio\EventSourcing\...\SnapshotInterface|null.
Loading history...
65
    }
66
67
    /**
68
     * @param string $aggregateClass
69
     * @param string $aggregateId
70
     * @param int $version
71
     * @return SnapshotInterface|null
72
     */
73 2
    public function findNearestSnapshotToVersion($aggregateClass, $aggregateId, $version)
74
    {
75 2
        $stmt = $this->connection
76 2
            ->prepare('SELECT type, snapshot FROM snapshots WHERE aggregate_type = :aggregateType AND aggregate_id = :aggregateId AND version <= :version ORDER BY version DESC LIMIT 1');
77 2
        $stmt->bindValue(':aggregateType', $aggregateClass);
78 2
        $stmt->bindValue(':aggregateId', $aggregateId);
79 2
        $stmt->bindValue(':version', $version);
80 2
        $stmt->execute();
81 2
        $snapshot = $stmt->fetch();
82 2
        return $snapshot ? $this->serializer->deserialize($snapshot['snapshot'], $snapshot['type']) : null;
0 ignored issues
show
Bug Compatibility introduced by
The expression $snapshot ? $this->seria...apshot['type']) : null; of type object|array|null adds the type array to the return on line 82 which is incompatible with the return type declared by the interface DDDominio\EventSourcing\...earestSnapshotToVersion of type DDDominio\EventSourcing\...\SnapshotInterface|null.
Loading history...
83
    }
84
85 7
    public function initialize()
86
    {
87 7
        $this->connection->exec(
88 7
            'CREATE TABLE `'.self::SNAPSHOTS_TABLE.'` (
89
                `id` int(11) NOT NULL AUTO_INCREMENT,
90
                `aggregate_type` varchar(255) NOT NULL,
91
                `aggregate_id` varchar(255) NOT NULL,
92
                `type` varchar(255) NOT NULL,
93
                `version` int(11) NOT NULL,
94
                `snapshot` json NOT NULL,
95
                PRIMARY KEY (`id`)
96 7
            )'
97
        );
98 7
    }
99
100
    /**
101
     * @return bool
102
     */
103 3 View Code Duplication
    public function initialized()
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...
104
    {
105
        try {
106 3
            $result = $this->connection->query('SELECT 1 FROM `'.self::SNAPSHOTS_TABLE.'` LIMIT 1');
107 1
        } catch (\Exception $e) {
108 1
            return false;
109
        }
110 2
        return $result !== false;
111
    }
112
}
113