1 | <?php |
||
2 | |||
3 | namespace Kodus\Cache\Database; |
||
4 | |||
5 | use function count; |
||
6 | use PDO; |
||
7 | use function implode; |
||
8 | |||
9 | class PostgreSQLAdapter extends Adapter |
||
10 | { |
||
11 | 1 | protected function createTable(): void |
|
12 | { |
||
13 | 1 | $this->unsafeExecute( |
|
14 | 1 | $this->prepare( |
|
15 | 1 | "CREATE TABLE {$this->table_name} (\n" |
|
16 | 1 | . " key CHARACTER VARYING NOT NULL PRIMARY KEY,\n" |
|
17 | 1 | . " data BYTEA,\n" |
|
18 | 1 | . " expires BIGINT\n" |
|
19 | 1 | . ")" |
|
20 | ) |
||
21 | ); |
||
22 | |||
23 | 1 | $this->unsafeExecute( |
|
24 | 1 | $this->prepare( |
|
25 | 1 | "CREATE INDEX {$this->table_name}_expires_index ON {$this->table_name} USING BTREE (expires);" |
|
26 | ) |
||
27 | ); |
||
28 | 1 | } |
|
29 | |||
30 | 36 | public function select(string $key): ?CacheEntry |
|
31 | { |
||
32 | 36 | $statement = $this->prepare("SELECT * FROM {$this->table_name} WHERE key = :key"); |
|
33 | |||
34 | 36 | $statement->bindValue("key", $key, PDO::PARAM_STR); |
|
35 | |||
36 | 36 | $result = $this->fetch($statement); |
|
37 | |||
38 | 36 | return $result[0] ?? null; |
|
39 | } |
||
40 | |||
41 | 45 | public function upsert(array $values, int $expires): void |
|
42 | { |
||
43 | 45 | $placeholders = []; |
|
44 | |||
45 | 45 | for ($index = 0; $index < count($values); $index++) { |
|
0 ignored issues
–
show
|
|||
46 | 45 | $placeholders[] = "(:key_{$index}, :data_{$index}, :expires)"; |
|
47 | } |
||
48 | |||
49 | 45 | $statement = $this->prepare( |
|
50 | 45 | "INSERT INTO {$this->table_name} (key, data, expires)" |
|
51 | 45 | . " VALUES " . implode(", ", $placeholders) |
|
52 | 45 | . " ON CONFLICT (key) DO UPDATE SET data=EXCLUDED.data, expires=EXCLUDED.expires" |
|
53 | ); |
||
54 | |||
55 | 45 | $statement->bindValue("expires", $expires); |
|
56 | |||
57 | 45 | $index = 0; |
|
58 | |||
59 | 45 | foreach ($values as $key => $data) { |
|
60 | 45 | $statement->bindValue("key_{$index}", $key, PDO::PARAM_STR); |
|
61 | 45 | $statement->bindValue("data_{$index}", $data, PDO::PARAM_LOB); |
|
62 | |||
63 | 45 | $index += 1; |
|
64 | } |
||
65 | |||
66 | 45 | $this->execute($statement); |
|
67 | 45 | } |
|
68 | |||
69 | 2 | public function delete(string $key): void |
|
70 | { |
||
71 | 2 | $statement = $this->prepare("DELETE FROM {$this->table_name} WHERE key = :key"); |
|
72 | |||
73 | 2 | $statement->bindValue("key", $key, PDO::PARAM_STR); |
|
74 | |||
75 | 2 | $this->execute($statement); |
|
76 | 2 | } |
|
77 | |||
78 | 1 | public function deleteExpired(int $now): void |
|
79 | { |
||
80 | 1 | $statement = $this->prepare("DELETE FROM {$this->table_name} WHERE :now >= expires"); |
|
81 | |||
82 | 1 | $statement->bindValue("now", $now, PDO::PARAM_INT); |
|
83 | |||
84 | 1 | $this->execute($statement); |
|
85 | 1 | } |
|
86 | |||
87 | /** |
||
88 | * @param string[] $keys |
||
89 | * |
||
90 | * @return CacheEntry[] |
||
91 | */ |
||
92 | 11 | public function selectMultiple(array $keys): array |
|
93 | { |
||
94 | 11 | $placeholders = []; |
|
95 | |||
96 | 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
}
![]() |
|||
97 | 11 | $placeholders[] = ":key_{$index}"; |
|
98 | } |
||
99 | |||
100 | 11 | $statement = $this->prepare( |
|
101 | 11 | "SELECT * FROM {$this->table_name} WHERE key IN (" . implode(", ", $placeholders) . ")" |
|
102 | ); |
||
103 | |||
104 | 11 | foreach ($keys as $index => $key) { |
|
105 | 11 | $statement->bindValue("key_{$index}", $key, PDO::PARAM_STR); |
|
106 | } |
||
107 | |||
108 | 11 | return $this->fetch($statement); |
|
109 | } |
||
110 | |||
111 | 2 | public function deleteMultiple(array $keys): void |
|
112 | { |
||
113 | 2 | $placeholders = []; |
|
114 | |||
115 | 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
}
![]() |
|||
116 | 2 | $placeholders[] = ":key_{$index}"; |
|
117 | } |
||
118 | |||
119 | 2 | $statement = $this->prepare( |
|
120 | 2 | "DELETE FROM {$this->table_name} WHERE key IN (" . implode(", ", $placeholders) . ")" |
|
121 | ); |
||
122 | |||
123 | 2 | foreach ($keys as $index => $key) { |
|
124 | 2 | $statement->bindValue("key_{$index}", $key, PDO::PARAM_STR); |
|
125 | } |
||
126 | |||
127 | 2 | $this->execute($statement); |
|
128 | 2 | } |
|
129 | |||
130 | 194 | public function truncate(): void |
|
131 | { |
||
132 | 194 | $this->execute( |
|
133 | 194 | $this->prepare("TRUNCATE TABLE {$this->table_name}") |
|
134 | ); |
||
135 | 194 | } |
|
136 | } |
||
137 |
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: