]> git.mxchange.org Git - friendica.git/commitdiff
Merge pull request #5848 from nupplaphil/friendica-5847
authorHypolite Petovan <hypolite@mrpetovan.com>
Sun, 7 Oct 2018 21:47:51 +0000 (17:47 -0400)
committerGitHub <noreply@github.com>
Sun, 7 Oct 2018 21:47:51 +0000 (17:47 -0400)
friendica-5847 Console Cache List command doesn't work

15 files changed:
src/Core/Cache.php
src/Core/Cache/AbstractCacheDriver.php
src/Core/Cache/ArrayCache.php
src/Core/Cache/DatabaseCacheDriver.php
src/Core/Cache/ICacheDriver.php
src/Core/Cache/MemcacheCacheDriver.php
src/Core/Cache/MemcachedCacheDriver.php
src/Core/Cache/RedisCacheDriver.php
src/Core/Console/Cache.php
tests/src/Core/Cache/ArrayCacheDriverTest.php
tests/src/Core/Cache/CacheTest.php
tests/src/Core/Cache/DatabaseCacheDriverTest.php
tests/src/Core/Cache/MemcacheCacheDriverTest.php
tests/src/Core/Cache/MemcachedCacheDriverTest.php
tests/src/Core/Cache/RedisCacheDriverTest.php

index ea7807031fde7389479dfb2bad49c1d342094e2c..b239af7d60bad23a8459ec6858769fc94a0e5991 100644 (file)
@@ -51,20 +51,15 @@ class Cache extends \Friendica\BaseObject
        /**
         * @brief Returns all the cache keys sorted alphabetically
         *
-        * @return array|null Null if the driver doesn't support this feature
+        * @param string $prefix Prefix of the keys (optional)
+        *
+        * @return array Empty if the driver doesn't support this feature
         */
