credishiredis

Can I use MGET with hiredis?


Consider following example:

#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <hiredis/hiredis.h>

int main(int argc, char **argv) {
  redisContext *redis;
  redisReply *reply;

  redis = redisConnect("127.0.0.1", 6379);
  if(redis->err) {
    fprintf(stderr, "Connection error: %s\n", redis->errstr);
    exit(EXIT_FAILURE);
  }

  reply = redisCommand(redis, "SET %s %s", "foo", "bar");
  printf("SET %s %s: %s\n", "foo", "bar", reply->str);
  freeReplyObject(reply);

  reply = redisCommand(redis, "SET %s %s", "name", "value");
  printf("SET %s %s: %s\n", "name", "value", reply->str);
  freeReplyObject(reply);

  reply = redisCommand(redis, "MGET %s %s", "foo", "name");
  printf("MGET %s %s: %s\n", "foo", "name", reply->str);
  freeReplyObject(reply);

  exit(EXIT_SUCCESS);
}

The output is:

PING: PONG
SET foo bar: OK
GET foo: bar
SET name value: OK
MGET foo name: (null)

It's about return from MGET. Can I get multi keys using hiredis?


Solution

  • A redisReply is a typed object (see the type field), and a multi-bulk reply has a specific type (REDIS_REPLY_ARRAY). The str field is not relevant in that case.

    From the hiredis documentation:

    The number of elements in the multi bulk reply is stored in reply->elements.
    Every element in the multi bulk reply is a redisReply object as well
    and can be accessed via reply->element[..index..].
    Redis may reply with nested arrays but this is fully supported.
    

    So your code should be changed as follows:

    reply = redisCommand(redis, "MGET %s %s", "foo", "name" );
    if ( reply->type == REDIS_REPLY_ERROR )
      printf( "Error: %s\n", reply->str );
    else if ( reply->type != REDIS_REPLY_ARRAY )
      printf( "Unexpected type: %d\n", reply->type );
    else 
    {
      int i;
      for ( i=0; i<reply->elements; ++i )
        printf( "Result: %s\n", reply->element[i]->str );
    }
    freeReplyObject(reply);
    

    With this change, the output is now:

    SET foo bar: OK
    SET name value: OK
    Result: bar
    Result: value
    

    Note: there is no need to free each individual element since freeReplyObject deletes the whole tree.