Skip to content

Commit

Permalink
xInfo response format
Browse files Browse the repository at this point in the history
  • Loading branch information
yatsukhnenko committed Jun 12, 2019
1 parent 1226303 commit 4852a51
Show file tree
Hide file tree
Showing 4 changed files with 119 additions and 1 deletion.
88 changes: 88 additions & 0 deletions library.c
Original file line number Diff line number Diff line change
Expand Up @@ -1451,6 +1451,94 @@ redis_xclaim_reply(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
return -1;
}

static int
redis_read_xinfo_response(RedisSock *redis_sock, zval *z_ret, int elements)
{
zval zv;
int i, len;
char *key = NULL, *data;
REDIS_REPLY_TYPE type;
long li;

for (i = 0; i < elements; ++i) {
if (redis_read_reply_type(redis_sock, &type, &li TSRMLS_CC) < 0) {
goto failure;
}
switch (type) {
case TYPE_BULK:
if ((data = redis_sock_read_bulk_reply(redis_sock, li TSRMLS_CC)) == NULL) {
goto failure;
} else if (key) {
add_assoc_stringl_ex(z_ret, key, len, data, li);
efree(data);
efree(key);
key = NULL;
} else {
key = data;
len = li;
}
break;
case TYPE_INT:
if (key) {
add_assoc_long_ex(z_ret, key, len, li);
efree(key);
key = NULL;
} else {
len = spprintf(&key, 0, "%ld", li);
}
break;
case TYPE_MULTIBULK:
array_init(&zv);
if (redis_read_xinfo_response(redis_sock, &zv, li) != SUCCESS) {
zval_dtor(&zv);
goto failure;
}
if (key) {
add_assoc_zval_ex(z_ret, key, len, &zv);
efree(key);
key = NULL;
} else {
add_next_index_zval(z_ret, &zv);
}
break;
default:
goto failure;
}
}

return SUCCESS;

failure:
if (key) efree(key);
return FAILURE;
}

PHP_REDIS_API int
redis_xinfo_reply(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx)
{
zval z_ret;
int i, elements;

if (read_mbulk_header(redis_sock, &elements TSRMLS_CC) == SUCCESS) {
array_init(&z_ret);
if (redis_read_xinfo_response(redis_sock, &z_ret, elements TSRMLS_CC) == SUCCESS) {
if (IS_ATOMIC(redis_sock)) {
RETVAL_ZVAL(&z_ret, 0, 1);
} else {
add_next_index_zval(z_tab, &z_ret);
}
return SUCCESS;
}
zval_dtor(&z_ret);
}
if (IS_ATOMIC(redis_sock)) {
RETVAL_FALSE;
} else {
add_next_index_bool(z_tab, 0);
}
return FAILURE;
}

/* Zipped key => value reply but we don't touch anything (e.g. CONFIG GET) */
PHP_REDIS_API int redis_mbulk_reply_zipped_raw(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx)
{
Expand Down
2 changes: 2 additions & 0 deletions library.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,8 @@ PHP_REDIS_API int redis_xread_reply(INTERNAL_FUNCTION_PARAMETERS,
RedisSock *redis_sock, zval *z_tab, void *ctx);
PHP_REDIS_API int redis_xclaim_reply(INTERNAL_FUNCTION_PARAMETERS,
RedisSock *redis_sock, zval *z_tab, void *ctx);
PHP_REDIS_API int redis_xinfo_reply(INTERNAL_FUNCTION_PARAMETERS,
RedisSock *redis_sock, zval *z_tab, void *ctx);

PHP_REDIS_API int redis_subscribe_response(INTERNAL_FUNCTION_PARAMETERS,
RedisSock *redis_sock, zval *z_tab, void *ctx);
Expand Down
2 changes: 1 addition & 1 deletion redis.c
Original file line number Diff line number Diff line change
Expand Up @@ -3663,7 +3663,7 @@ PHP_METHOD(Redis, xgroup) {
}

PHP_METHOD(Redis, xinfo) {
REDIS_PROCESS_CMD(xinfo, redis_read_variant_reply);
REDIS_PROCESS_CMD(xinfo, redis_xinfo_reply);
}

PHP_METHOD(Redis, xlen) {
Expand Down
28 changes: 28 additions & 0 deletions tests/RedisTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -5854,6 +5854,34 @@ public function testXClaim() {
}
}

public function testXInfo()
{
if (!$this->minVersionCheck("5.0")) {
return $this->markTestSkipped();
}
/* Create some streams and groups */
$stream = 's';
$groups = ['g1' => 0, 'g2' => 0];
$this->addStreamsAndGroups([$stream], 1, $groups);

$info = $this->redis->xInfo('GROUPS', $stream);
$this->assertTrue(is_array($info));
$this->assertEquals(count($info), count($groups));
foreach ($info as $group) {
$this->assertTrue(array_key_exists('name', $group));
$this->assertTrue(array_key_exists($group['name'], $groups));
}

$info = $this->redis->xInfo('STREAM', $stream);
$this->assertTrue(is_array($info));
$this->assertTrue(array_key_exists('groups', $info));
$this->assertEquals($info['groups'], count($groups));
foreach (['first-entry', 'last-entry'] as $key) {
$this->assertTrue(array_key_exists($key, $info));
$this->assertTrue(is_array($info[$key]));
}
}

public function testSession_savedToRedis()
{
$this->setSessionHandler();
Expand Down

0 comments on commit 4852a51

Please sign in to comment.