KeyValueStorage   A
last analyzed

Complexity

Total Complexity 14

Size/Duplication

Total Lines 124
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 1

Importance

Changes 0
Metric Value
wmc 14
lcom 1
cbo 1
dl 0
loc 124
rs 10
c 0
b 0
f 0

10 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A get() 0 17 2
A set() 0 11 2
A has() 0 4 1
A remove() 0 8 2
A insert() 0 10 1
A update() 0 8 1
A delete() 0 7 1
A escapeKeys() 0 9 2
A createKey() 0 4 1
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the Explicit Architecture POC,
7
 * which is created on top of the Symfony Demo application.
8
 *
9
 * (c) Herberto Graça <[email protected]>
10
 *
11
 * For the full copyright and license information, please view the LICENSE
12
 * file that was distributed with this source code.
13
 */
14
15
namespace Acme\App\Infrastructure\Persistence\Doctrine;
16
17
use Acme\App\Core\Port\Persistence\KeyValueStorageInterface;
18
use Doctrine\DBAL\Connection;
19
use Doctrine\DBAL\DBALException;
20
21
/**
22
 * @author Coen Moij
23
 * @author Marcos Loureiro
24
 * @author Kasper Agg
25
 * @author Herberto Graca <[email protected]>
26
 */
27
final class KeyValueStorage implements KeyValueStorageInterface
28
{
29
    private const TABLE = 'KeyValueStorage';
30
    private const KEY_KEY = 'key';
31
    private const VALUE_KEY = 'value';
32
33
    /**
34
     * @var Connection
35
     */
36
    private $connection;
37
38
    public function __construct(Connection $connection)
39
    {
40
        $this->connection = $connection;
41
    }
42
43
    /**
44
     * @throws DBALException
45
     */
46
    public function get(string $namespace, string $key): ?string
47
    {
48
        $query = sprintf(
49
            'SELECT `%s` FROM `%s` WHERE `%s` = :%s',
50
            self::VALUE_KEY,
51
            self::TABLE,
52
            self::KEY_KEY,
53
            self::KEY_KEY
54
        );
55
56
        $result = $this->connection->fetchColumn(
57
            $query,
58
            [self::KEY_KEY => $this->createKey($namespace, $key)]
59
        );
60
61
        return $result === false ? null : (string) $result;
62
    }
63
64
    /**
65
     * @throws DBALException
66
     */
67
    public function set(string $namespace, string $key, string $value): void
68
    {
69
        $generatedKey = $this->createKey($namespace, $key);
70
71
        if ($this->has($namespace, $key)) {
72
            $this->update($generatedKey, $value);
73
74
            return;
75
        }
76
        $this->insert($generatedKey, $value);
77
    }
78
79
    /**
80
     * @throws DBALException
81
     */
82
    public function has(string $namespace, string $key): bool
83
    {
84
        return $this->get($namespace, $key) !== null;
85
    }
86
87
    /**
88
     * @throws DBALException
89
     */
90
    public function remove(string $namespace, string $key): void
91
    {
92
        $generatedKey = $this->createKey($namespace, $key);
93
94
        if ($this->has($namespace, $key)) {
95
            $this->delete($generatedKey);
96
        }
97
    }
98
99
    /**
100
     * @throws DBALException
101
     */
102
    private function insert($key, $value): void
103
    {
104
        $this->connection->insert(
105
            self::TABLE,
106
            $this->escapeKeys([
107
                self::KEY_KEY => $key,
108
                self::VALUE_KEY => $value,
109
            ])
110
        );
111
    }
112
113
    /**
114
     * @throws DBALException
115
     */
116
    private function update($key, $value): void
117
    {
118
        $this->connection->update(
119
            self::TABLE,
120
            $this->escapeKeys([self::VALUE_KEY => $value]),
121
            $this->escapeKeys([self::KEY_KEY => $key])
122
        );
123
    }
124
125
    /**
126
     * @throws DBALException
127
     */
128
    private function delete($key): void
129
    {
130
        $this->connection->delete(
131
            self::TABLE,
132
            $this->escapeKeys([self::KEY_KEY => $key])
133
        );
134
    }
135
136
    private function escapeKeys(array $data): array
137
    {
138
        $escapedData = [];
139
        foreach ($data as $key => $value) {
140
            $escapedData["`{$key}`"] = $value;
141
        }
142
143
        return $escapedData;
144
    }
145
146
    private function createKey(string $namespace, string $key): string
147
    {
148
        return sprintf('%s_%s', $namespace, $key);
149
    }
150
}
151