SqlIndexStore::find()   A
last analyzed

Complexity

Conditions 2
Paths 1

Size

Total Lines 19
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 1
Metric Value
cc 2
eloc 9
c 1
b 0
f 1
nc 1
nop 1
dl 0
loc 19
ccs 8
cts 8
cp 1
crap 2
rs 9.9666
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\Indexes\Store;
14
15
use function Amp\call;
16
use function ServiceBus\Storage\Sql\equalsCriteria;
17
use function ServiceBus\Storage\Sql\fetchOne;
18
use function ServiceBus\Storage\Sql\find;
19
use function ServiceBus\Storage\Sql\insertQuery;
20
use function ServiceBus\Storage\Sql\remove;
21
use function ServiceBus\Storage\Sql\updateQuery;
22
use Amp\Promise;
23
use ServiceBus\EventSourcing\Indexes\IndexKey;
24
use ServiceBus\EventSourcing\Indexes\IndexValue;
25
use ServiceBus\Storage\Common\DatabaseAdapter;
26
27
/**
28
 *
29
 */
30
final class SqlIndexStore implements IndexStore
31
{
32
    private const TABLE_NAME = 'event_sourcing_indexes';
33
34
    /** @var DatabaseAdapter */
35
    private $adapter;
36
37 10
    public function __construct(DatabaseAdapter $adapter)
38
    {
39 10
        $this->adapter = $adapter;
40 10
    }
41
42
    /**
43
     * {@inheritdoc}
44
     */
45 7
    public function find(IndexKey $indexKey): Promise
46
    {
47 7
        return call(
48
            function() use ($indexKey): \Generator
49
            {
50
                $criteria = [
51 7
                    equalsCriteria('index_tag', $indexKey->indexName),
52 7
                    equalsCriteria('value_key', $indexKey->valueKey),
53
                ];
54
55
                /** @var \ServiceBus\Storage\Common\ResultSet $resultSet $resultSet */
56 7
                $resultSet = yield find($this->adapter, self::TABLE_NAME, $criteria);
57
58
                /** @var array<string, mixed>|null $result */
59 7
                $result = yield fetchOne($resultSet);
60
61 7
                if (\is_array($result))
62
                {
63 5
                    return new IndexValue($result['value_data']);
64
                }
65 7
            }
66
        );
67
    }
68
69
    /**
70
     * {@inheritdoc}
71
     */
72 9
    public function add(IndexKey $indexKey, IndexValue $value): Promise
73
    {
74 9
        return call(
75
            function() use ($indexKey, $value): \Generator
76
            {
77
                /** @var \Latitude\QueryBuilder\Query\InsertQuery $insertQuery */
78 9
                $insertQuery = insertQuery(self::TABLE_NAME, [
79 9
                    'index_tag'  => $indexKey->indexName,
80 9
                    'value_key'  => $indexKey->valueKey,
81 9
                    'value_data' => $value->value,
82
                ]);
83
84 9
                $compiledQuery = $insertQuery->compile();
85
86
                /**
87
                 * @psalm-suppress MixedTypeCoercion Invalid params() docblock
88
                 *
89
                 * @var \ServiceBus\Storage\Common\ResultSet $resultSet
90
                 */
91 9
                $resultSet = yield $this->adapter->execute($compiledQuery->sql(), $compiledQuery->params());
92
93 9
                return $resultSet->affectedRows();
94 9
            }
95
        );
96
    }
97
98
    /**
99
     * {@inheritdoc}
100
     */
101 2
    public function delete(IndexKey $indexKey): Promise
102
    {
103 2
        return call(
104
            function() use ($indexKey): \Generator
105
            {
106
                $criteria = [
107 2
                    equalsCriteria('index_tag', $indexKey->indexName),
108 2
                    equalsCriteria('value_key', $indexKey->valueKey),
109
                ];
110
111 2
                yield remove($this->adapter, self::TABLE_NAME, $criteria);
112 2
            }
113
        );
114
    }
115
116
    /**
117
     * {@inheritdoc}
118
     */
119 2
    public function update(IndexKey $indexKey, IndexValue $value): Promise
120
    {
121 2
        return call(
122
            function() use ($indexKey, $value): \Generator
123
            {
124 2
                $updateQuery = updateQuery(self::TABLE_NAME, ['value_data' => $value->value])
125 2
                    ->where(equalsCriteria('index_tag', $indexKey->indexName))
126 2
                    ->andWhere(equalsCriteria('value_key', $indexKey->valueKey));
127
128 2
                $compiledQuery = $updateQuery->compile();
129
130
                /**
131
                 * @psalm-suppress MixedTypeCoercion Invalid params() docblock
132
                 *
133
                 * @var \ServiceBus\Storage\Common\ResultSet $resultSet
134
                 */
135 2
                $resultSet = yield $this->adapter->execute($compiledQuery->sql(), $compiledQuery->params());
136
137 2
                return $resultSet->affectedRows();
138 2
            }
139
        );
140
    }
141
}
142