1 | <?php |
||
2 | |||
3 | namespace Kodus\Cache\Database; |
||
4 | |||
5 | use function count; |
||
6 | use PDO; |
||
7 | use function implode; |
||
8 | |||
9 | class MySQLAdapter extends Adapter |
||
10 | { |
||
11 | 1 | protected function createTable(): void |
|
12 | { |
||
13 | 1 | $this->unsafeExecute( |
|
14 | 1 | $this->prepare( |
|
15 | 1 | "CREATE TABLE IF NOT EXISTS `{$this->table_name}` (\n" |
|
16 | 1 | . " `key` VARCHAR(512) NOT NULL COLLATE 'latin1_bin',\n" |
|
17 | 1 | . " `data` MEDIUMBLOB NOT NULL,\n" |
|
18 | 1 | . " `expires` BIGINT NOT NULL,\n" |
|
19 | 1 | . " PRIMARY KEY (`key`),\n" |
|
20 | 1 | . " INDEX `expires` (`expires`)\n" |
|
21 | 1 | . ")" |
|
22 | ) |
||
23 | ); |
||
24 | 1 | } |
|
25 | |||
26 | 36 | public function select(string $key): ?CacheEntry |
|
27 | { |
||
28 | 36 | $statement = $this->prepare("SELECT * FROM `{$this->table_name}` WHERE `key` = :key"); |
|
29 | |||
30 | 36 | $statement->bindValue("key", $key, PDO::PARAM_STR); |
|
31 | |||
32 | 36 | $result = $this->fetch($statement); |
|
33 | |||
34 | 36 | return $result[0] ?? null; |
|
35 | } |
||
36 | |||
37 | 45 | public function upsert(array $values, int $expires): void |
|
38 | { |
||
39 | 45 | $placeholders = []; |
|
40 | |||
41 | 45 | for ($index = 0; $index < count($values); $index++) { |
|
0 ignored issues
–
show
|
|||
42 | 45 | $placeholders[] = "(:key_{$index}, :data_{$index}, :expires)"; |
|
43 | } |
||
44 | |||
45 | 45 | $statement = $this->prepare( |
|
46 | 45 | "REPLACE INTO `{$this->table_name}` (`key`, `data`, `expires`)" |
|
47 | 45 | . " VALUES " . implode(", ", $placeholders) |
|
48 | ); |
||
49 | |||
50 | 45 | $statement->bindValue("expires", $expires); |
|
51 | |||
52 | 45 | $index = 0; |
|
53 | |||
54 | 45 | foreach ($values as $key => $data) { |
|
55 | 45 | $statement->bindValue("key_{$index}", $key, PDO::PARAM_STR); |
|
56 | 45 | $statement->bindValue("data_{$index}", $data, PDO::PARAM_LOB); |
|
57 | |||
58 | 45 | $index += 1; |
|
59 | } |
||
60 | |||
61 | 45 | $this->execute($statement); |
|
62 | 45 | } |
|
63 | |||
64 | 2 | public function delete(string $key): void |
|
65 | { |
||
66 | 2 | $statement = $this->prepare("DELETE FROM `{$this->table_name}` WHERE `key` = :key"); |
|
67 | |||
68 | 2 | $statement->bindValue("key", $key, PDO::PARAM_STR); |
|
69 | |||
70 | 2 | $this->execute($statement); |
|
71 | 2 | } |
|
72 | |||
73 | 1 | public function deleteExpired(int $now): void |
|
74 | { |
||
75 | 1 | $statement = $this->prepare("DELETE FROM `{$this->table_name}` WHERE :now >= `expires`"); |
|
76 | |||
77 | 1 | $statement->bindValue("now", $now, PDO::PARAM_INT); |
|
78 | |||
79 | 1 | $this->execute($statement); |
|
80 | 1 | } |
|
81 | |||
82 | /** |
||
83 | * @param string[] $keys |
||
84 | * |
||
85 | * @return CacheEntry[] |
||
86 | */ |
||
87 | 11 | public function selectMultiple(array $keys): array |
|
88 | { |
||
89 | 11 | $placeholders = []; |
|
90 | |||
91 | 11 | for ($index=0; $index<count($keys); $index++) { |
|
0 ignored issues
–
show
It seems like you are calling the size function
count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.
If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration: for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}
// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
![]() |
|||
92 | 11 | $placeholders[] = ":key_{$index}"; |
|
93 | } |
||
94 | |||
95 | 11 | $statement = $this->prepare( |
|
96 | 11 | "SELECT * FROM `{$this->table_name}` WHERE `key` IN (" . implode(", ", $placeholders) . ")" |
|
97 | ); |
||
98 | |||
99 | 11 | foreach ($keys as $index => $key) { |
|
100 | 11 | $statement->bindValue("key_{$index}", $key, PDO::PARAM_STR); |
|
101 | } |
||
102 | |||
103 | 11 | return $this->fetch($statement); |
|
104 | } |
||
105 | |||
106 | 2 | public function deleteMultiple(array $keys): void |
|
107 | { |
||
108 | 2 | $placeholders = []; |
|
109 | |||
110 | 2 | for ($index=0; $index<count($keys); $index++) { |
|
0 ignored issues
–
show
It seems like you are calling the size function
count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.
If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration: for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}
// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
![]() |
|||
111 | 2 | $placeholders[] = ":key_{$index}"; |
|
112 | } |
||
113 | |||
114 | 2 | $statement = $this->prepare( |
|
115 | 2 | "DELETE FROM `{$this->table_name}` WHERE `key` IN (" . implode(", ", $placeholders) . ")" |
|
116 | ); |
||
117 | |||
118 | 2 | foreach ($keys as $index => $key) { |
|
119 | 2 | $statement->bindValue("key_{$index}", $key, PDO::PARAM_STR); |
|
120 | } |
||
121 | |||
122 | 2 | $this->execute($statement); |
|
123 | 2 | } |
|
124 | |||
125 | 194 | public function truncate(): void |
|
126 | { |
||
127 | 194 | $this->execute( |
|
128 | 194 | $this->prepare("TRUNCATE TABLE `{$this->table_name}`") |
|
129 | ); |
||
130 | 194 | } |
|
131 | } |
||
132 |
If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration: