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