Implement VLINKS command

This commit is contained in:
michael-grunder
2025-07-31 20:36:27 -07:00
committed by Michael Grunder
parent ea11d62aec
commit 7f9b1f416e
14 changed files with 178 additions and 4 deletions

View File

@@ -2527,6 +2527,27 @@ cluster_vinfo_resp(INTERNAL_FUNCTION_PARAMETERS, redisCluster *c, void *ctx) {
add_next_index_zval(&c->multi_resp, &z_ret);
}
PHP_REDIS_API void
cluster_vlinks_resp(INTERNAL_FUNCTION_PARAMETERS, redisCluster *c, void *ctx) {
zval z_ret;
if (c->reply_len < 0) {
CLUSTER_RETURN_FALSE(c);
}
if (redis_read_vlinks_response(c->cmd_sock, &z_ret, c->reply_len, ctx)
!= SUCCESS)
{
CLUSTER_RETURN_FALSE(c);
}
if (CLUSTER_IS_ATOMIC(c)) {
RETURN_ZVAL(&z_ret, 0, 1);
} else {
add_next_index_zval(&c->multi_resp, &z_ret);
}
}
/* XINFO */
PHP_REDIS_API void
cluster_xinfo_resp(INTERNAL_FUNCTION_PARAMETERS, redisCluster *c, void *ctx)

View File

@@ -450,6 +450,8 @@ PHP_REDIS_API void cluster_unsub_resp(INTERNAL_FUNCTION_PARAMETERS, redisCluster
void *ctx);
PHP_REDIS_API void cluster_vinfo_resp(INTERNAL_FUNCTION_PARAMETERS, redisCluster *c,
void *ctx);
PHP_REDIS_API void cluster_vlinks_resp(INTERNAL_FUNCTION_PARAMETERS, redisCluster *c,
void *ctx);
PHP_REDIS_API void cluster_zrange_resp(INTERNAL_FUNCTION_PARAMETERS, redisCluster *c,
void *ctx);

View File

@@ -2623,6 +2623,63 @@ redis_vemb_reply(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
return SUCCESS;
}
PHP_REDIS_API int
redis_read_vlinks_response(RedisSock *redis_sock, zval *z_ret,
long long elements, void *ctx)
{
long long i;
zval z_ele;
int links;
array_init_size(z_ret, elements);
for (i = 0; i < elements; i++) {
if (read_mbulk_header(redis_sock, &links) < 0)
return FAILURE;
array_init(&z_ele);
redis_mbulk_reply_loop(redis_sock, &z_ele, links, UNSERIALIZE_KEYS);
if (ctx == PHPREDIS_CTX_PTR) {
array_zip_values_and_scores(redis_sock, &z_ele, SCORE_DECODE_DOUBLE);
}
add_next_index_zval(z_ret, &z_ele);
}
return SUCCESS;
}
PHP_REDIS_API int
redis_vlinks_reply(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
zval *z_tab, void *ctx)
{
int elements;
zval z_ret;
ZVAL_FALSE(&z_ret);
if (read_mbulk_header(redis_sock, &elements) < 0)
goto fail;
/* TODO: Figure out if we want `false` or `[]` here */
if (elements < 0) {
REDIS_RETURN_ZVAL(redis_sock, z_tab, z_ret);
return SUCCESS;
}
if (redis_read_vlinks_response(redis_sock, &z_ret, elements, ctx) != SUCCESS)
goto fail;
REDIS_RETURN_ZVAL(redis_sock, z_tab, z_ret);
return SUCCESS;
fail:
zval_dtor(&z_ret);
REDIS_RESPONSE_ERROR(redis_sock, z_tab);
return FAILURE;
}
PHP_REDIS_API int
redis_xinfo_reply(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
zval *z_tab, void *ctx)

View File

