Passed
Pull Request — master (#21)
by Vincent
07:14
created

CachableTrait::cacheNamespace()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2.032

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 4
c 1
b 0
f 0
dl 0
loc 9
ccs 4
cts 5
cp 0.8
rs 10
cc 2
nc 2
nop 0
crap 2.032
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\Query\Contract\Cachable;
9
10
/**
11
 * Provides result cache on queries
12
 *
13
 * @see Cachable
14
 *
15
 * @property ConnectionInterface $connection
16
 *
17
 * @todo Cache statement instead of assoc array result ?
0 ignored issues
show
Coding Style introduced by
Comment refers to a TODO task

This check looks TODO comments that have been left in the code.

``TODO``s show that something is left unfinished and should be attended to.

Loading history...
18
 */
19
trait CachableTrait
20
{
21
    /**
22
     * @var null|CacheInterface
23
     */
24
    protected $cache;
25
26
    /**
27
     * @var CacheKey
28
     */
29
    protected $cacheKey = null;
30
31
32
    /**
33
     * @see Cachable::cache()
34
     */
35 2
    public function cache()
0 ignored issues
show
Coding Style introduced by
Expected 1 blank line before function; 2 found
Loading history...
36
    {
37 2
        return $this->cache;
38
    }
39
40
    /**
0 ignored issues
show
Coding Style introduced by
Parameter $lifetime should have a doc-comment as per coding-style.
Loading history...
Coding Style introduced by
Parameter $key should have a doc-comment as per coding-style.
Loading history...
41
     * @see Cachable::useCache()
42
     */
43 13
    public function useCache(int $lifetime = 0, ?string $key = null)
44
    {
45 13
        if ($this->cacheKey === null) {
46 13
            $this->cacheKey = new CacheKey(
47
                function () { return $this->cacheNamespace(); },
0 ignored issues
show
Coding Style introduced by
Opening brace must be the last content on the line
Loading history...
introduced by
There should be no white space after an opening "{"
Loading history...
introduced by
There should be no white space before a closing "}"
Loading history...
Coding Style introduced by
Closing brace of nested function must be on a new line
Loading history...
48
                $key ?? function () { return $this->cacheKey(); },
0 ignored issues
show
Coding Style introduced by
Operation must be bracketed
Loading history...
Coding Style introduced by
Opening brace must be the last content on the line
Loading history...
introduced by
There should be no white space after an opening "{"
Loading history...
introduced by
There should be no white space before a closing "}"
Loading history...
Coding Style introduced by
Closing brace of nested function must be on a new line
Loading history...
49 13
                $lifetime
50
            );
51
52 13
            return $this;
53
        }
54
55 1
        $this->cacheKey->setLifetime($lifetime);
56
57 1
        if ($key !== null) {
58 1
            $this->cacheKey->setKey($key);
59
        }
60
61 1
        return $this;
62
    }
63
64
    /**
0 ignored issues
show
Coding Style introduced by
Parameter $cache should have a doc-comment as per coding-style.
Loading history...
65
     * @see Cachable::setCache()
66
     */
67 482
    public function setCache(CacheInterface $cache = null)
68
    {
69 482
        $this->cache = $cache;
70
71 482
        return $this;
72
    }
73
74
    /**
0 ignored issues
show
Coding Style introduced by
Parameter $lifetime should have a doc-comment as per coding-style.
Loading history...
75
     * @see Cachable::setCacheLifetime()
76
     */
77 1
    public function setCacheLifetime(int $lifetime)
78
    {
79 1
        if (!$this->cacheKey) {
80
            $this->useCache();
81
        }
82
83 1
        $this->cacheKey->setLifetime($lifetime);
84
85 1
        return $this;
86
    }
87
88
    /**
0 ignored issues
show
Coding Style introduced by
Parameter $cacheKey should have a doc-comment as per coding-style.
Loading history...
89
     * @see Cachable::setCacheKey()
90
     */
91 2
    public function setCacheKey(?string $cacheKey)
92
    {
93 2
        if (!$this->cacheKey) {
94
            $this->useCache();
95
        }
96
97 2
        $this->cacheKey->setKey($cacheKey);
98
99 2
        return $this;
100
    }
101
102
    /**
0 ignored issues
show
Coding Style introduced by
Parameter $namespace should have a doc-comment as per coding-style.
Loading history...
103
     * @see Cachable::setCacheNamespace()
104
     */
105 1
    public function setCacheNamespace(string $namespace)
106
    {
107 1
        if (!$this->cacheKey) {
108
            $this->useCache();
109
        }
110
111 1
        $this->cacheKey->setNamespace($namespace);
112
113 1
        return $this;
114
    }
115
116
    /**
117
     * @see Cachable::getCacheKey()
118
     */
119 2
    public function getCacheKey(): ?CacheKey
120
    {
121 2
        return $this->cacheKey;
122
    }
123
124
    /**
125
     * Retrieve data from cache, or execute the query and save into cache
126
     *
127
     * @return mixed
128
     * @throws \Bdf\Prime\Exception\PrimeException
0 ignored issues
show
introduced by
Comment missing for @throws tag in function comment
Loading history...
129
     */
130 558
    protected function executeCached()
131
    {
132 558
        $key = $this->cacheKey;
133
134 558
        if (!$this->cache || !$key || !$key->valid()) {
135 547
            return $this->connection->execute($this)->all();
0 ignored issues
show
Bug introduced by
$this of type Bdf\Prime\Query\Extension\CachableTrait is incompatible with the type Bdf\Prime\Query\Contract\Compilable expected by parameter $query of Bdf\Prime\Connection\Con...ionInterface::execute(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

135
            return $this->connection->execute(/** @scrutinizer ignore-type */ $this)->all();
Loading history...
136
        }
137
138 12
        $data = $this->cache->get($key);
139
140 12
        if ($data !== null) {
0 ignored issues
show
introduced by
The condition $data !== null is always true.
Loading history...
141 3
            return $data;
142
        }
143
144 12
        $data = $this->connection->execute($this)->all();
145
146 12
        $this->cache->set($key, $data);
147
148 12
        return $data;
149
    }
150
151
    /**
152
     * Clear the cache when a write operation is performed
153
     */
154 565
    protected function clearCacheOnWrite()
155
    {
156 565
        if ($this->cache) {
157 7
            $this->cache->flush($this->cacheKey ? $this->cacheKey->namespace() : $this->cacheNamespace());
0 ignored issues
show
Coding Style introduced by
Inline shorthand IF statement requires brackets around comparison
Loading history...
158
        }
159 565
    }
160
161
    /**
162
     * Get the cache key
163
     * The cache key is generated from the query string
0 ignored issues
show
introduced by
Doc comment short description must be on a single line, further text should be a separate paragraph
Loading history...
164
     *
165
     * @return string
166
     */
167
    protected function cacheKey()
168
    {
169
        return null;
170
    }
171
172
    /**
173
     * Get cache namespace
174
     * The namespace is in form : [connection name] ":" [table name]
0 ignored issues
show
introduced by
Doc comment short description must be on a single line, further text should be a separate paragraph
Loading history...
175
     *
176
     * @return string
177
     */
178 11
    protected function cacheNamespace()
179
    {
180 11
        $ns = $this->connection->getName().':';
181
182 11
        foreach ($this->statements['tables'] as $from) {
183 11
            return $ns.$from['table'];
184
        }
185
186
        return $ns;
187
    }
188
}
189