mirror of
https://github.com/php-win-ext/phpredis.git
synced 2026-04-26 10:08:05 +02:00
SRANDMEMBER
Implemented SRANDMEMBER command for Redis and RedisCluster
This commit is contained in:
@@ -1339,49 +1339,24 @@ PHP_METHOD(Redis, sPop)
|
||||
*/
|
||||
PHP_METHOD(Redis, sRandMember)
|
||||
{
|
||||
zval *object;
|
||||
char *cmd;
|
||||
int cmd_len;
|
||||
short have_count;
|
||||
RedisSock *redis_sock;
|
||||
char *key = NULL, *cmd;
|
||||
int key_len, cmd_len, key_free = 0;
|
||||
long count;
|
||||
|
||||
/* Parse our params */
|
||||
if(zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os|l",
|
||||
&object, redis_ce, &key, &key_len, &count) == FAILURE) {
|
||||
// Grab our socket, validate call
|
||||
if(redis_sock_get(getThis(), &redis_sock TSRMLS_CC, 0)<0 ||
|
||||
redis_srandmember_cmd(INTERNAL_FUNCTION_PARAM_PASSTHRU, redis_sock,
|
||||
&cmd, &cmd_len, NULL, NULL, &have_count)==FAILURE)
|
||||
{
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
/* Get our redis socket */
|
||||
if(redis_sock_get(object, &redis_sock TSRMLS_CC, 0) < 0) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
/* Prefix our key if necissary */
|
||||
key_free = redis_key_prefix(redis_sock, &key, &key_len);
|
||||
|
||||
/* If we have two arguments, we're running with an optional COUNT, which will return */
|
||||
/* a multibulk reply. Without the argument we'll return a string response */
|
||||
if(ZEND_NUM_ARGS() == 2) {
|
||||
// Construct our command with count
|
||||
cmd_len = redis_cmd_format_static(&cmd, "SRANDMEMBER", "sl",
|
||||
key, key_len, count);
|
||||
} else {
|
||||
// Construct our command
|
||||
cmd_len = redis_cmd_format_static(&cmd, "SRANDMEMBER", "s",
|
||||
key, key_len);
|
||||
}
|
||||
|
||||
/* Free our key if we prefixed it */
|
||||
if(key_free) efree(key);
|
||||
|
||||
/* Process our command */
|
||||
REDIS_PROCESS_REQUEST(redis_sock, cmd, cmd_len);
|
||||
|
||||
/* Either bulk or multi-bulk depending on argument count */
|
||||
if(ZEND_NUM_ARGS() == 2) {
|
||||
if(have_count) {
|
||||
IF_ATOMIC() {
|
||||
if(redis_sock_read_multibulk_reply(INTERNAL_FUNCTION_PARAM_PASSTHRU,
|
||||
redis_sock, NULL, NULL) < 0)
|
||||
redis_sock, NULL, NULL)<0)
|
||||
{
|
||||
RETURN_FALSE;
|
||||
}
|
||||
@@ -1390,7 +1365,7 @@ PHP_METHOD(Redis, sRandMember)
|
||||
} else {
|
||||
IF_ATOMIC() {
|
||||
redis_string_response(INTERNAL_FUNCTION_PARAM_PASSTHRU, redis_sock,
|
||||
NULL, NULL);
|
||||
NULL, NULL);
|
||||
}
|
||||
REDIS_PROCESS_RESPONSE(redis_string_response);
|
||||
}
|
||||
|
||||
@@ -62,6 +62,7 @@ zend_function_entry redis_cluster_functions[] = {
|
||||
PHP_ME(RedisCluster, scard, NULL, ZEND_ACC_PUBLIC)
|
||||
PHP_ME(RedisCluster, smembers, NULL, ZEND_ACC_PUBLIC)
|
||||
PHP_ME(RedisCluster, sismember, NULL, ZEND_ACC_PUBLIC)
|
||||
PHP_ME(RedisCluster, srandmember, NULL, ZEND_ACC_PUBLIC)
|
||||
PHP_ME(RedisCluster, strlen, NULL, ZEND_ACC_PUBLIC)
|
||||
PHP_ME(RedisCluster, persist, NULL, ZEND_ACC_PUBLIC)
|
||||
PHP_ME(RedisCluster, ttl, NULL, ZEND_ACC_PUBLIC)
|
||||
@@ -361,6 +362,35 @@ PHP_METHOD(RedisCluster, spop) {
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ proto string|array RedisCluster::srandmember(string key, [long count]) */
|
||||
PHP_METHOD(RedisCluster, srandmember) {
|
||||
redisCluster *c = GET_CONTEXT();
|
||||
char *cmd; int cmd_len; short slot;
|
||||
short have_count;
|
||||
|
||||
if(redis_srandmember_cmd(INTERNAL_FUNCTION_PARAM_PASSTHRU, c->flags,
|
||||
&cmd, &cmd_len, &slot, NULL, &have_count)
|
||||
==FAILURE)
|
||||
{
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
if(cluster_send_command(c,slot,cmd,cmd_len TSRMLS_CC)<0 || c->err!=NULL) {
|
||||
efree(cmd);
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
// Clean up command
|
||||
efree(cmd);
|
||||
|
||||
// Response type differs if we use WITHSCORES or not
|
||||
if(have_count) {
|
||||
cluster_mbulk_resp(INTERNAL_FUNCTION_PARAM_PASSTHRU, c, NULL);
|
||||
} else {
|
||||
cluster_bulk_resp(INTERNAL_FUNCTION_PARAM_PASSTHRU, c, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/* {{{ proto string RedisCluster::strlen(string key) */
|
||||
PHP_METHOD(RedisCluster, strlen) {
|
||||
CLUSTER_PROCESS_KW_CMD("STRLEN", redis_key_cmd, cluster_bulk_resp);
|
||||
|
||||
@@ -138,6 +138,7 @@ PHP_METHOD(RedisCluster, pfmerge);
|
||||
PHP_METHOD(RedisCluster, restore);
|
||||
PHP_METHOD(RedisCluster, setrange);
|
||||
PHP_METHOD(RedisCluster, smove);
|
||||
PHP_METHOD(RedisCluster, srandmember);
|
||||
PHP_METHOD(RedisCluster, zrange);
|
||||
PHP_METHOD(RedisCluster, zrevrange);
|
||||
#endif
|
||||
|
||||
@@ -1259,4 +1259,43 @@ int redis_hsetnx_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
|
||||
cmd, cmd_len, slot);
|
||||
}
|
||||
|
||||
/* SRANDMEMBER */
|
||||
int redis_srandmember_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
|
||||
char **cmd, int *cmd_len, short *slot, void **ctx,
|
||||
short *have_count)
|
||||
{
|
||||
char *key;
|
||||
int key_len, key_free;
|
||||
long count;
|
||||
|
||||
if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &key, &key_len,
|
||||
&count)==FAILURE)
|
||||
{
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
// Prefix key if requested
|
||||
key_free = redis_key_prefix(redis_sock, &key, &key_len);
|
||||
|
||||
// Set our have count flag
|
||||
*have_count = ZEND_NUM_ARGS() == 2;
|
||||
|
||||
// Two args means we have the optional COUNT
|
||||
if(*have_count) {
|
||||
*cmd_len = redis_cmd_format_static(cmd, "SRANDMEMBER", "sl", key,
|
||||
key_len, count);
|
||||
} else {
|
||||
*cmd_len = redis_cmd_format_static(cmd, "SRANDMEMBER", "s", key,
|
||||
key_len);
|
||||
}
|
||||
|
||||
// Set slot
|
||||
CMD_SET_SLOT(slot,key,key_len);
|
||||
|
||||
// Cleanup
|
||||
if(key_free) efree(key);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/* vim: set tabstop=4 softtabstops=4 noexpandtab shiftwidth=4: */
|
||||
|
||||
@@ -113,6 +113,9 @@ int redis_hset_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
|
||||
int redis_hsetnx_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
|
||||
char **cmd, int *cmd_len, short *slot, void **ctx);
|
||||
|
||||
int redis_srandmember_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
|
||||
char **cmd, int *cmd_len, short *slot, void **ctx,
|
||||
short *have_count);
|
||||
#endif
|
||||
|
||||
/* vim: set tabstop=4 softtabstops=4 noexpandtab shiftwidth=4: */
|
||||
|
||||
Reference in New Issue
Block a user