-       public static function getAllKeys()
+       public static function getAllKeys($prefix = null)
        {
                $time = microtime(true);
 
-               $return = self::getDriver()->getAllKeys();
-
-               // Keys are prefixed with the node hostname, let's remove it
-               array_walk($return, function (&$value) {
-                       $value = preg_replace('/^' . self::getApp()->get_hostname() . ':/', '', $value);
-               });
-
-               sort($return);
+               $return = self::getDriver()->getAllKeys($prefix);
 
                self::getApp()->save_timestamp($time, 'cache');
 
index 15b822dc3b519f8e0fac9412429991a1f06384f7..1cdecf6ceb0ce6ff9473bdc8f0a8f4647e600298 100644 (file)
@@ -17,8 +17,56 @@ abstract class AbstractCacheDriver extends BaseObject
         * @param string $key   The original key
         * @return string               The cache key used for the cache
         */
-       protected function getCacheKey($key) {
+       protected function getCacheKey($key)
+       {
                // We fetch with the hostname as key to avoid problems with other applications
                return self::getApp()->get_hostname() . ":" . $key;
        }
+
+       /**
+        * @param array $keys   A list of cached keys
+        * @return array        A list of original keys
+        */
+       protected function getOriginalKeys($keys)
+       {
+               if (empty($keys)) {
+                       return [];
+               } else {
+                       // Keys are prefixed with the node hostname, let's remove it
+                       array_walk($keys, function (&$value) {
+                               $value = preg_replace('/^' . self::getApp()->get_hostname() . ':/', '', $value);
+                       });
+
+                       sort($keys);
+
+                       return $keys;
+               }
+       }
+
+       /**
+        * Filters the keys of an array with a given prefix
+        * Returns the filtered keys as an new array
+        *
+        * @param array $array The array, which should get filtered
+        * @param string|null $prefix The prefix (if null, all keys will get returned)
+        *
+        * @return array The filtered array with just the keys
+        */
+       protected function filterArrayKeysByPrefix($array, $prefix = null)
+       {
+               if (empty($prefix)) {
+                       return array_keys($array);
+               } else {
+                       $result = [];
+
+                       foreach (array_keys($array) as $key) {
+                               if (strpos($key, $prefix) === 0) {
+                                       array_push($result, $key);
+                               }
+                       }
+
+                       return $result;
+               }
+
+       }
 }
index 47c9c166808b86b8b53b4bac601223ac2a3c00e3..a99b05788f64e75e46d5d8e4df8c230bdcf6c414 100644 (file)
@@ -22,9 +22,9 @@ class ArrayCache extends AbstractCacheDriver implements IMemoryCacheDriver
        /**
         * (@inheritdoc)
         */
-       public function getAllKeys()
+       public function getAllKeys($prefix = null)
        {
-               return array_keys($this->cachedData);
+               return $this->filterArrayKeysByPrefix($this->cachedData, $prefix);
        }
 
        /**
index 74dfe3991e1ca4beeb818db1bf23f885a5903cb7..d90c6e4f18180f6777a316dbe1cf2d70249ce85f 100644 (file)
@@ -16,11 +16,23 @@ class DatabaseCacheDriver extends AbstractCacheDriver implements ICacheDriver
        /**
         * (@inheritdoc)
         */
-       public function getAllKeys()
+       public function getAllKeys($prefix = null)
        {
-               $stmt = DBA::select('cache', ['k'], ['`expires` >= ?', DateTimeFormat::utcNow()]);
+               if (empty($prefix)) {
+                       $where = ['`expires` >= ?', DateTimeFormat::utcNow()];
+               } else {
+                       $where = ['`expires` >= ? AND `k` LIKE CONCAT(?, \'%\')', DateTimeFormat::utcNow(), $prefix];
+               }
+
+               $stmt = DBA::select('cache', ['k'], $where);
+
+               $keys = [];
+               while ($key = DBA::fetch($stmt)) {
+                       array_push($keys, $key['k']);
+               }
+               DBA::close($stmt);
 
-               return DBA::toArray($stmt);
+               return $keys;
        }
 
        /**
index b77aa03c162de44abea89ac60415e735cc03d5e0..2c04c5992578588611fd08fdefc1dd0d0ffb87f6 100644 (file)
@@ -14,9 +14,11 @@ interface ICacheDriver
        /**
         * Lists all cache keys
         *
-        * @return array|null Null if it isn't supported by the cache driver
+        * @param string prefix optional a prefix to search
+        *
+        * @return array Empty if it isn't supported by the cache driver
         */
-       public function getAllKeys();
+       public function getAllKeys($prefix = null);
 
        /**
         * Fetches cached data according to the key
index 207225b1a269eed59913d633de7c63bdbb2a61fe..fd928c6fcc15ed2a5245f2bca27c664a6f696531 100644 (file)
@@ -43,23 +43,25 @@ class MemcacheCacheDriver extends AbstractCacheDriver implements IMemoryCacheDri
        /**
         * (@inheritdoc)
         */
-       public function getAllKeys()
+       public function getAllKeys($prefix = null)
        {
-               $list = [];
+               $keys = [];
                $allSlabs = $this->memcache->getExtendedStats('slabs');
                foreach ($allSlabs as $slabs) {
                        foreach (array_keys($slabs) as $slabId) {
                                $cachedump = $this->memcache->getExtendedStats('cachedump', (int)$slabId);
-                               foreach ($cachedump as $keys => $arrVal) {
+                               foreach ($cachedump as $key => $arrVal) {
                                        if (!is_array($arrVal)) {
                                                continue;
                                        }
-                                       $list = array_merge($list, array_keys($arrVal));
+                                       $keys = array_merge($keys, array_keys($arrVal));
                                }
                        }
                }
 
-               return $list;
+               $keys = $this->getOriginalKeys($keys);
+
+               return $this->filterArrayKeysByPrefix($keys, $prefix);
        }
 
        /**
index c1d08f33212855d3ef9b8f16df081fa636fbd84d..1a6b2a9aefbfa7d25e9d7369fe6e77b8147e1a91 100644 (file)
@@ -5,6 +5,7 @@ namespace Friendica\Core\Cache;
 use Friendica\Core\Cache;
 
 use Exception;
+use Friendica\Network\HTTPException\InternalServerErrorException;
 use Memcached;
 
 /**
@@ -56,9 +57,16 @@ class MemcachedCacheDriver extends AbstractCacheDriver implements IMemoryCacheDr
        /**
         * (@inheritdoc)
         */
-       public function getAllKeys()
+       public function getAllKeys($prefix = null)
        {
-               return $this->memcached->getAllKeys();
+               $keys = $this->getOriginalKeys($this->memcached->getAllKeys());
+
+               if ($this->memcached->getResultCode() == Memcached::RES_SUCCESS) {
+                       return $this->filterArrayKeysByPrefix($keys, $prefix);
+               } else {
+                       logger('Memcached \'getAllKeys\' failed with ' . $this->memcached->getResultMessage(), LOGGER_ALL);
+                       return [];
+               }
        }
 
        /**
@@ -74,6 +82,8 @@ class MemcachedCacheDriver extends AbstractCacheDriver implements IMemoryCacheDr
 
                if ($this->memcached->getResultCode() === Memcached::RES_SUCCESS) {
                        $return = $value;
+               } else {
+                       logger('Memcached \'get\' failed with ' . $this->memcached->getResultMessage(), LOGGER_ALL);
                }
 
                return $return;
@@ -99,7 +109,6 @@ class MemcachedCacheDriver extends AbstractCacheDriver implements IMemoryCacheDr
                                $value
                        );
                }
-
        }
 
        /**
index f9d00fde21fb4c3366ec8878f5e3f8dcdf4a69df..fcbfab548a6b2bfba0e74e150a7d7b5f505dd9e1 100644 (file)
@@ -41,9 +41,17 @@ class RedisCacheDriver extends AbstractCacheDriver implements IMemoryCacheDriver
        /**
         * (@inheritdoc)
         */
-       public function getAllKeys()
+       public function getAllKeys($prefix = null)
        {
-               return null;
+               if (empty($prefix)) {
+                       $search = '*';
+               } else {
+                       $search = $prefix . '*';
+               }
+
+               $list = $this->redis->keys($this->getCacheKey($search));
+
+               return $this->getOriginalKeys($list);
        }
 
        /**
index af0d771307ffd31bdf6496a72becf39e976feeb9..510c05b04acec6cbb068cfdafb3f9714f70e9f7b 100644 (file)
@@ -105,7 +105,7 @@ HELP;
        private function executeList()
        {
                $prefix = $this->getArgument(1);
-               $keys = Core\Cache::getAllKeys();
+               $keys = Core\Cache::getAllKeys($prefix);
 
                if (empty($prefix)) {
                        $this->out('Listing all cache keys:');
@@ -115,10 +115,8 @@ HELP;
 
                $count = 0;
                foreach ($keys as $key) {
-                       if (empty($prefix) || strpos($key, $prefix) === 0) {
-                               $this->out($key);
-                               $count++;
-                       }
+                       $this->out($key);
+                       $count++;
                }
 
                $this->out($count . ' keys found');
index 0cad6e9c7f5ddd5a9464cd6f4bbab170b078fb40..6863d149ffbf49bd53435a3fd2f583cfc25843f0 100644 (file)
@@ -7,11 +7,6 @@ use Friendica\Core\Cache\ArrayCache;
 
 class ArrayCacheDriverTest extends MemoryCacheTest
 {
-       /**
-        * @var \Friendica\Core\Cache\IMemoryCacheDriver
-        */
-       private $cache;
-
        protected function getInstance()
        {
                $this->cache = new ArrayCache();
index 5c56c2072f4f13add69b2552cc03531fedadab7f..86bf5e7f01fa2a1e115db8aaee1aa9a15dba6dc4 100644 (file)
@@ -2,6 +2,7 @@
 
 namespace Friendica\Test\src\Core\Cache;
 
+use Friendica\Core\Cache\MemcachedCacheDriver;
 use Friendica\Core\Config;
 use Friendica\Test\DatabaseTest;
 use Friendica\Util\DateTimeFormat;
@@ -13,6 +14,12 @@ abstract class CacheTest extends DatabaseTest
         */
        protected $instance;
 
+       /**
+        * @var \Friendica\Core\Cache\IMemoryCacheDriver
+        */
+       protected $cache;
+
+
        abstract protected function getInstance();
 
        protected function setUp()
@@ -29,6 +36,8 @@ abstract class CacheTest extends DatabaseTest
                Config::set('system', 'throttle_limit_week', 100);
                Config::set('system', 'throttle_limit_month', 100);
                Config::set('system', 'theme', 'system_theme');
+
+               $this->instance->clear(false);
        }
 
        /**
@@ -177,4 +186,27 @@ abstract class CacheTest extends DatabaseTest
                $received = $this->instance->get('objVal');
                $this->assertEquals($value, $received, 'Value type changed from ' . gettype($value) . ' to ' . gettype($received));
        }
+
+       /**
+        * @small
+        */
+       public function testGetAllKeys() {
+               if ($this->cache instanceof MemcachedCacheDriver) {
+                       $this->markTestSkipped('Memcached doesn\'t support getAllKeys anymore');
+               }
+
+               $this->assertTrue($this->instance->set('value1', 'test'));
+               $this->assertTrue($this->instance->set('value2', 'test'));
+               $this->assertTrue($this->instance->set('test_value3', 'test'));
+
+               $list = $this->instance->getAllKeys();
+
+               $this->assertContains('value1', $list);
+               $this->assertContains('value2', $list);
+               $this->assertContains('test_value3', $list);
+
+               $list = $this->instance->getAllKeys('test');
+
+               $this->assertContains('test_value3', $list);
+       }
 }
index 5df00fc913581a36d0afffa51f38ecf81424a71b..3cc4a72ed1d6441f6e2e2992401677041c20561e 100644 (file)
@@ -6,11 +6,6 @@ use Friendica\Core\Cache\CacheDriverFactory;
 
 class DatabaseCacheDriverTest extends CacheTest
 {
-       /**
-        * @var \Friendica\Core\Cache\IMemoryCacheDriver
-        */
-       private $cache;
-
        protected function getInstance()
        {
                $this->cache = CacheDriverFactory::create('database');
index 62f7440033f1db0153133ac5c676eeba88ea110a..db85723af16e41cc967e164c79fc878d3f4a5674 100644 (file)
@@ -11,11 +11,6 @@ use Friendica\Core\Cache\CacheDriverFactory;
  */
 class MemcacheCacheDriverTest extends MemoryCacheTest
 {
-       /**
-        * @var \Friendica\Core\Cache\IMemoryCacheDriver
-        */
-       private $cache;
-
        protected function getInstance()
        {
                $this->cache = CacheDriverFactory::create('memcache');
index 5a07814a383760618ff4ddf9f6e316288119be30..fba5c4a958c4347053305c948b0b40a03db271ff 100644 (file)
@@ -11,11 +11,6 @@ use Friendica\Core\Cache\CacheDriverFactory;
  */
 class MemcachedCacheDriverTest extends MemoryCacheTest
 {
-       /**
-        * @var \Friendica\Core\Cache\IMemoryCacheDriver
-        */
-       private $cache;
-
        protected function getInstance()
        {
                $this->cache = CacheDriverFactory::create('memcached');
index 460c1184ba47b5d2c684c8996b9424c43edd69de..0ee73945b9620ac68b3bdd16f201dce67080624d 100644 (file)
@@ -11,11 +11,6 @@ use Friendica\Core\Cache\CacheDriverFactory;
  */
 class RedisCacheDriverTest extends MemoryCacheTest
 {
-       /**
-        * @var \Friendica\Core\Cache\IMemoryCacheDriver
-        */
-       private $cache;
-
        protected function getInstance()
        {
                $this->cache = CacheDriverFactory::create('redis');