Completed
Pull Request — master (#5)
by Vincent
07:04
created

CachableTrait::setCache()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 2
c 1
b 0
f 0
dl 0
loc 5
ccs 3
cts 3
cp 1
rs 10
cc 1
nc 1
nop 1
crap 1
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;
0 ignored issues
show
introduced by
Unused use statement
Loading history...
8
use Bdf\Prime\Query\Contract\Cachable;
0 ignored issues
show
introduced by
Unused use statement
Loading history...
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;
0 ignored issues
show
Coding Style introduced by
Expected 1 blank line(s) before first member var; 0 found
Loading history...
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 477
    public function setCache(CacheInterface $cache = null)
68
    {
69 477
        $this->cache = $cache;
70
71 477
        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
     */
129 554
    protected function executeCached()
130
    {
131 554
        $key = $this->cacheKey;
132
133 554
        if (!$this->cache || !$key || !$key->valid()) {
134 543
            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

134
            return $this->connection->execute(/** @scrutinizer ignore-type */ $this)->all();
Loading history...
135
        }
136
137 12
        $data = $this->cache->get($key);
138
139 12
        if ($data !== null) {
0 ignored issues
show
introduced by
The condition $data !== null is always true.
Loading history...
140 3
            return $data;
141
        }
142
143 12
        $data = $this->connection->execute($this)->all();
144
145 12
        $this->cache->set($key, $data);
146
147 12
        return $data;
148
    }
149
150
    /**
151
     * Clear the cache when a write operation is performed
152
     */
153 561
    protected function clearCacheOnWrite()
154
    {
155 561
        if ($this->cache) {
156 7
            $this->cache->flush($this->cacheKey ? $this->cacheKey->namespace() : $this->cacheNamespace());
0 ignored issues
show
Coding Style introduced by
Inline IF statements are not allowed
Loading history...
Coding Style introduced by
Inline shorthand IF statement requires brackets around comparison
Loading history...
157
        }
158 561
    }
159
160
    /**
161
     * Get the cache key
162
     * 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...
163
     *
164
     * @return string
165
     */
166
    protected function cacheKey()
167
    {
168
        return null;
169
    }
170
171
    /**
172
     * Get cache namespace
173
     * 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...
174
     *
175
     * @return string
176
     */
177 11
    protected function cacheNamespace()
178
    {
179 11
        return $this->connection->getName().':'.(isset($this->statements['tables'][0]['table']) ? $this->statements['tables'][0]['table'] : '');
0 ignored issues
show
Coding Style introduced by
Inline IF statements are not allowed
Loading history...
180
    }
181
}
182