From 569b5601155dacc50a1d700117f06293ba303c65 Mon Sep 17 00:00:00 2001 From: Ali Bakir Date: Sun, 13 Apr 2014 20:05:51 +0100 Subject: [PATCH] Cache: Implement writeMany, readMany, deleteMany --- src/Cache/Cache.php | 91 ++++++++++++++++++++++++++++++ src/Cache/CacheEngine.php | 44 +++++++++++++++ tests/TestCase/Cache/CacheTest.php | 52 +++++++++++++++++ 3 files changed, 187 insertions(+) diff --git a/src/Cache/Cache.php b/src/Cache/Cache.php index 292ecd66798..4bf14b89870 100644 --- a/src/Cache/Cache.php +++ b/src/Cache/Cache.php @@ -202,6 +202,44 @@ public static function write($key, $value, $config = 'default') { return $success; } +/** + * Write data for many keys into cache. + * + * ### Usage: + * + * Writing to the active cache config: + * + * `Cache::writeMany(array('cached_data_1' => 'data 1', 'cached_data_2' => 'data 2'));` + * + * Writing to a specific cache config: + * + * `Cache::writeMany(array('cached_data_1' => 'data 1', 'cached_data_2' => 'data 2'), 'long_term');` + * + * @param array $data An array of data to be stored in the cache + * @param string $config Optional string configuration name to write to. Defaults to 'default' + * @return array of bools for each key provided, indicating true for success or false for fail + * @throws \Cake\Error\Exception + */ + public static function writeMany($data, $config = 'default') { + $engine = static::engine($config); + if (!$engine) { + return false; + } + + $return = $engine->writeMany($data); + foreach ($return as $key => $success) { + if ($success === false && !empty($data[$key])) { + throw new Error\Exception(sprintf( + '%s cache was unable to write \'%s\' to %s cache', + $config, + $key, + get_class($engine) + )); + } + } + return $return; + } + /** * Read a key from the cache. * @@ -228,6 +266,32 @@ public static function read($key, $config = 'default') { return $engine->read($key); } +/** + * Read multiple keys from the cache. + * + * ### Usage: + * + * Reading multiple keys from the active cache configuration. + * + * `Cache::readMany(array('my_data_1', 'my_data_2)));` + * + * Reading from a specific cache configuration. + * + * `Cache::readMany(array('my_data_1', 'my_data_2), 'long_term');` + * + * @param array $keys an array of keys to fetch from the cache + * @param string $config optional name of the configuration to use. Defaults to 'default' + * @return array An array containing, for each of the given $keys, the cached data or false if cached data could not be + * retreived + */ + public static function readMany($keys, $config = 'default') { + $engine = static::engine($config); + if (!$engine) { + return false; + } + + return $engine->readMany($keys); + } /** * Increment a number under the key and return incremented value. * @@ -290,6 +354,33 @@ public static function delete($key, $config = 'default') { return $engine->delete($key); } +/** + * Delete many keys from the cache. + * + * ### Usage: + * + * Deleting multiple keys from the active cache configuration. + * + * `Cache::deleteMany(array('my_data_1', 'my_data_2'));` + * + * Deleting from a specific cache configuration. + * + * `Cache::deleteMany(array('my_data_1', 'my_data_2), 'long_term');` + * + * @param array $keys Array of cache keys to be deleted + * @param string $config name of the configuration to use. Defaults to 'default' + * @return array of boolean values that are true if the value was successfully deleted, false if it didn't exist or + * couldn't be removed + */ + public static function deleteMany($keys, $config = 'default') { + $engine = static::engine($config); + if (!$engine) { + return false; + } + + return $engine->deleteMany($keys); + } + /** * Delete all keys from the cache. * diff --git a/src/Cache/CacheEngine.php b/src/Cache/CacheEngine.php index 5e47115044b..f1ac845965c 100644 --- a/src/Cache/CacheEngine.php +++ b/src/Cache/CacheEngine.php @@ -97,6 +97,20 @@ public function gc($expires = null) { */ abstract public function write($key, $value); +/** + * Write data for many keys into cache + * + * @param array $data An array of data to be stored in the cache + * @return array of bools for each key provided, true if the data was successfully cached, false on failure + */ + public function writeMany($data) { + $return = array(); + foreach ($data as $key => $value) { + $return[$key] = $this->write($key, $value); + } + return $return; + } + /** * Read a key from the cache * @@ -105,6 +119,21 @@ abstract public function write($key, $value); */ abstract public function read($key); +/** + * Read multiple keys from the cache + * + * @param array $keys An array of identifiers for the data + * @return array For each cache key (given as the array key) the cache data associated or false if the data doesn't + * exist, has expired, or if there was an error fetching it + */ + public function readMany($keys) { + $return = array(); + foreach ($keys as $key) { + $return[$key] = $this->read($key); + } + return $return; + } + /** * Increment a number under the key and return incremented value * @@ -131,6 +160,21 @@ abstract public function decrement($key, $offset = 1); */ abstract public function delete($key); +/** + * Deletes keys from the cache + * + * @param array $keys An array of identifiers for the data + * @return array For each provided cache key (given back as the array key) true if the value was successfully deleted, + * false if it didn't exist or couldn't be removed + */ + public function deleteMany($keys) { + $return = array(); + foreach ($keys as $key) { + $return[$key] = $this->delete($key); + } + return $return; + } + /** * Delete all keys from the cache * diff --git a/tests/TestCase/Cache/CacheTest.php b/tests/TestCase/Cache/CacheTest.php index 1f51864298b..a77216c8b9a 100644 --- a/tests/TestCase/Cache/CacheTest.php +++ b/tests/TestCase/Cache/CacheTest.php @@ -343,6 +343,58 @@ public function testWriteEmptyKey() { Cache::write(null, 'not null', 'tests'); } +/** + * testReadWriteMany method + * + * @return void + */ + public function testReadWriteMany() { + $this->_configCache(); + $data = array( + 'App.falseTest' => false, + 'App.trueTest' => true, + 'App.nullTest' => null, + 'App.zeroTest' => 0, + 'App.zeroTest2' => '0' + ); + Cache::writeMany($data, 'tests'); + + $read = Cache::readMany(array_keys($data), 'tests'); + + $this->assertSame($read['App.falseTest'], false); + $this->assertSame($read['App.trueTest'], true); + $this->assertSame($read['App.nullTest'], null); + $this->assertSame($read['App.zeroTest'], 0); + $this->assertSame($read['App.zeroTest2'], '0'); + } + +/** + * testDeleteMany method + * + * @return void + */ + public function testDeleteMany() { + $this->_configCache(); + $data = array( + 'App.falseTest' => false, + 'App.trueTest' => true, + 'App.nullTest' => null, + 'App.zeroTest' => 0, + 'App.zeroTest2' => '0' + ); + Cache::writeMany(array_merge($data, array('App.keepTest' => 'keepMe')), 'tests'); + + Cache::deleteMany(array_keys($data), 'tests'); + $read = Cache::readMany(array_merge(array_keys($data), array('App.keepTest')), 'tests'); + + $this->assertSame($read['App.falseTest'], false); + $this->assertSame($read['App.trueTest'], false); + $this->assertSame($read['App.nullTest'], false); + $this->assertSame($read['App.zeroTest'], false); + $this->assertSame($read['App.zeroTest2'], false); + $this->assertSame($read['App.keepTest'], 'keepMe'); + } + /** * Test that failed writes cause errors to be triggered. *