aboutsummaryrefslogtreecommitdiff
path: root/lib/classes/cache/DbCache.php
blob: c7abef22a7465c423dcf4cf7b2de85e867ef37b2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
<?php

namespace Studip\Cache;

use DBManager;
use Psr\Cache\CacheItemInterface;

/**
 * StudipCache implementation using database table
 *
 * @author    Elmar Ludwig <elmar.ludwig@uos.de>
 */
class DbCache extends Cache
{
    /**
     * @return string A display name (that can be translated) for this cache class.
     */
    public static function getDisplayName(): string
    {
        return _('Datenbank');
    }

    /**
     * Expire item from the cache.
     *
     * @param string $arg a single key
     */
    public function expire($arg)
    {
        $db = DBManager::get();

        $stmt = $db->prepare('DELETE FROM cache WHERE cache_key = ?');
        $stmt->execute([$arg]);
    }

    /**
     * Expire all items from the cache.
     */
    public function flush()
    {
        $db = DBManager::get();

        $db->exec('TRUNCATE TABLE cache');
    }

    /**
     * Delete all expired items from the cache.
     */
    public function purge()
    {
        $db = DBManager::get();

        $stmt = $db->prepare('DELETE FROM cache WHERE expires < ?');
        $stmt->execute([time()]);
    }

    /**
     * Return statistics.
     *
     * @return array|array[]
     *@see Cache::getStats()
     *
     */
    public function getStats(): array
    {
        return [
            __CLASS__ => [
                'name' => _('Anzahl Einträge'),
                'value' => DBManager::get()->fetchColumn("SELECT COUNT(*) FROM `cache`")
            ]
        ];
    }

    /**
     * Return the Vue component name and props that handle configuration.
     *
     * @return array
     *@see Cache::getConfig()
     *
     */
    public static function getConfig(): array
    {
        return [
            'component' => null,
            'props' => []
        ];
    }

    /**
     * @inheritDoc
     */
    public function getItem(string $key): CacheItemInterface
    {
        $query = "SELECT `content`, `expires`
                  FROM `cache`
                  WHERE `cache_key` = :key
                    AND `expires` > UNIX_TIMESTAMP()";
        $result = DBManager::get()->fetchOne($query, [':key' => $key]);

        $item = new Item($key);
        if (!empty($result)) {
            $item->setHit();
            if ($result['content']) {
                $item->set(unserialize($result['content']));
            }
            if ($result['expires']) {
                $expiration = new \DateTime();
                $expiration->setTimestamp($result['expires']);
                $item->expiresAt($expiration);
            }
        }
        return $item;
    }

    /**
     * @inheritDoc
     */
    public function hasItem(string $key): bool
    {
        $query = "SELECT 1
                  FROM `cache`
                  WHERE `cache_key` = :key
                    AND `expires` > UNIX_TIMESTAMP()";
        return (bool) DBManager::get()->fetchColumn($query, [':key' => $key]);
    }

    /**
     * @inheritDoc
     */
    public function save(CacheItemInterface $item): bool
    {
        $expiration = $this->getExpiration($item);
        if ($expiration < 1) {
            // The item would expire immediately.
            return false;
        }

        return DBManager::get()->execute(
            'REPLACE INTO `cache` VALUES (?, ?, ?)',
            [$item->getKey(), serialize($item->get()), $expiration]
        );
    }
}