diff --git a/php_redis.h b/php_redis.h index 0368b17..96a0f39 100644 --- a/php_redis.h +++ b/php_redis.h @@ -115,6 +115,7 @@ PHP_METHOD(Redis, zRevRange); PHP_METHOD(Redis, zRangeByScore); PHP_METHOD(Redis, zRangeByLex); PHP_METHOD(Redis, zRevRangeByScore); +PHP_METHOD(Redis, zRangeByLex); PHP_METHOD(Redis, zCount); PHP_METHOD(Redis, zDeleteRangeByScore); PHP_METHOD(Redis, zDeleteRangeByRank); diff --git a/redis.c b/redis.c index 5e38601..a715741 100644 --- a/redis.c +++ b/redis.c @@ -2003,6 +2003,13 @@ PHP_METHOD(Redis, zRevRangeByScore) { } /* }}} */ +/* {{{ proto array Redis::zRangeByLex(string key, string min, string max, [ + * offset, limit]) */ +PHP_METHOD(Redis, zRangeByLex) { + REDIS_PROCESS_CMD(zrangebylex, redis_sock_read_multibulk_reply); +} +/* }}} */ + /* {{{ proto long Redis::zDelete(string key, string member) */ PHP_METHOD(Redis, zDelete) { diff --git a/redis_cluster.c b/redis_cluster.c index 00977ab..13d8847 100644 --- a/redis_cluster.c +++ b/redis_cluster.c @@ -154,6 +154,8 @@ zend_function_entry redis_cluster_functions[] = { PHP_ME(RedisCluster, zrange, NULL, ZEND_ACC_PUBLIC) PHP_ME(RedisCluster, zrevrange, NULL, ZEND_ACC_PUBLIC) PHP_ME(RedisCluster, zrangebyscore, NULL, ZEND_ACC_PUBLIC) + PHP_ME(RedisCluster, zrevrangebyscore, NULL, ZEND_ACC_PUBLIC) + PHP_ME(RedisCluster, zrangebylex, NULL, ZEND_ACC_PUBLIC) PHP_ME(RedisCluster, zunionstore, NULL, ZEND_ACC_PUBLIC) PHP_ME(RedisCluster, zinterstore, NULL, ZEND_ACC_PUBLIC) PHP_ME(RedisCluster, zrem, NULL, ZEND_ACC_PUBLIC) @@ -1409,6 +1411,12 @@ PHP_METHOD(RedisCluster, zrevrangebyscore) { } /* }}} */ +/* {{{ proto RedisCluster::zrangebylex(string key, string min, string max, [ + * LIMIT offset count) */ +PHP_METHOD(RedisCluster, zrangebylex) { + CLUSTER_PROCESS_CMD(zrangebylex, cluster_mbulk_resp); +} +/* }}} */ /* {{{ proto RedisCluster::sort(string key, array options) */ PHP_METHOD(RedisCluster, sort) { diff --git a/redis_cluster.h b/redis_cluster.h index e063510..36228df 100644 --- a/redis_cluster.h +++ b/redis_cluster.h @@ -212,6 +212,8 @@ PHP_METHOD(RedisCluster, srandmember); PHP_METHOD(RedisCluster, zrange); PHP_METHOD(RedisCluster, zrevrange); PHP_METHOD(RedisCluster, zrangebyscore); +PHP_METHOD(RedisCluster, zrevrangebyscore); +PHP_METHOD(RedisCluster, zrangebylex); PHP_METHOD(RedisCluster, zunionstore); PHP_METHOD(RedisCluster, zinterstore); PHP_METHOD(RedisCluster, sort); diff --git a/redis_commands.c b/redis_commands.c index 2b07a22..48692f8 100644 --- a/redis_commands.c +++ b/redis_commands.c @@ -2398,6 +2398,60 @@ int redis_sdiffstore_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, "SDIFFSTORE", sizeof("SDIFFSTORE")-1, 2, 0, cmd, cmd_len, slot); } +/* ZRANGEBYLEX */ +int redis_zrangebylex_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, + char **cmd, int *cmd_len, short *slot, void **ctx) +{ + char *key, *min, *max; + int key_len, min_len, max_len, key_free; + long offset, count; + int argc = ZEND_NUM_ARGS(); + + /* We need either 3 or 5 arguments for this to be valid */ + if(argc != 3 && argc != 5) { + php_error_docref(0 TSRMLS_CC, E_WARNING, + "Must pass either 3 or 5 arguments"); + return FAILURE; + } + + if(zend_parse_parameters(argc TSRMLS_CC, "sss|ll", &key, + &key_len, &min, &min_len, &max, &max_len, + &offset, &count)==FAILURE) + { + return FAILURE; + } + + /* min and max must start with '(' or '[' */ + if(min_len < 1 || max_len < 1 || (min[0] != '(' && min[0] != '[') || + (max[0] != '(' && max[0] != '[')) + { + php_error_docref(0 TSRMLS_CC, E_WARNING, + "min and max arguments must start with '[' or '('"); + return FAILURE; + } + + /* Prefix key */ + key_free = redis_key_prefix(redis_sock, &key, &key_len); + + /* Construct command */ + if(argc == 3) { + *cmd_len = redis_cmd_format_static(cmd, "ZRANGEBYLEX", "sss", key, + key_len, min, min_len, max, max_len); + } else { + *cmd_len = redis_cmd_format_static(cmd, "ZRANGEBYLEX", "ssssll", key, + key_len, min, min_len, max, max_len, "LIMIT", sizeof("LIMIT")-1, + offset, count); + } + + /* Pick our slot */ + CMD_SET_SLOT(slot,key,key_len); + + /* Free key if we prefixed */ + if(key_free) efree(key); + + return SUCCESS; +} + /* * Redis commands that don't deal with the server at all. The RedisSock* * pointer is the only thing retreived differently, so we just take that diff --git a/redis_commands.h b/redis_commands.h index 64a8a0c..08763c2 100644 --- a/redis_commands.h +++ b/redis_commands.h @@ -197,6 +197,9 @@ int redis_sdiff_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, int redis_sdiffstore_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, char **cmd, int *cmd_len, short *slot, void **ctx); +int redis_zrangebylex_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, + char **cmd, int *cmd_len, short *slot, void **ctx); + int redis_fmt_scan_cmd(char **cmd, REDIS_SCAN_TYPE type, char *key, int key_len, long it, char *pat, int pat_len, long count);