Completed
Push — master ( 9fa596...e14f7e )
by Marco
02:55
created

CacheProvider::deleteMultiple()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 1
crap 1
1
<?php
2
/*
3
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
4
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
5
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
6
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
7
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
8
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
9
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
10
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
11
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
12
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
13
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
14
 *
15
 * This software consists of voluntary contributions made by many individuals
16
 * and is licensed under the MIT license. For more information, see
17
 * <http://www.doctrine-project.org>.
18
 */
19
20
namespace Doctrine\Common\Cache;
21
22
/**
23
 * Base class for cache provider implementations.
24
 *
25
 * @since  2.2
26
 * @author Benjamin Eberlei <[email protected]>
27
 * @author Guilherme Blanco <[email protected]>
28
 * @author Jonathan Wage <[email protected]>
29
 * @author Roman Borschel <[email protected]>
30
 * @author Fabio B. Silva <[email protected]>
31
 * @author Benoit Burnichon <[email protected]>
32
 */
33
abstract class CacheProvider implements Cache, FlushableCache, ClearableCache, MultiGetCache, MultiPutCache, MultiDeleteCache
34
{
35
    const DOCTRINE_NAMESPACE_CACHEKEY = 'DoctrineNamespaceCacheKey[%s]';
36
37
    /**
38
     * The namespace to prefix all cache ids with.
39
     *
40
     * @var string
41
     */
42
    private $namespace = '';
43
44
    /**
45
     * The namespace version.
46
     *
47
     * @var integer|null
48
     */
49
    private $namespaceVersion;
50
51
    /**
52
     * Sets the namespace to prefix all cache ids with.
53
     *
54
     * @param string $namespace
55
     *
56
     * @return void
57
     */
58 25
    public function setNamespace($namespace)
59
    {
60 25
        $this->namespace        = (string) $namespace;
61 25
        $this->namespaceVersion = null;
62 25
    }
63
64
    /**
65
     * Retrieves the namespace that prefixes all cache ids.
66
     *
67
     * @return string
68
     */
69 1
    public function getNamespace()
70
    {
71 1
        return $this->namespace;
72
    }
73
74
    /**
75
     * {@inheritdoc}
76
     */
77 734
    public function fetch($id)
78
    {
79 734
        return $this->doFetch($this->getNamespacedId($id));
80
    }
81
82
    /**
83
     * {@inheritdoc}
84
     */
85 39
    public function fetchMultiple(array $keys)
86
    {
87 39
        if (empty($keys)) {
88 12
            return [];
89
        }
90
        
91
        // note: the array_combine() is in place to keep an association between our $keys and the $namespacedKeys
92 27
        $namespacedKeys = array_combine($keys, array_map([$this, 'getNamespacedId'], $keys));
93 27
        $items          = $this->doFetchMultiple($namespacedKeys);
94 27
        $foundItems     = [];
95
96
        // no internal array function supports this sort of mapping: needs to be iterative
97
        // this filters and combines keys in one pass
98 27
        foreach ($namespacedKeys as $requestedKey => $namespacedKey) {
99 27
            if (isset($items[$namespacedKey]) || array_key_exists($namespacedKey, $items)) {
100 27
                $foundItems[$requestedKey] = $items[$namespacedKey];
101 27
            }
102 27
        }
103
104 27
        return $foundItems;
105
    }
106
107
    /**
108
     * {@inheritdoc}
109
     */
110 85
    public function saveMultiple(array $keysAndValues, $lifetime = 0)
111
    {
112 15
        $namespacedKeysAndValues = [];
113 15
        foreach ($keysAndValues as $key => $value) {
114 15
            $namespacedKeysAndValues[$this->getNamespacedId($key)] = $value;
115 15
        }
116
117 85
        return $this->doSaveMultiple($namespacedKeysAndValues, $lifetime);
118
    }
119
120
    /**
121
     * {@inheritdoc}
122
     */
123 823
    public function contains($id)
124
    {
125 823
        return $this->doContains($this->getNamespacedId($id));
126
    }
127
128
    /**
129
     * {@inheritdoc}
130
     */
131 861
    public function save($id, $data, $lifeTime = 0)
132
    {
133 861
        return $this->doSave($this->getNamespacedId($id), $data, $lifeTime);
134
    }
135
136
    /**
137
     * {@inheritdoc}
138
     */
139 14
    public function deleteMultiple(array $keys)
140
    {
141 14
        return $this->doDeleteMultiple(array_map(array($this, 'getNamespacedId'), $keys));
142
    }
143
144
    /**
145
     * {@inheritdoc}
146
     */
147 521
    public function delete($id)
148
    {
149 521
        return $this->doDelete($this->getNamespacedId($id));
150
    }
151
152
    /**
153
     * {@inheritdoc}
154
     */
155 14
    public function getStats()
156
    {
157 14
        return $this->doGetStats();
158
    }
159
160
    /**
161
     * {@inheritDoc}
162
     */
163 27
    public function flushAll()
164
    {
165 27
        return $this->doFlush();
166
    }
167
168
    /**
169
     * {@inheritDoc}
170
     */
171 66
    public function deleteAll()
172
    {
173 66
        $namespaceCacheKey = $this->getNamespaceCacheKey();
174 65
        $namespaceVersion  = $this->getNamespaceVersion() + 1;
175
176 65
        if ($this->doSave($namespaceCacheKey, $namespaceVersion)) {
177 64
            $this->namespaceVersion = $namespaceVersion;
178
179 64
            return true;
180
        }
181
182 1
        return false;
183
    }
184
185
    /**
186
     * Prefixes the passed id with the configured namespace value.
187
     *
188
     * @param string $id The id to namespace.
189
     *
190
     * @return string The namespaced id.
191
     */
192 904
    private function getNamespacedId($id)
193
    {
194 904
        $namespaceVersion  = $this->getNamespaceVersion();
195
196 904
        return sprintf('%s[%s][%s]', $this->namespace, $id, $namespaceVersion);
197 2
    }
198
199
    /**
200
     * Returns the namespace cache key.
201
     *
202
     * @return string
203
     */
204 904
    private function getNamespaceCacheKey()
205
    {
206 904
        return sprintf(self::DOCTRINE_NAMESPACE_CACHEKEY, $this->namespace);
207
    }
208
209
    /**
210
     * Returns the namespace version.
211
     *
212
     * @return integer
213
     */
214 904
    private function getNamespaceVersion()
215
    {
216 904
        if (null !== $this->namespaceVersion) {
217 890
            return $this->namespaceVersion;
218
        }
219
220 904
        $namespaceCacheKey = $this->getNamespaceCacheKey();
221 904
        $this->namespaceVersion = $this->doFetch($namespaceCacheKey) ?: 1;
222
223 904
        return $this->namespaceVersion;
224
    }
225
226
    /**
227
     * Default implementation of doFetchMultiple. Each driver that supports multi-get should owerwrite it.
228
     *
229
     * @param array $keys Array of keys to retrieve from cache
230
     * @return array Array of values retrieved for the given keys.
231
     */
232 16
    protected function doFetchMultiple(array $keys)
233
    {
234 16
        $returnValues = [];
235
236 16
        foreach ($keys as $key) {
237 16
            if (false !== ($item = $this->doFetch($key)) || $this->doContains($key)) {
238 16
                $returnValues[$key] = $item;
239 16
            }
240 16
        }
241
242 16
        return $returnValues;
243
    }
244
245
    /**
246
     * Fetches an entry from the cache.
247
     *
248
     * @param string $id The id of the cache entry to fetch.
249
     *
250
     * @return mixed|false The cached data or FALSE, if no cache entry exists for the given id.
251
     */
252
    abstract protected function doFetch($id);
253
254
    /**
255
     * Tests if an entry exists in the cache.
256
     *
257
     * @param string $id The cache id of the entry to check for.
258
     *
259
     * @return bool TRUE if a cache entry exists for the given cache id, FALSE otherwise.
260
     */
261
    abstract protected function doContains($id);
262
263
    /**
264
     * Default implementation of doSaveMultiple. Each driver that supports multi-put should override it.
265
     *
266
     * @param array $keysAndValues  Array of keys and values to save in cache
267
     * @param int   $lifetime       The lifetime. If != 0, sets a specific lifetime for these
268
     *                              cache entries (0 => infinite lifeTime).
269
     *
270
     * @return bool TRUE if the operation was successful, FALSE if it wasn't.
271
     */
272 10
    protected function doSaveMultiple(array $keysAndValues, $lifetime = 0)
273
    {
274 10
        $success = true;
275
276 10
        foreach ($keysAndValues as $key => $value) {
277 10
            if (!$this->doSave($key, $value, $lifetime)) {
278 2
                $success = false;
279 2
            }
280 10
        }
281
282 10
        return $success;
283
    }
284
285
    /**
286
     * Puts data into the cache.
287
     *
288
     * @param string $id       The cache id.
289
     * @param string $data     The cache entry/data.
290
     * @param int    $lifeTime The lifetime. If != 0, sets a specific lifetime for this
291
     *                           cache entry (0 => infinite lifeTime).
292
     *
293
     * @return bool TRUE if the entry was successfully stored in the cache, FALSE otherwise.
294
     */
295
    abstract protected function doSave($id, $data, $lifeTime = 0);
296
297
    /**
298
     * Default implementation of doDeleteMultiple. Each driver that supports multi-delete should override it.
299
     *
300
     * @param array $keys Array of keys to delete from cache
301
     *
302
     * @return bool TRUE if the operation was successful, FALSE if it wasn't
303
     */
304 12
    protected function doDeleteMultiple(array $keys)
305
    {
306 12
        $success = true;
307
308 12
        foreach ($keys as $key) {
309 12
            if (! $this->doDelete($key)) {
310 1
                $success = false;
311 1
            }
312 12
        }
313
314 12
        return $success;
315
    }
316
317
    /**
318
     * Deletes a cache entry.
319
     *
320
     * @param string $id The cache id.
321
     *
322
     * @return bool TRUE if the cache entry was successfully deleted, FALSE otherwise.
323
     */
324
    abstract protected function doDelete($id);
325
326
    /**
327
     * Flushes all cache entries.
328
     *
329
     * @return bool TRUE if the cache entries were successfully flushed, FALSE otherwise.
330
     */
331
    abstract protected function doFlush();
332
333
    /**
334
     * Retrieves cached information from the data store.
335
     *
336
     * @since 2.2
337
     *
338
     * @return array|null An associative array with server's statistics if available, NULL otherwise.
339
     */
340
    abstract protected function doGetStats();
341
}
342