Issues (590)

src/Query/Extension/CachableTrait.php (1 issue)

Labels
Severity
1
<?php
2
3
namespace Bdf\Prime\Query\Extension;
4
5
use Bdf\Prime\Cache\CacheInterface;
6
use Bdf\Prime\Cache\CacheKey;
7
use Bdf\Prime\Connection\ConnectionInterface;
8
use Bdf\Prime\Connection\Result\ArrayResultSet;
9
use Bdf\Prime\Connection\Result\ResultSetInterface;
10
use Bdf\Prime\Query\Contract\Cachable;
11
use Bdf\Util\Arr;
12
13
/**
14
 * Provides result cache on queries
15
 *
16
 * @see Cachable
17
 *
18
 * @psalm-require-implements Cachable
19
 *
20
 * @todo Cache statement instead of assoc array result ?
21
 */
22
trait CachableTrait
23
{
24
    /**
25
     * @var null|CacheInterface
26
     */
27
    protected $cache;
28
29
    /**
30
     * @var CacheKey
31
     */
32
    protected $cacheKey = null;
33
34
35
    /**
36
     * {@inheritdoc}
37
     *
38
     * @see Cachable::cache()
39
     */
40 2
    public function cache(): ?CacheInterface
41
    {
42 2
        return $this->cache;
43
    }
44
45
    /**
46
     * {@inheritdoc}
47
     *
48
     * @see Cachable::useCache()
49
     */
50 13
    public function useCache(int $lifetime = 0, ?string $key = null)
51
    {
52 13
        if ($this->cacheKey === null) {
53 13
            $this->cacheKey = new CacheKey(
54 13
                function () {
55 13
                    return $this->cacheNamespace();
56 13
                },
57 13
                $key ?? function () {
58 12
                    return $this->cacheKey();
0 ignored issues
show
Are you sure the usage of $this->cacheKey() targeting Bdf\Prime\Query\Extensio...chableTrait::cacheKey() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
59 13
                },
60 13
                $lifetime
61 13
            );
62
63 13
            return $this;
64
        }
65
66 1
        $this->cacheKey->setLifetime($lifetime);
67
68 1
        if ($key !== null) {
69 1
            $this->cacheKey->setKey($key);
70
        }
71
72 1
        return $this;
73
    }
74
75
    /**
76
     * {@inheritdoc}
77
     *
78
     * @see Cachable::setCache()
79
     */
80 735
    public function setCache(CacheInterface $cache = null)
81
    {
82 735
        $this->cache = $cache;
83
84 735
        return $this;
85
    }
86
87
    /**
88
     * {@inheritdoc}
89
     *
90
     * @see Cachable::setCacheLifetime()
91
     */
92 1
    public function setCacheLifetime(int $lifetime)
93
    {
94 1
        if (!$this->cacheKey) {
95
            $this->useCache();
96
        }
97
98 1
        $this->cacheKey->setLifetime($lifetime);
99
100 1
        return $this;
101
    }
102
103
    /**
104
     * {@inheritdoc}
105
     *
106
     * @see Cachable::setCacheKey()
107
     */
108 2
    public function setCacheKey(?string $cacheKey)
109
    {
110 2
        if (!$this->cacheKey) {
111
            $this->useCache();
112
        }
113
114 2
        $this->cacheKey->setKey($cacheKey);
115
116 2
        return $this;
117
    }
118
119
    /**
120
     * {@inheritdoc}
121
     *
122
     * @see Cachable::setCacheNamespace()
123
     */
124 1
    public function setCacheNamespace(string $namespace)
125
    {
126 1
        if (!$this->cacheKey) {
127
            $this->useCache();
128
        }
129
130 1
        $this->cacheKey->setNamespace($namespace);
131
132 1
        return $this;
133
    }
134
135
    /**
136
     * {@inheritdoc}
137
     *
138
     * @see Cachable::getCacheKey()
139
     */
140 2
    public function getCacheKey(): ?CacheKey
141
    {
142 2
        return $this->cacheKey;
143
    }
144
145
    /**
146
     * Retrieve data from cache, or execute the query and save into cache
147
     *
148
     * @return ResultSetInterface<array<string, mixed>>
149
     * @throws \Bdf\Prime\Exception\PrimeException
150
     */
151 798
    protected function executeCached(): ResultSetInterface
152
    {
153 798
        $key = $this->cacheKey;
154
155 798
        if (!$this->cache || !$key || !$key->valid()) {
156
            /** @psalm-suppress InvalidArgument */
157 787
            return $this->connection->execute($this);
158
        }
159
160 12
        $data = $this->cache->get($key);
161
162 12
        if ($data !== null) {
163 3
            return new ArrayResultSet($data);
164
        }
165
166
        /** @psalm-suppress InvalidArgument */
167 12
        $result = $this->connection->execute($this);
168
169 12
        $data = $result->all();
170 12
        $this->cache->set($key, $data);
171
172 12
        return new ArrayResultSet($data);
173
    }
174
175
    /**
176
     * Clear the cache when a write operation is performed
177
     *
178
     * @return void
179
     */
180 813
    protected function clearCacheOnWrite()
181
    {
182 813
        if ($this->cache) {
183 7
            $this->cache->flush($this->cacheKey ? $this->cacheKey->namespace() : $this->cacheNamespace());
184
        }
185
    }
186
187
    /**
188
     * Get the cache key
189
     * The cache key is generated from the query string
190
     *
191
     * @return string
192
     */
193
    protected function cacheKey(): ?string
194
    {
195
        return null;
196
    }
197
198
    /**
199
     * Get cache namespace
200
     * The namespace is in form : [connection name] ":" [table name]
201
     *
202
     * @return string
203
     */
204 11
    protected function cacheNamespace(): string
205
    {
206 11
        $ns = $this->connection->getName().':';
207
208 11
        foreach ($this->statements['tables'] as $from) {
209 11
            return $ns.$from['table'];
210
        }
211
212
        return $ns;
213
    }
214
}
215