]> git.mxchange.org Git - friendica.git/blob - src/Core/Cache/DatabaseCache.php
Adding possibility to use a different cache-backend for locking and caching
[friendica.git] / src / Core / Cache / DatabaseCache.php
1 <?php
2
3 namespace Friendica\Core\Cache;
4
5 use Friendica\Core\Cache;
6 use Friendica\Database\Database;
7 use Friendica\Util\DateTimeFormat;
8
9 /**
10  * Database Cache
11  *
12  * @author Hypolite Petovan <hypolite@mrpetovan.com>
13  */
14 class DatabaseCache extends AbstractCache implements ICache
15 {
16         /**
17          * @var Database
18          */
19         private $dba;
20
21         public function __construct(string $hostname, Database $dba)
22         {
23                 parent::__construct($hostname);
24
25                 $this->dba = $dba;
26         }
27
28         /**
29          * (@inheritdoc)
30          */
31         public function getAllKeys($prefix = null)
32         {
33                 if (empty($prefix)) {
34                         $where = ['`expires` >= ?', DateTimeFormat::utcNow()];
35                 } else {
36                         $where = ['`expires` >= ? AND `k` LIKE CONCAT(?, \'%\')', DateTimeFormat::utcNow(), $prefix];
37                 }
38
39                 $stmt = $this->dba->select('cache', ['k'], $where);
40
41                 $keys = [];
42                 while ($key = $this->dba->fetch($stmt)) {
43                         array_push($keys, $key['k']);
44                 }
45                 $this->dba->close($stmt);
46
47                 return $keys;
48         }
49
50         /**
51          * (@inheritdoc)
52          */
53         public function get($key)
54         {
55                 $cache = $this->dba->selectFirst('cache', ['v'], ['`k` = ? AND (`expires` >= ? OR `expires` = -1)', $key, DateTimeFormat::utcNow()]);
56
57                 if ($this->dba->isResult($cache)) {
58                         $cached = $cache['v'];
59                         $value = @unserialize($cached);
60
61                         // Only return a value if the serialized value is valid.
62                         // We also check if the db entry is a serialized
63                         // boolean 'false' value (which we want to return).
64                         if ($cached === serialize(false) || $value !== false) {
65                                 return $value;
66                         }
67                 }
68
69                 return null;
70         }
71
72         /**
73          * (@inheritdoc)
74          */
75         public function set($key, $value, $ttl = Cache::FIVE_MINUTES)
76         {
77                 if ($ttl > 0) {
78                         $fields = [
79                                 'v' => serialize($value),
80                                 'expires' => DateTimeFormat::utc('now + ' . $ttl . 'seconds'),
81                                 'updated' => DateTimeFormat::utcNow()
82                         ];
83                 } else {
84                         $fields = [
85                                 'v' => serialize($value),
86                                 'expires' => -1,
87                                 'updated' => DateTimeFormat::utcNow()
88                         ];
89                 }
90
91                 return $this->dba->update('cache', $fields, ['k' => $key], true);
92         }
93
94         /**
95          * (@inheritdoc)
96          */
97         public function delete($key)
98         {
99                 return $this->dba->delete('cache', ['k' => $key]);
100         }
101
102         /**
103          * (@inheritdoc)
104          */
105         public function clear($outdated = true)
106         {
107                 if ($outdated) {
108                         return $this->dba->delete('cache', ['`expires` < NOW()']);
109                 } else {
110                         return $this->dba->delete('cache', ['`k` IS NOT NULL ']);
111                 }
112         }
113
114         public function __toString()
115         {
116                 return self::TYPE_DATABASE;
117         }
118 }