]> git.mxchange.org Git - friendica.git/blob - src/Core/Cache/Type/DatabaseCache.php
Restructure Cache to follow new paradigm
[friendica.git] / src / Core / Cache / Type / DatabaseCache.php
1 <?php
2 /**
3  * @copyright Copyright (C) 2010-2021, the Friendica project
4  *
5  * @license GNU AGPL version 3 or any later version
6  *
7  * This program is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU Affero General Public License as
9  * published by the Free Software Foundation, either version 3 of the
10  * License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU Affero General Public License for more details.
16  *
17  * You should have received a copy of the GNU Affero General Public License
18  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
19  *
20  */
21
22 namespace Friendica\Core\Cache\Type;
23
24 use Friendica\Core\Cache\Enum\Duration;
25 use Friendica\Core\Cache\ICache;
26 use Friendica\Core\Cache\Enum\Type;
27 use Friendica\Database\Database;
28 use Friendica\Util\DateTimeFormat;
29
30 /**
31  * Database Cache
32  */
33 class DatabaseCache extends BaseCache implements ICache
34 {
35         /**
36          * @var Database
37          */
38         private $dba;
39
40         public function __construct(string $hostname, Database $dba)
41         {
42                 parent::__construct($hostname);
43
44                 $this->dba = $dba;
45         }
46
47         /**
48          * (@inheritdoc)
49          */
50         public function getAllKeys($prefix = null)
51         {
52                 if (empty($prefix)) {
53                         $where = ['`expires` >= ?', DateTimeFormat::utcNow()];
54                 } else {
55                         $where = ['`expires` >= ? AND `k` LIKE CONCAT(?, \'%\')', DateTimeFormat::utcNow(), $prefix];
56                 }
57
58                 $stmt = $this->dba->select('cache', ['k'], $where);
59
60                 $keys = [];
61                 while ($key = $this->dba->fetch($stmt)) {
62                         array_push($keys, $key['k']);
63                 }
64                 $this->dba->close($stmt);
65
66                 return $keys;
67         }
68
69         /**
70          * (@inheritdoc)
71          */
72         public function get($key)
73         {
74                 $cache = $this->dba->selectFirst('cache', ['v'], ['`k` = ? AND (`expires` >= ? OR `expires` = -1)', $key, DateTimeFormat::utcNow()]);
75
76                 if ($this->dba->isResult($cache)) {
77                         $cached = $cache['v'];
78                         $value = @unserialize($cached);
79
80                         // Only return a value if the serialized value is valid.
81                         // We also check if the db entry is a serialized
82                         // boolean 'false' value (which we want to return).
83                         if ($cached === serialize(false) || $value !== false) {
84                                 return $value;
85                         }
86                 }
87
88                 return null;
89         }
90
91         /**
92          * (@inheritdoc)
93          */
94         public function set($key, $value, $ttl = Duration::FIVE_MINUTES)
95         {
96                 if ($ttl > 0) {
97                         $fields = [
98                                 'v' => serialize($value),
99                                 'expires' => DateTimeFormat::utc('now + ' . $ttl . 'seconds'),
100                                 'updated' => DateTimeFormat::utcNow()
101                         ];
102                 } else {
103                         $fields = [
104                                 'v' => serialize($value),
105                                 'expires' => -1,
106                                 'updated' => DateTimeFormat::utcNow()
107                         ];
108                 }
109
110                 return $this->dba->update('cache', $fields, ['k' => $key], true);
111         }
112
113         /**
114          * (@inheritdoc)
115          */
116         public function delete($key)
117         {
118                 return $this->dba->delete('cache', ['k' => $key]);
119         }
120
121         /**
122          * (@inheritdoc)
123          */
124         public function clear($outdated = true)
125         {
126                 if ($outdated) {
127                         return $this->dba->delete('cache', ['`expires` < NOW()']);
128                 } else {
129                         return $this->dba->delete('cache', ['`k` IS NOT NULL ']);
130                 }
131         }
132
133         /**
134          * {@inheritDoc}
135          */
136         public function getName()
137         {
138                 return Type::DATABASE;
139         }
140 }