Add getWithMeta method

This commit is contained in:
Pavlo Yatsukhnenko
2025-01-30 20:15:00 +02:00
parent abb0f6ccc8
commit 9036ffca6a
16 changed files with 195 additions and 59 deletions

View File

@@ -1677,27 +1677,33 @@ PHP_REDIS_API void cluster_bulk_resp(INTERNAL_FUNCTION_PARAMETERS, redisCluster
void *ctx)
{
char *resp;
zval z_unpacked, z_ret, *zv;
// Make sure we can read the response
if (c->reply_type != TYPE_BULK ||
(resp = redis_sock_read_bulk_reply(c->cmd_sock, c->reply_len)) == NULL)
{
CLUSTER_RETURN_FALSE(c);
if (c->reply_type != TYPE_BULK) {
ZVAL_FALSE(&z_unpacked);
c->reply_len = 0;
} else if ((resp = redis_sock_read_bulk_reply(c->cmd_sock, c->reply_len)) == NULL) {
ZVAL_FALSE(&z_unpacked);
} else {
if (!redis_unpack(c->flags, resp, c->reply_len, &z_unpacked)) {
ZVAL_STRINGL_FAST(&z_unpacked, resp, c->reply_len);
}
efree(resp);
}
if (c->flags->flags & PHPREDIS_WITH_METADATA) {
redis_with_metadata(&z_ret, &z_unpacked, c->reply_len);
zv = &z_ret;
} else {
zv = &z_unpacked;
}
if (CLUSTER_IS_ATOMIC(c)) {
if (!redis_unpack(c->flags, resp, c->reply_len, return_value)) {
CLUSTER_RETURN_STRING(c, resp, c->reply_len);
}
RETVAL_ZVAL(zv, 0, 1);
} else {
zval z_unpacked;
if (redis_unpack(c->flags, resp, c->reply_len, &z_unpacked)) {
add_next_index_zval(&c->multi_resp, &z_unpacked);
} else {
add_next_index_stringl(&c->multi_resp, resp, c->reply_len);
}
add_next_index_zval(&c->multi_resp, zv);
}
efree(resp);
}
/* Bulk response where we expect a double */
@@ -2553,8 +2559,9 @@ PHP_REDIS_API void cluster_multi_mbulk_resp(INTERNAL_FUNCTION_PARAMETERS,
redisCluster *c, void *ctx)
{
zval *multi_resp = &c->multi_resp;
array_init(multi_resp);
uint8_t flags = c->flags->flags;
array_init(multi_resp);
clusterFoldItem *fi = c->multi_head;
while (fi) {
/* Make sure our transaction didn't fail here */
@@ -2570,7 +2577,9 @@ PHP_REDIS_API void cluster_multi_mbulk_resp(INTERNAL_FUNCTION_PARAMETERS,
RETURN_FALSE;
}
c->flags->flags = fi->flags;
fi->callback(INTERNAL_FUNCTION_PARAM_PASSTHRU, c, fi->ctx);
c->flags->flags = flags;
} else {
/* Just add false */
add_next_index_bool(multi_resp, 0);

View File

@@ -264,6 +264,8 @@ struct clusterFoldItem {
/* Next item in our list */
struct clusterFoldItem *next;
uint8_t flags;
};
/* Key and value container, with info if they need freeing */

View File

@@ -152,6 +152,7 @@ typedef enum {
#define PIPELINE 2
#define PHPREDIS_DEBUG_LOGGING 0
#define PHPREDIS_WITH_METADATA 1
#if PHP_VERSION_ID < 80000
#define Z_PARAM_ARRAY_HT_OR_NULL(dest) \
@@ -184,6 +185,7 @@ typedef enum {
#define REDIS_SAVE_CALLBACK(callback, closure_context) do { \
fold_item *fi = redis_add_reply_callback(redis_sock); \
fi->fun = callback; \
fi->flags = redis_sock->flags; \
fi->ctx = closure_context; \
} while (0)
@@ -266,6 +268,9 @@ static inline int redis_strncmp(const char *s1, const char *s2, size_t n) {
#define REDIS_ENABLE_MODE(redis_sock, m) (redis_sock->mode |= m)
#define REDIS_DISABLE_MODE(redis_sock, m) (redis_sock->mode &= ~m)
#define REDIS_ENABLE_FLAG(redis_sock, f) (redis_sock->flags |= f)
#define REDIS_DISABLE_FLAG(redis_sock, f) (redis_sock->flags &= ~f)
/* HOST_NAME_MAX doesn't exist everywhere */
#ifndef HOST_NAME_MAX
#if defined(_POSIX_HOST_NAME_MAX)
@@ -325,6 +330,7 @@ typedef struct {
int sentinel;
size_t txBytes;
size_t rxBytes;
uint8_t flags;
} RedisSock;
/* }}} */
@@ -334,6 +340,7 @@ typedef int (*FailableResultCallback)(INTERNAL_FUNCTION_PARAMETERS, RedisSock*,
typedef struct fold_item {
FailableResultCallback fun;
uint8_t flags;
void *ctx;
} fold_item;

View File

@@ -2669,32 +2669,34 @@ PHP_REDIS_API int redis_string_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock
char *response;
int response_len;
zval z_unpacked, z_ret, *zv;
zend_bool ret;
if ((response = redis_sock_read(redis_sock, &response_len))
== NULL)
{
if (IS_ATOMIC(redis_sock)) {
RETVAL_FALSE;
} else {
add_next_index_bool(z_tab, 0);
}
return FAILURE;
}
if (IS_ATOMIC(redis_sock)) {
if (!redis_unpack(redis_sock, response, response_len, return_value)) {
RETVAL_STRINGL_FAST(response, response_len);
}
if ((response = redis_sock_read(redis_sock, &response_len)) == NULL) {
ZVAL_FALSE(&z_unpacked);
ret = FAILURE;
} else {
zval z_unpacked;
if (redis_unpack(redis_sock, response, response_len, &z_unpacked)) {
add_next_index_zval(z_tab, &z_unpacked);
} else {
redis_add_next_index_stringl(z_tab, response, response_len);
if (!redis_unpack(redis_sock, response, response_len, &z_unpacked)) {
ZVAL_STRINGL_FAST(&z_unpacked, response, response_len);
}
efree(response);
ret = SUCCESS;
}
efree(response);
return SUCCESS;
if (redis_sock->flags & PHPREDIS_WITH_METADATA) {
redis_with_metadata(&z_ret, &z_unpacked, response_len);
zv = &z_ret;
} else {
zv = &z_unpacked;
}
if (IS_ATOMIC(redis_sock)) {
RETVAL_ZVAL(zv, 0, 1);
} else {
add_next_index_zval(z_tab, zv);
}
return ret;
}
/* like string response, but never unserialized. */
@@ -4455,6 +4457,17 @@ int redis_extract_auth_info(zval *ztest, zend_string **user, zend_string **pass)
return FAILURE;
}
PHP_REDIS_API void redis_with_metadata(zval *zdst, zval *zsrc, zend_long length) {
zval z_sub;
array_init(zdst);
add_next_index_zval(zdst, zsrc);
array_init(&z_sub);
add_assoc_long_ex(&z_sub, ZEND_STRL("length"), length);
add_next_index_zval(zdst, &z_sub);
}
/* Helper methods to extract configuration settings from a hash table */
zval *redis_hash_str_find_type(HashTable *ht, const char *key, int keylen, int type) {

View File

@@ -44,6 +44,7 @@ fold_item* redis_add_reply_callback(RedisSock *redis_sock);
void redis_free_reply_callbacks(RedisSock *redis_sock);
PHP_REDIS_API int redis_extract_auth_info(zval *ztest, zend_string **user, zend_string **pass);
PHP_REDIS_API void redis_with_metadata(zval *zdst, zval *zsrc, zend_long length);
int redis_cmd_init_sstr(smart_string *str, int num_args, char *keyword, int keyword_len);
int redis_cmd_append_sstr(smart_string *str, char *append, int append_len);

35
redis.c
View File

@@ -760,11 +760,32 @@ PHP_METHOD(Redis, reset)
}
/* }}} */
static void
redis_get_passthru(INTERNAL_FUNCTION_PARAMETERS)
{
REDIS_PROCESS_KW_CMD("GET", redis_key_cmd, redis_string_response);
}
/* {{{ proto string Redis::get(string key)
*/
PHP_METHOD(Redis, get)
{
REDIS_PROCESS_KW_CMD("GET", redis_key_cmd, redis_string_response);
redis_get_passthru(INTERNAL_FUNCTION_PARAM_PASSTHRU);
}
/* }}} */
/* {{{ proto Redis|array|false Redis::getWithMeta(string key)
*/
PHP_METHOD(Redis, getWithMeta)
{
RedisSock *redis_sock;
if ((redis_sock = redis_sock_get_instance(getThis(), 0)) == NULL) {
RETURN_FALSE;
}
REDIS_ENABLE_FLAG(redis_sock, PHPREDIS_WITH_METADATA);
redis_get_passthru(INTERNAL_FUNCTION_PARAM_PASSTHRU);
REDIS_DISABLE_FLAG(redis_sock, PHPREDIS_WITH_METADATA);
}
/* }}} */
@@ -2067,13 +2088,17 @@ PHP_REDIS_API int
redis_sock_read_multibulk_multi_reply_loop(INTERNAL_FUNCTION_PARAMETERS,
RedisSock *redis_sock, zval *z_tab)
{
fold_item fi;
fold_item *fi;
uint8_t flags;
size_t i;
flags = redis_sock->flags;
for (i = 0; i < redis_sock->reply_callback_count; i++) {
fi = redis_sock->reply_callback[i];
if (fi.fun) {
fi.fun(INTERNAL_FUNCTION_PARAM_PASSTHRU, redis_sock, z_tab, fi.ctx);
fi = &redis_sock->reply_callback[i];
if (fi->fun) {
redis_sock->flags = fi->flags;
fi->fun(INTERNAL_FUNCTION_PARAM_PASSTHRU, redis_sock, z_tab, fi->ctx);
redis_sock->flags = flags;
continue;
}
size_t len;

View File

@@ -1467,6 +1467,16 @@ class Redis {
*/
public function get(string $key): mixed;
/**
* Retrieve a value and metadata of key.
*
* @param string $key The key to query
* @return Redis|array|false
*
* @example $redis->getWithMeta('foo');
*/
public function getWithMeta(string $key): Redis|array|false;
/**
* Get the authentication information on the connection, if any.
*

View File

@@ -1,5 +1,5 @@
/* This is a generated file, edit the .stub.php file instead.
* Stub hash: 3c4051fdd9f860523bcd72aba260b1af823d1d9c */
* Stub hash: 6dd5a9e9d1d5ed8a78e248c99352232e30046f28 */
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")
@@ -323,6 +323,10 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Redis_get, 0, 1, IS_MIXED,
ZEND_ARG_TYPE_INFO(0, key, IS_STRING, 0)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_class_Redis_getWithMeta, 0, 1, Redis, MAY_BE_ARRAY|MAY_BE_FALSE)
ZEND_ARG_TYPE_INFO(0, key, IS_STRING, 0)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Redis_getAuth, 0, 0, IS_MIXED, 0)
ZEND_END_ARG_INFO()
@@ -404,9 +408,7 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Redis_hGet, 0, 2, IS_MIXED
ZEND_ARG_TYPE_INFO(0, member, IS_STRING, 0)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_class_Redis_hGetAll, 0, 1, Redis, MAY_BE_ARRAY|MAY_BE_FALSE)
ZEND_ARG_TYPE_INFO(0, key, IS_STRING, 0)
ZEND_END_ARG_INFO()
#define arginfo_class_Redis_hGetAll arginfo_class_Redis_getWithMeta
ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_class_Redis_hIncrBy, 0, 3, Redis, MAY_BE_LONG|MAY_BE_FALSE)
ZEND_ARG_TYPE_INFO(0, key, IS_STRING, 0)
@@ -420,7 +422,7 @@ ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_class_Redis_hIncrByFloat, 0,
ZEND_ARG_TYPE_INFO(0, value, IS_DOUBLE, 0)
ZEND_END_ARG_INFO()
#define arginfo_class_Redis_hKeys arginfo_class_Redis_hGetAll
#define arginfo_class_Redis_hKeys arginfo_class_Redis_getWithMeta
#define arginfo_class_Redis_hLen arginfo_class_Redis_expiretime
@@ -455,7 +457,7 @@ ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_class_Redis_hStrLen, 0, 2, R
ZEND_ARG_TYPE_INFO(0, field, IS_STRING, 0)
ZEND_END_ARG_INFO()
#define arginfo_class_Redis_hVals arginfo_class_Redis_hGetAll
#define arginfo_class_Redis_hVals arginfo_class_Redis_getWithMeta
ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_class_Redis_hscan, 0, 2, Redis, MAY_BE_ARRAY|MAY_BE_BOOL)
ZEND_ARG_TYPE_INFO(0, key, IS_STRING, 0)
@@ -747,7 +749,7 @@ ZEND_END_ARG_INFO()
#define arginfo_class_Redis_sInterStore arginfo_class_Redis_del
#define arginfo_class_Redis_sMembers arginfo_class_Redis_hGetAll
#define arginfo_class_Redis_sMembers arginfo_class_Redis_getWithMeta
#define arginfo_class_Redis_sMisMember arginfo_class_Redis_geohash
@@ -1249,6 +1251,7 @@ ZEND_METHOD(Redis, georadiusbymember_ro);
ZEND_METHOD(Redis, geosearch);
ZEND_METHOD(Redis, geosearchstore);
ZEND_METHOD(Redis, get);
ZEND_METHOD(Redis, getWithMeta);
ZEND_METHOD(Redis, getAuth);
ZEND_METHOD(Redis, getBit);
ZEND_METHOD(Redis, getEx);
@@ -1507,6 +1510,7 @@ static const zend_function_entry class_Redis_methods[] = {
ZEND_ME(Redis, geosearch, arginfo_class_Redis_geosearch, ZEND_ACC_PUBLIC)
ZEND_ME(Redis, geosearchstore, arginfo_class_Redis_geosearchstore, ZEND_ACC_PUBLIC)
ZEND_ME(Redis, get, arginfo_class_Redis_get, ZEND_ACC_PUBLIC)
ZEND_ME(Redis, getWithMeta, arginfo_class_Redis_getWithMeta, ZEND_ACC_PUBLIC)
ZEND_ME(Redis, getAuth, arginfo_class_Redis_getAuth, ZEND_ACC_PUBLIC)
ZEND_ME(Redis, getBit, arginfo_class_Redis_getBit, ZEND_ACC_PUBLIC)
ZEND_ME(Redis, getEx, arginfo_class_Redis_getEx, ZEND_ACC_PUBLIC)

View File

@@ -275,12 +275,28 @@ PHP_METHOD(RedisCluster, close) {
RETURN_TRUE;
}
/* {{{ proto string RedisCluster::get(string key) */
PHP_METHOD(RedisCluster, get) {
static void
cluster_get_passthru(INTERNAL_FUNCTION_PARAMETERS)
{
CLUSTER_PROCESS_KW_CMD("GET", redis_key_cmd, cluster_bulk_resp, 1);
}
/* {{{ proto string RedisCluster::get(string key) */
PHP_METHOD(RedisCluster, get) {
cluster_get_passthru(INTERNAL_FUNCTION_PARAM_PASSTHRU);
}
/* }}} */
/* {{{ proto array|false RedisCluster::getWithMeta(string key) */
PHP_METHOD(RedisCluster, getWithMeta) {
redisCluster *c = GET_CONTEXT();
REDIS_ENABLE_FLAG(c->flags, PHPREDIS_WITH_METADATA);
cluster_get_passthru(INTERNAL_FUNCTION_PARAM_PASSTHRU);
REDIS_DISABLE_FLAG(c->flags, PHPREDIS_WITH_METADATA);
}
/* }}} */
/* {{{ proto bool RedisCluster::set(string key, string value) */
PHP_METHOD(RedisCluster, set) {
CLUSTER_PROCESS_CMD(set, cluster_set_resp, 0);

View File

@@ -22,6 +22,7 @@
_item->slot = slot; \
_item->ctx = ctx; \
_item->next = NULL; \
_item->flags = c->flags->flags; \
if(c->multi_head == NULL) { \
c->multi_head = _item; \
c->multi_curr = _item; \

View File

@@ -390,6 +390,11 @@ class RedisCluster {
*/
public function get(string $key): mixed;
/**
* @see Redis::getWithMeta
*/
public function getWithMeta(string $key): RedisCluster|array|false;
/**
* @see Redis::getEx
*/

View File

@@ -1,5 +1,5 @@
/* This is a generated file, edit the .stub.php file instead.
* Stub hash: b9310b607794caa862d509ba316a2a512d2736fe */
* Stub hash: 5966b99fd578eca94880e09539542edfbcbcdaed */
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_RedisCluster___construct, 0, 0, 1)
ZEND_ARG_TYPE_INFO(0, name, IS_STRING, 1)
@@ -325,6 +325,10 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_RedisCluster_get, 0, 1, IS
ZEND_ARG_TYPE_INFO(0, key, IS_STRING, 0)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_class_RedisCluster_getWithMeta, 0, 1, RedisCluster, MAY_BE_ARRAY|MAY_BE_FALSE)
ZEND_ARG_TYPE_INFO(0, key, IS_STRING, 0)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_class_RedisCluster_getex, 0, 1, RedisCluster, MAY_BE_STRING|MAY_BE_FALSE)
ZEND_ARG_TYPE_INFO(0, key, IS_STRING, 0)
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, options, IS_ARRAY, 0, "[]")
@@ -379,9 +383,7 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_RedisCluster_hget, 0, 2, I
ZEND_ARG_TYPE_INFO(0, member, IS_STRING, 0)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_class_RedisCluster_hgetall, 0, 1, RedisCluster, MAY_BE_ARRAY|MAY_BE_FALSE)
ZEND_ARG_TYPE_INFO(0, key, IS_STRING, 0)
ZEND_END_ARG_INFO()
#define arginfo_class_RedisCluster_hgetall arginfo_class_RedisCluster_getWithMeta
ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_class_RedisCluster_hincrby, 0, 3, RedisCluster, MAY_BE_LONG|MAY_BE_FALSE)
ZEND_ARG_TYPE_INFO(0, key, IS_STRING, 0)
@@ -395,7 +397,7 @@ ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_class_RedisCluster_hincrbyfl
ZEND_ARG_TYPE_INFO(0, value, IS_DOUBLE, 0)
ZEND_END_ARG_INFO()
#define arginfo_class_RedisCluster_hkeys arginfo_class_RedisCluster_hgetall
#define arginfo_class_RedisCluster_hkeys arginfo_class_RedisCluster_getWithMeta
#define arginfo_class_RedisCluster_hlen arginfo_class_RedisCluster_expiretime
@@ -451,7 +453,7 @@ ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_class_RedisCluster_hstrlen,
ZEND_ARG_TYPE_INFO(0, field, IS_STRING, 0)
ZEND_END_ARG_INFO()
#define arginfo_class_RedisCluster_hvals arginfo_class_RedisCluster_hgetall
#define arginfo_class_RedisCluster_hvals arginfo_class_RedisCluster_getWithMeta
#define arginfo_class_RedisCluster_incr arginfo_class_RedisCluster_decr
@@ -754,7 +756,7 @@ ZEND_END_ARG_INFO()
#define arginfo_class_RedisCluster_slowlog arginfo_class_RedisCluster_script
#define arginfo_class_RedisCluster_smembers arginfo_class_RedisCluster_hgetall
#define arginfo_class_RedisCluster_smembers arginfo_class_RedisCluster_getWithMeta
ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_class_RedisCluster_smove, 0, 3, RedisCluster, MAY_BE_BOOL)
ZEND_ARG_TYPE_INFO(0, src, IS_STRING, 0)
@@ -1127,6 +1129,7 @@ ZEND_METHOD(RedisCluster, georadiusbymember_ro);
ZEND_METHOD(RedisCluster, geosearch);
ZEND_METHOD(RedisCluster, geosearchstore);
ZEND_METHOD(RedisCluster, get);
ZEND_METHOD(RedisCluster, getWithMeta);
ZEND_METHOD(RedisCluster, getex);
ZEND_METHOD(RedisCluster, getbit);
ZEND_METHOD(RedisCluster, getlasterror);
@@ -1356,6 +1359,7 @@ static const zend_function_entry class_RedisCluster_methods[] = {
ZEND_ME(RedisCluster, geosearch, arginfo_class_RedisCluster_geosearch, ZEND_ACC_PUBLIC)
ZEND_ME(RedisCluster, geosearchstore, arginfo_class_RedisCluster_geosearchstore, ZEND_ACC_PUBLIC)
ZEND_ME(RedisCluster, get, arginfo_class_RedisCluster_get, ZEND_ACC_PUBLIC)
ZEND_ME(RedisCluster, getWithMeta, arginfo_class_RedisCluster_getWithMeta, ZEND_ACC_PUBLIC)
ZEND_ME(RedisCluster, getex, arginfo_class_RedisCluster_getex, ZEND_ACC_PUBLIC)
ZEND_ME(RedisCluster, getbit, arginfo_class_RedisCluster_getbit, ZEND_ACC_PUBLIC)
ZEND_ME(RedisCluster, getlasterror, arginfo_class_RedisCluster_getlasterror, ZEND_ACC_PUBLIC)

View File

@@ -1,5 +1,5 @@
/* This is a generated file, edit the .stub.php file instead.
* Stub hash: b9310b607794caa862d509ba316a2a512d2736fe */
* Stub hash: 5966b99fd578eca94880e09539542edfbcbcdaed */
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_RedisCluster___construct, 0, 0, 1)
ZEND_ARG_INFO(0, name)
@@ -295,6 +295,8 @@ ZEND_END_ARG_INFO()
#define arginfo_class_RedisCluster_get arginfo_class_RedisCluster__prefix
#define arginfo_class_RedisCluster_getWithMeta arginfo_class_RedisCluster__prefix
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_RedisCluster_getex, 0, 0, 1)
ZEND_ARG_INFO(0, key)
ZEND_ARG_INFO(0, options)
@@ -969,6 +971,7 @@ ZEND_METHOD(RedisCluster, georadiusbymember_ro);
ZEND_METHOD(RedisCluster, geosearch);
ZEND_METHOD(RedisCluster, geosearchstore);
ZEND_METHOD(RedisCluster, get);
ZEND_METHOD(RedisCluster, getWithMeta);
ZEND_METHOD(RedisCluster, getex);
ZEND_METHOD(RedisCluster, getbit);
ZEND_METHOD(RedisCluster, getlasterror);
@@ -1198,6 +1201,7 @@ static const zend_function_entry class_RedisCluster_methods[] = {
ZEND_ME(RedisCluster, geosearch, arginfo_class_RedisCluster_geosearch, ZEND_ACC_PUBLIC)
ZEND_ME(RedisCluster, geosearchstore, arginfo_class_RedisCluster_geosearchstore, ZEND_ACC_PUBLIC)
ZEND_ME(RedisCluster, get, arginfo_class_RedisCluster_get, ZEND_ACC_PUBLIC)
ZEND_ME(RedisCluster, getWithMeta, arginfo_class_RedisCluster_getWithMeta, ZEND_ACC_PUBLIC)
ZEND_ME(RedisCluster, getex, arginfo_class_RedisCluster_getex, ZEND_ACC_PUBLIC)
ZEND_ME(RedisCluster, getbit, arginfo_class_RedisCluster_getbit, ZEND_ACC_PUBLIC)
ZEND_ME(RedisCluster, getlasterror, arginfo_class_RedisCluster_getlasterror, ZEND_ACC_PUBLIC)

View File

@@ -1,5 +1,5 @@
/* This is a generated file, edit the .stub.php file instead.
* Stub hash: 3c4051fdd9f860523bcd72aba260b1af823d1d9c */
* Stub hash: 6dd5a9e9d1d5ed8a78e248c99352232e30046f28 */
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Redis___construct, 0, 0, 0)
ZEND_ARG_INFO(0, options)
@@ -301,6 +301,8 @@ ZEND_END_ARG_INFO()
#define arginfo_class_Redis_get arginfo_class_Redis__prefix
#define arginfo_class_Redis_getWithMeta arginfo_class_Redis__prefix
#define arginfo_class_Redis_getAuth arginfo_class_Redis___destruct
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Redis_getBit, 0, 0, 2)
@@ -1092,6 +1094,7 @@ ZEND_METHOD(Redis, georadiusbymember_ro);
ZEND_METHOD(Redis, geosearch);
ZEND_METHOD(Redis, geosearchstore);
ZEND_METHOD(Redis, get);
ZEND_METHOD(Redis, getWithMeta);
ZEND_METHOD(Redis, getAuth);
ZEND_METHOD(Redis, getBit);
ZEND_METHOD(Redis, getEx);
@@ -1350,6 +1353,7 @@ static const zend_function_entry class_Redis_methods[] = {
ZEND_ME(Redis, geosearch, arginfo_class_Redis_geosearch, ZEND_ACC_PUBLIC)
ZEND_ME(Redis, geosearchstore, arginfo_class_Redis_geosearchstore, ZEND_ACC_PUBLIC)
ZEND_ME(Redis, get, arginfo_class_Redis_get, ZEND_ACC_PUBLIC)
ZEND_ME(Redis, getWithMeta, arginfo_class_Redis_getWithMeta, ZEND_ACC_PUBLIC)
ZEND_ME(Redis, getAuth, arginfo_class_Redis_getAuth, ZEND_ACC_PUBLIC)
ZEND_ME(Redis, getBit, arginfo_class_Redis_getBit, ZEND_ACC_PUBLIC)
ZEND_ME(Redis, getEx, arginfo_class_Redis_getEx, ZEND_ACC_PUBLIC)

View File

@@ -248,6 +248,21 @@ class Redis_Cluster_Test extends Redis_Test {
$this->assertTrue($this->redis->client($key, 'kill', $addr));
}
public function testGetWithMeta() {
$this->redis->del('key');
$this->assertFalse($this->redis->get('key'));
$this->assertEquals([false, ['length' => -1]], $this->redis->getWithMeta('key'));
$this->assertEquals([true, ['value', ['length' => strlen('value')]]], $this->redis->multi()->set('key', 'value')->getWithMeta('key')->exec());
$serializer = $this->redis->getOption(Redis::OPT_SERIALIZER);
$this->redis->setOption(Redis::OPT_SERIALIZER, Redis::SERIALIZER_PHP);
$this->assertTrue($this->redis->set('key', false));
$this->assertEquals([false, ['length' => strlen(serialize(false))]], $this->redis->getWithMeta('key'));
$this->assertFalse($this->redis->get('key'));
$this->redis->setOption(Redis::OPT_SERIALIZER, $serializer);
}
public function testTime() {
[$sec, $usec] = $this->redis->time(uniqid());
$this->assertEquals(strval(intval($sec)), strval($sec));

View File

@@ -5800,6 +5800,22 @@ class Redis_Test extends TestSuite {
$this->redis->setOption(Redis::OPT_COMPRESSION, $oldcmp);
}
public function testGetWithMeta() {
$this->redis->del('key');
$this->assertFalse($this->redis->get('key'));
$this->assertEquals([false, ['length' => -1]], $this->redis->getWithMeta('key'));
$this->assertEquals([false, [false, ['length' => -1]]], $this->redis->pipeline()->get('key')->getWithMeta('key')->exec());
$this->assertEquals([true, ['value', ['length' => strlen('value')]]], $this->redis->multi()->set('key', 'value')->getWithMeta('key')->exec());
$serializer = $this->redis->getOption(Redis::OPT_SERIALIZER);
$this->redis->setOption(Redis::OPT_SERIALIZER, Redis::SERIALIZER_PHP);
$this->assertTrue($this->redis->set('key', false));
$this->assertEquals([false, ['length' => strlen(serialize(false))]], $this->redis->getWithMeta('key'));
$this->assertFalse($this->redis->get('key'));
$this->redis->setOption(Redis::OPT_SERIALIZER, $serializer);
}
public function testPrefix() {
// no prefix
$this->redis->setOption(Redis::OPT_PREFIX, '');