Completed
Pull Request — master (#46)
by Klaus
09:50
created

MysqlAdapter::validateConnectionOptions()   B

Complexity

Conditions 7
Paths 7

Size

Total Lines 21

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 21
rs 8.6506
c 0
b 0
f 0
cc 7
nc 7
nop 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Linio\Component\Cache\Adapter;
6
7
use Linio\Component\Cache\Exception\InvalidConfigurationException;
8
use Linio\Component\Cache\Exception\KeyNotFoundException;
9
use Linio\Component\Database\DatabaseManager;
10
11
class MysqlAdapter extends AbstractAdapter implements AdapterInterface
12
{
13
    protected DatabaseManager $dbManager;
0 ignored issues
show
Bug introduced by
This code did not parse for me. Apparently, there is an error somewhere around this line:

Syntax error, unexpected T_STRING, expecting T_FUNCTION or T_CONST
Loading history...
14
    protected string $tableName;
15
16
    public function __construct(array $config = [])
17
    {
18
        $this->validateConnectionOptions($config);
19
        $connectionOptions = $this->getConnectionOptions($config);
20
21
        if (isset($config['cache_not_found_keys'])) {
22
            $this->cacheNotFoundKeys = (bool) $config['cache_not_found_keys'];
23
        }
24
25
        $dbManager = new DatabaseManager();
26
        $dbManager->addConnection(DatabaseManager::DRIVER_MYSQL, $connectionOptions);
27
28
        $this->setDbManager($dbManager);
29
        $this->setTableName($config['table_name']);
30
31
        $this->checkTableCreated($config);
32
    }
33
34
    public function setDbManager(DatabaseManager $dbManager): void
35
    {
36
        $this->dbManager = $dbManager;
37
    }
38
39
    public function setTableName(string $tableName): void
40
    {
41
        $this->tableName = $tableName;
42
    }
43
44
    /**
45
     * @return mixed
46
     */
47
    public function get(string $key)
48
    {
49
        $sql = sprintf('SELECT `value` FROM `%s` WHERE `key` = :key LIMIT 1', $this->tableName);
50
51
        $results = $this->dbManager->fetchColumn($sql, ['key' => $this->addNamespaceToKey($key)], 0);
52
53
        if (!$results) {
54
            throw new KeyNotFoundException();
55
        }
56
57
        return $results[0];
58
    }
59
60
    public function getMulti(array $keys): array
61
    {
62
        $placeholders = array_fill(1, count($keys), '?');
63
        $sql = sprintf('SELECT `key`, `value` FROM `%s` WHERE `key` IN(%s)', $this->tableName, implode(',', $placeholders));
64
65
        $namespacedKeys = $this->addNamespaceToKeys($keys);
66
        $namespacedData = $this->dbManager->fetchKeyPairs($sql, $namespacedKeys);
67
68
        return $this->removeNamespaceFromKeys($namespacedData);
69
    }
70
71
    /**
72
     * @param mixed $value
73
     */
74
    public function set(string $key, $value): bool
75
    {
76
        $sql = sprintf('INSERT INTO `%s` (`key`, `value`) VALUES(:key, :value) ON DUPLICATE KEY UPDATE `value` = VALUES(`value`)', $this->tableName);
77
78
        $this->dbManager->execute($sql, ['key' => $this->addNamespaceToKey($key), 'value' => $value]);
79
80
        return true;
81
    }
82
83
    public function setMulti(array $data): bool
84
    {
85
        $placeholders = [];
86
        $keyValues = [];
87
        foreach ($data as $key => $value) {
88
            $placeholders[] = '(?, ?)';
89
            $keyValues[] = $this->addNamespaceToKey($key);
90
            $keyValues[] = $value;
91
        }
92
93
        $sql = sprintf(
94
            'INSERT INTO `%s` (`key`, `value`) VALUES %s ON DUPLICATE KEY UPDATE `value` = VALUES(`value`)',
95
            $this->tableName,
96
            implode(',', $placeholders)
97
        );
98
99
        $this->dbManager->execute($sql, $keyValues);
100
101
        return true;
102
    }
103
104
    public function contains(string $key): bool
105
    {
106
        try {
107
            $this->get($key);
108
        } catch (KeyNotFoundException $e) {
109
            return false;
110
        }
111
112
        return true;
113
    }
114
115
    public function delete(string $key): bool
116
    {
117
        $sql = sprintf('DELETE FROM `%s` WHERE `key` = :key', $this->tableName);
118
119
        $this->dbManager->execute($sql, ['key' => $this->addNamespaceToKey($key)]);
120
121
        return true;
122
    }
123
124
    public function deleteMulti(array $keys): bool
125
    {
126
        $placeholders = array_fill(1, count($keys), '?');
127
        $sql = sprintf('DELETE FROM `%s` WHERE `key` IN (%s)', $this->tableName, implode(',', $placeholders));
128
129
        $namespacedKeys = $this->addNamespaceToKeys($keys);
130
        $this->dbManager->execute($sql, $namespacedKeys);
131
132
        return true;
133
    }
134
135
    public function flush(): bool
136
    {
137
        $sql = sprintf('DELETE FROM `%s`', $this->tableName);
138
139
        $this->dbManager->execute($sql);
140
141
        return true;
142
    }
143
144
    /**
145
     * @throws InvalidConfigurationException
146
     */
147
    protected function validateConnectionOptions(array $config): void
148
    {
149
        if (!isset($config['host'])) {
150
            throw new InvalidConfigurationException('Missing configuration parameter: host');
151
        }
152
153
        if (!isset($config['port'])) {
154
            throw new InvalidConfigurationException('Missing configuration parameter: port');
155
        }
156
157
        if (!isset($config['dbname'])) {
158
            throw new InvalidConfigurationException('Missing configuration parameter: dbname');
159
        }
160
161
        if (!isset($config['username'])) {
162
            throw new InvalidConfigurationException('Missing configuration parameter: username');
163
        }
164
165
        if (!isset($config['password'])) {
166
            throw new InvalidConfigurationException('Missing configuration parameter: password');
167
        }
168
169
        if (!isset($config['table_name'])) {
170
            throw new InvalidConfigurationException('Missing configuration parameter: table_name');
171
        }
172
    }
173
174
    protected function checkTableCreated(array $config): void
175
    {
176
        if (!isset($config['ensure_table_created'])) {
177
            $this->dbManager->execute(
178
                'CREATE TABLE IF NOT EXISTS `key_value` (`key` varchar(255) NOT NULL, `value` varchar(10000) DEFAULT NULL, PRIMARY KEY (`key`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;'
179
            );
180
        }
181
    }
182
183
    protected function getConnectionOptions(array $config): array
184
    {
185
        return [
186
            'host' => $config['host'],
187
            'port' => $config['port'],
188
            'dbname' => $config['dbname'],
189
            'username' => $config['username'],
190
            'password' => $config['password'],
191
        ];
192
    }
193
}
194