From e80600e244b8442cb7c86e99b067966cd59bf2ee Mon Sep 17 00:00:00 2001 From: Pavlo Yatsukhnenko Date: Tue, 19 May 2020 04:11:40 +0300 Subject: Issue #548 (#1649) Adds `Redis::SCAN_PREFIX` and `Redis::SCAN_NOPREFIX` as options to SCAN. See #548 --- redis.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'redis.c') diff --git a/redis.c b/redis.c index 729bcf9b..6c1a7642 100644 --- a/redis.c +++ b/redis.c @@ -723,6 +723,8 @@ static void add_class_constants(zend_class_entry *ce, int is_cluster) { zend_declare_class_constant_long(ce, ZEND_STRL("OPT_SCAN"), REDIS_OPT_SCAN); zend_declare_class_constant_long(ce, ZEND_STRL("SCAN_RETRY"), REDIS_SCAN_RETRY); zend_declare_class_constant_long(ce, ZEND_STRL("SCAN_NORETRY"), REDIS_SCAN_NORETRY); + zend_declare_class_constant_long(ce, ZEND_STRL("SCAN_PREFIX"), REDIS_SCAN_PREFIX); + zend_declare_class_constant_long(ce, ZEND_STRL("SCAN_NOPREFIX"), REDIS_SCAN_NOPREFIX); /* Cluster option to allow for slave failover */ if (is_cluster) { @@ -3462,7 +3464,7 @@ generic_scan_cmd(INTERNAL_FUNCTION_PARAMETERS, REDIS_SCAN_TYPE type) { RedisSock *redis_sock; HashTable *hash; char *pattern = NULL, *cmd, *key = NULL; - int cmd_len, num_elements, key_free = 0; + int cmd_len, num_elements, key_free = 0, pattern_free = 0; size_t key_len = 0, pattern_len = 0; zend_string *match_type = NULL; zend_long count = 0, iter; @@ -3520,6 +3522,10 @@ generic_scan_cmd(INTERNAL_FUNCTION_PARAMETERS, REDIS_SCAN_TYPE type) { key_free = redis_key_prefix(redis_sock, &key, &key_len); } + if (redis_sock->scan & REDIS_SCAN_PREFIX) { + pattern_free = redis_key_prefix(redis_sock, &pattern, &pattern_len); + } + /** * Redis can return to us empty keys, especially in the case where there * are a large number of keys to scan, and we're matching against a @@ -3552,9 +3558,12 @@ generic_scan_cmd(INTERNAL_FUNCTION_PARAMETERS, REDIS_SCAN_TYPE type) { /* Get the number of elements */ hash = Z_ARRVAL_P(return_value); num_elements = zend_hash_num_elements(hash); - } while(redis_sock->scan == REDIS_SCAN_RETRY && iter != 0 && + } while (redis_sock->scan & REDIS_SCAN_RETRY && iter != 0 && num_elements == 0); + /* Free our pattern if it was prefixed */ + if (pattern_free) efree(pattern); + /* Free our key if it was prefixed */ if(key_free) efree(key); -- cgit v1.2.3