@@ -133,6 +133,11 @@ PHP_REDIS_API int redis_vemb_reply(INTERNAL_FUNCTION_PARAMETERS,
PHP_REDIS_API int redis_read_vemb_response(RedisSock *redis_sock, zval *z_ret,
long long count);
PHP_REDIS_API int redis_read_vlinks_response(RedisSock *redis_sock, zval *z_ret,
long long elements, void *ctx);
PHP_REDIS_API int redis_vlinks_reply(INTERNAL_FUNCTION_PARAMETERS,
RedisSock *redis_sock, zval *z_tab, void *ctx);
PHP_REDIS_API int redis_pubsub_response(INTERNAL_FUNCTION_PARAMETERS,
RedisSock *redis_sock, zval *z_tab, void *ctx);
PHP_REDIS_API int redis_subscribe_response(INTERNAL_FUNCTION_PARAMETERS,

View File

@@ -3213,6 +3213,10 @@ PHP_METHOD(Redis, vsetattr) {
REDIS_PROCESS_CMD(vsetattr, redis_long_response);
}
PHP_METHOD(Redis, vlinks) {
REDIS_PROCESS_CMD(vlinks, redis_vlinks_reply);
}
/*
* Streams
*/

View File

@@ -4312,6 +4312,17 @@ class Redis {
*/
public function vsetattr(string $key, mixed $member, array|string $attributes): Redis|int|false;
/**
* Get any adajcent values for a member of a vector set.
*
* @param string $key The vector set to query.
* @param mixed $member The member to query.
* @param bool $withscores If set to `true`, the scores of the adjacent values will be returned.
*
* @return Redis|array|false An array of adjacent values and their scores, or false on failure.
*/
public function vlinks(string $key, mixed $member, bool $withscores = false): Redis|array|false;
/**
* Truncate a STREAM key in various ways.
*

View File

@@ -1,5 +1,5 @@
/* This is a generated file, edit the .stub.php file instead.
* Stub hash: 4f62aadbf7d71be1cff70adecdb4e9565acb9d35 */
* Stub hash: b946fc56310f3c069255e85b0fd733f96232c933 */
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Redis___construct, 0, 0, 0)
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, options, IS_ARRAY, 1, "null")
@@ -1104,6 +1104,12 @@ ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_class_Redis_vsetattr, 0, 3,
ZEND_ARG_TYPE_MASK(0, attributes, MAY_BE_ARRAY|MAY_BE_STRING, NULL)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_class_Redis_vlinks, 0, 2, Redis, MAY_BE_ARRAY|MAY_BE_FALSE)
ZEND_ARG_TYPE_INFO(0, key, IS_STRING, 0)
ZEND_ARG_TYPE_INFO(0, member, IS_MIXED, 0)
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, withscores, _IS_BOOL, 0, "false")
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_class_Redis_xtrim, 0, 2, Redis, MAY_BE_LONG|MAY_BE_FALSE)
ZEND_ARG_TYPE_INFO(0, key, IS_STRING, 0)
ZEND_ARG_TYPE_INFO(0, threshold, IS_STRING, 0)
@@ -1521,6 +1527,7 @@ ZEND_METHOD(Redis, vemb);
ZEND_METHOD(Redis, vrandmember);
ZEND_METHOD(Redis, vrem);
ZEND_METHOD(Redis, vsetattr);
ZEND_METHOD(Redis, vlinks);
ZEND_METHOD(Redis, xtrim);
ZEND_METHOD(Redis, zAdd);
ZEND_METHOD(Redis, zCard);
@@ -1806,6 +1813,7 @@ static const zend_function_entry class_Redis_methods[] = {
ZEND_ME(Redis, vrandmember, arginfo_class_Redis_vrandmember, ZEND_ACC_PUBLIC)
ZEND_ME(Redis, vrem, arginfo_class_Redis_vrem, ZEND_ACC_PUBLIC)
ZEND_ME(Redis, vsetattr, arginfo_class_Redis_vsetattr, ZEND_ACC_PUBLIC)
ZEND_ME(Redis, vlinks, arginfo_class_Redis_vlinks, ZEND_ACC_PUBLIC)
ZEND_ME(Redis, xtrim, arginfo_class_Redis_xtrim, ZEND_ACC_PUBLIC)
ZEND_ME(Redis, zAdd, arginfo_class_Redis_zAdd, ZEND_ACC_PUBLIC)
ZEND_ME(Redis, zCard, arginfo_class_Redis_zCard, ZEND_ACC_PUBLIC)

View File

@@ -3213,6 +3213,10 @@ PHP_METHOD(RedisCluster, vrem) {
CLUSTER_PROCESS_KW_CMD("VREM", redis_kv_cmd, cluster_long_resp, 0);
}
PHP_METHOD(RedisCluster, vlinks) {
CLUSTER_PROCESS_CMD(vlinks, cluster_vlinks_resp, 1);
}
/* {{{ proto long RedisCluster::xack(string key, string group, array ids) }}} */
PHP_METHOD(RedisCluster, xack) {
CLUSTER_PROCESS_CMD(xack, cluster_long_resp, 0);

View File

@@ -1103,6 +1103,11 @@ class RedisCluster {
*/
public function vrem(string $key, mixed $member): RedisCluster|int|false;
/**
* @see Redis::vlinks
*/
public function vlinks(string $key, mixed $member, bool $withscores = false): RedisCluster|array|false;
/**
* @see Redis::xack
*/

View File

@@ -1,5 +1,5 @@
/* This is a generated file, edit the .stub.php file instead.
* Stub hash: 3711907dacfa040f9670181e005bd8daaec146af */
* Stub hash: 62909e1180a5d48d447f8de46ae3a70f60e7d6bb */
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_RedisCluster___construct, 0, 0, 1)
ZEND_ARG_TYPE_INFO(0, name, IS_STRING, 1)
@@ -914,6 +914,12 @@ ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_class_RedisCluster_vrem, 0,
ZEND_ARG_TYPE_INFO(0, member, IS_MIXED, 0)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_class_RedisCluster_vlinks, 0, 2, RedisCluster, MAY_BE_ARRAY|MAY_BE_FALSE)
ZEND_ARG_TYPE_INFO(0, key, IS_STRING, 0)
ZEND_ARG_TYPE_INFO(0, member, IS_MIXED, 0)
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, withscores, _IS_BOOL, 0, "false")
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_class_RedisCluster_xack, 0, 3, RedisCluster, MAY_BE_LONG|MAY_BE_FALSE)
ZEND_ARG_TYPE_INFO(0, key, IS_STRING, 0)
ZEND_ARG_TYPE_INFO(0, group, IS_STRING, 0)
@@ -1354,6 +1360,7 @@ ZEND_METHOD(RedisCluster, vinfo);
ZEND_METHOD(RedisCluster, vemb);
ZEND_METHOD(RedisCluster, vrandmember);
ZEND_METHOD(RedisCluster, vrem);
ZEND_METHOD(RedisCluster, vlinks);
ZEND_METHOD(RedisCluster, xack);
ZEND_METHOD(RedisCluster, xadd);
ZEND_METHOD(RedisCluster, xclaim);
@@ -1606,6 +1613,7 @@ static const zend_function_entry class_RedisCluster_methods[] = {
ZEND_ME(RedisCluster, vemb, arginfo_class_RedisCluster_vemb, ZEND_ACC_PUBLIC)
ZEND_ME(RedisCluster, vrandmember, arginfo_class_RedisCluster_vrandmember, ZEND_ACC_PUBLIC)
ZEND_ME(RedisCluster, vrem, arginfo_class_RedisCluster_vrem, ZEND_ACC_PUBLIC)
ZEND_ME(RedisCluster, vlinks, arginfo_class_RedisCluster_vlinks, ZEND_ACC_PUBLIC)
ZEND_ME(RedisCluster, xack, arginfo_class_RedisCluster_xack, ZEND_ACC_PUBLIC)
ZEND_ME(RedisCluster, xadd, arginfo_class_RedisCluster_xadd, ZEND_ACC_PUBLIC)
ZEND_ME(RedisCluster, xclaim, arginfo_class_RedisCluster_xclaim, ZEND_ACC_PUBLIC)

View File

@@ -1,5 +1,5 @@
/* This is a generated file, edit the .stub.php file instead.
* Stub hash: 3711907dacfa040f9670181e005bd8daaec146af */
* Stub hash: 62909e1180a5d48d447f8de46ae3a70f60e7d6bb */
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_RedisCluster___construct, 0, 0, 1)
ZEND_ARG_INFO(0, name)
@@ -771,6 +771,12 @@ ZEND_END_ARG_INFO()
#define arginfo_class_RedisCluster_vrem arginfo_class_RedisCluster_hexists
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_RedisCluster_vlinks, 0, 0, 2)
ZEND_ARG_INFO(0, key)
ZEND_ARG_INFO(0, member)
ZEND_ARG_INFO(0, withscores)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_RedisCluster_xack, 0, 0, 3)
ZEND_ARG_INFO(0, key)
ZEND_ARG_INFO(0, group)
@@ -1186,6 +1192,7 @@ ZEND_METHOD(RedisCluster, vinfo);
ZEND_METHOD(RedisCluster, vemb);
ZEND_METHOD(RedisCluster, vrandmember);
ZEND_METHOD(RedisCluster, vrem);
ZEND_METHOD(RedisCluster, vlinks);
ZEND_METHOD(RedisCluster, xack);
ZEND_METHOD(RedisCluster, xadd);
ZEND_METHOD(RedisCluster, xclaim);
@@ -1438,6 +1445,7 @@ static const zend_function_entry class_RedisCluster_methods[] = {
ZEND_ME(RedisCluster, vemb, arginfo_class_RedisCluster_vemb, ZEND_ACC_PUBLIC)
ZEND_ME(RedisCluster, vrandmember, arginfo_class_RedisCluster_vrandmember, ZEND_ACC_PUBLIC)
ZEND_ME(RedisCluster, vrem, arginfo_class_RedisCluster_vrem, ZEND_ACC_PUBLIC)
ZEND_ME(RedisCluster, vlinks, arginfo_class_RedisCluster_vlinks, ZEND_ACC_PUBLIC)
ZEND_ME(RedisCluster, xack, arginfo_class_RedisCluster_xack, ZEND_ACC_PUBLIC)
ZEND_ME(RedisCluster, xadd, arginfo_class_RedisCluster_xadd, ZEND_ACC_PUBLIC)
ZEND_ME(RedisCluster, xclaim, arginfo_class_RedisCluster_xclaim, ZEND_ACC_PUBLIC)

View File

@@ -7039,6 +7039,36 @@ redis_vemb_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
return SUCCESS;
}
int
redis_vlinks_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
char **cmd, int *cmd_len, short *slot, void **ctx)
{
zend_bool withscores = false;
smart_string cmdstr = {0};
zend_string *key;
zval *member;
ZEND_PARSE_PARAMETERS_START(2, 3) {
Z_PARAM_STR(key)
Z_PARAM_ZVAL(member)
Z_PARAM_OPTIONAL
Z_PARAM_BOOL(withscores)
} ZEND_PARSE_PARAMETERS_END_EX(return FAILURE);
REDIS_CMD_INIT_SSTR_STATIC(&cmdstr, 2 + !!withscores, "VLINKS");
redis_cmd_append_sstr_key_zstr(&cmdstr, key, redis_sock, slot);
redis_cmd_append_sstr_zval(&cmdstr, member, redis_sock);
if (withscores) {
REDIS_CMD_APPEND_SSTR_STATIC(&cmdstr, "WITHSCORES");
*ctx = PHPREDIS_CTX_PTR;
}
*cmd = cmdstr.c;
*cmd_len = cmdstr.len;
return SUCCESS;
}
int
redis_vsetattr_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
char **cmd, int *cmd_len, short *slot, void **ctx)

