Completed
Pull Request — master (#61)
by Anton
04:22
created

EntityCache   A

Complexity

Total Complexity 17

Size/Duplication

Total Lines 146
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Importance

Changes 2
Bugs 0 Features 0
Metric Value
wmc 17
c 2
b 0
f 0
lcom 1
cbo 3
dl 0
loc 146
rs 10

9 Methods

Rating   Name   Duplication   Size   Complexity  
A isEnabled() 0 4 1
A configureCache() 0 4 1
A configure() 0 11 3
B remember() 0 12 5
A forget() 0 8 2
A has() 0 4 1
A get() 0 8 2
A flushCache() 0 4 1
A __destruct() 0 4 1
1
<?php
2
/**
3
 * Spiral Framework.
4
 *
5
 * @license   MIT
6
 * @author    Anton Titov (Wolfy-J)
7
 */
8
namespace Spiral\ORM;
9
10
use Spiral\Core\Component;
11
use Spiral\Models\IdentifiedInterface;
12
use Spiral\ORM\Exceptions\CacheException;
13
14
/**
15
 * Entity cache support. Used to share same model instance across it's child or related objects.
16
 *
17
 * @todo Interface is needed
18
 */
19
class EntityCache extends Component
20
{
21
    /**
22
     * Indication that entity cache is enabled.
23
     *
24
     * @var bool
25
     */
26
    private $enabled = true;
27
28
    /**
29
     * Maximum entity cache size. Null is unlimited.
30
     *
31
     * @var int|null
32
     */
33
    private $cacheSize = null;
34
35
    /**
36
     * In cases when ORM cache is enabled every constructed instance will be stored here, cache used
37
     * mainly to ensure the same instance of object, even if was accessed from different spots.
38
     * Cache usage increases memory consumption and does not decreases amount of queries being made.
39
     *
40
     * @var RecordEntity[]
41
     */
42
    private $cache = [];
43
44
    /**
45
     * Check if entity cache enabled.
46
     *
47
     * @return bool
48
     */
49
    public function isEnabled()
50
    {
51
        return $this->enabled;
52
    }
53
54
    /**
55
     * Enable or disable entity cache. Disabling cache will not flush it's values.
56
     *
57
     * @deprecated see configure
58
     * @param bool     $enabled
59
     * @param int|null $maxSize Null = unlimited.
60
     * @return $this
61
     */
62
    public function configureCache($enabled, $maxSize = null)
63
    {
64
        return $this->configure($enabled, $maxSize);
65
    }
66
67
    /**
68
     * Enable or disable entity cache. Disabling cache will not flush it's values.
69
     *
70
     * @param bool     $enabled
71
     * @param int|null $maxSize Null = unlimited.
72
     * @return $this
73
     */
74
    public function configure($enabled, $maxSize = null)
75
    {
76
        $this->enabled = (bool)$enabled;
77
        if (!is_null($maxSize) && !is_int($maxSize)) {
78
            throw new \InvalidArgumentException("Cache size value has to be null or integer.");
79
        }
80
81
        $this->cacheSize = $maxSize;
82
83
        return $this;
84
    }
85
86
    /**
87
     * Add Record to entity cache (only if cache enabled). Primary key is required for caching.
88
     *
89
     * @param IdentifiedInterface $entity
90
     * @param bool                $ignoreLimit Cache overflow will be ignored.
91
     * @return IdentifiedInterface
92
     * @throws CacheException
93
     */
94
    public function remember(IdentifiedInterface $entity, $ignoreLimit = true)
95
    {
96
        if (empty($entity->primaryKey()) || !$this->enabled) {
97
            return $entity;
98
        }
99
100
        if (!$ignoreLimit && count($this->cache) > $this->cacheSize) {
101
            throw new CacheException("Entity cache size exceeded.");
102
        }
103
104
        return $this->cache[get_class($entity) . '.' . $entity->primaryKey()] = $entity;
105
    }
106
107
    /**
108
     * Remove Record record from entity cache. Primary key is required for caching.
109
     *
110
     * @param IdentifiedInterface $entity
111
     */
112
    public function forget(IdentifiedInterface $entity)
113
    {
114
        if (empty($entity->primaryKey())) {
115
            return;
116
        }
117
118
        unset($this->cache[get_class($entity) . '.' . $entity->primaryKey()]);
119
    }
120
121
    /**
122
     * Check if desired entity was already cached.
123
     *
124
     * @param string $class
125
     * @param mixed  $primaryKey
126
     * @return bool
127
     */
128
    public function has($class, $primaryKey)
129
    {
130
        return isset($this->cache[$class . '.' . $primaryKey]);
131
    }
132
133
    /**
134
     * Fetch entity from cache.
135
     *
136
     * @param string $class
137
     * @param mixed  $primaryKey
138
     * @return null|IdentifiedInterface
139
     */
140
    public function get($class, $primaryKey)
141
    {
142
        if (empty($this->cache[$class . '.' . $primaryKey])) {
143
            return null;
144
        }
145
146
        return $this->cache[$class . '.' . $primaryKey];
147
    }
148
149
    /**
150
     * Flush content of entity cache.
151
     */
152
    public function flushCache()
153
    {
154
        $this->cache = [];
155
    }
156
157
    /**
158
     * Destructing.
159
     */
160
    public function __destruct()
161
    {
162
        $this->flushCache();
163
    }
164
}