View File

@@ -355,6 +355,9 @@ int redis_vemb_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
int redis_vsetattr_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
char **cmd, int *cmd_len, short *slot, void **ctx);
int redis_vlinks_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
char **cmd, int *cmd_len, short *slot, void **ctx);
int redis_xadd_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
char **cmd, int *cmd_len, short *slot, void **ctx);

View File

@@ -1,5 +1,5 @@
/* This is a generated file, edit the .stub.php file instead.
* Stub hash: 4f62aadbf7d71be1cff70adecdb4e9565acb9d35 */
* Stub hash: b946fc56310f3c069255e85b0fd733f96232c933 */
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Redis___construct, 0, 0, 0)
ZEND_ARG_INFO(0, options)
@@ -978,6 +978,12 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Redis_vsetattr, 0, 0, 3)
ZEND_ARG_INFO(0, attributes)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Redis_vlinks, 0, 0, 2)
ZEND_ARG_INFO(0, key)
ZEND_ARG_INFO(0, member)
ZEND_ARG_INFO(0, withscores)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Redis_xtrim, 0, 0, 2)
ZEND_ARG_INFO(0, key)
ZEND_ARG_INFO(0, threshold)
@@ -1356,6 +1362,7 @@ ZEND_METHOD(Redis, vemb);
ZEND_METHOD(Redis, vrandmember);
ZEND_METHOD(Redis, vrem);
ZEND_METHOD(Redis, vsetattr);
ZEND_METHOD(Redis, vlinks);
ZEND_METHOD(Redis, xtrim);
ZEND_METHOD(Redis, zAdd);
ZEND_METHOD(Redis, zCard);
@@ -1641,6 +1648,7 @@ static const zend_function_entry class_Redis_methods[] = {
ZEND_ME(Redis, vrandmember, arginfo_class_Redis_vrandmember, ZEND_ACC_PUBLIC)
ZEND_ME(Redis, vrem, arginfo_class_Redis_vrem, ZEND_ACC_PUBLIC)
ZEND_ME(Redis, vsetattr, arginfo_class_Redis_vsetattr, ZEND_ACC_PUBLIC)
ZEND_ME(Redis, vlinks, arginfo_class_Redis_vlinks, ZEND_ACC_PUBLIC)
ZEND_ME(Redis, xtrim, arginfo_class_Redis_xtrim, ZEND_ACC_PUBLIC)
ZEND_ME(Redis, zAdd, arginfo_class_Redis_zAdd, ZEND_ACC_PUBLIC)
ZEND_ME(Redis, zCard, arginfo_class_Redis_zCard, ZEND_ACC_PUBLIC)