summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorantirez <antirez@gmail.com>2010-04-13 18:30:55 +0200
committerantirez <antirez@gmail.com>2010-04-13 18:30:55 +0200
commitb60bace9f945d30029596a6bd91412d2e1053c69 (patch)
tree0331a74b268ae42983f4a02f3fef177c65c61fda
parentbbe025e04bca8c1631152aada1ed7db5a6aa625c (diff)
parent09aeb5790fa09e1a5fb7545f669780efe1eb4632 (diff)
downloadredis-b60bace9f945d30029596a6bd91412d2e1053c69.tar.gz
Merge branch 'hmget' of git://github.com/pietern/redis
-rw-r--r--redis-cli.c3
-rw-r--r--redis.c55
-rw-r--r--redis.tcl2
-rw-r--r--test-redis.tcl40
4 files changed, 96 insertions, 4 deletions
diff --git a/redis-cli.c b/redis-cli.c
index febc7cec0..b34c42773 100644
--- a/redis-cli.c
+++ b/redis-cli.c
@@ -150,9 +150,10 @@ static struct redisCommand cmdTable[] = {
{"exec",1,REDIS_CMD_INLINE},
{"discard",1,REDIS_CMD_INLINE},
{"hset",4,REDIS_CMD_MULTIBULK},
+ {"hget",3,REDIS_CMD_BULK},
{"hmset",-4,REDIS_CMD_MULTIBULK},
+ {"hmget",-3,REDIS_CMD_MULTIBULK},
{"hincrby",4,REDIS_CMD_INLINE},
- {"hget",3,REDIS_CMD_BULK},
{"hdel",3,REDIS_CMD_BULK},
{"hlen",2,REDIS_CMD_INLINE},
{"hkeys",2,REDIS_CMD_INLINE},
diff --git a/redis.c b/redis.c
index cbb0993ad..e78f75aa6 100644
--- a/redis.c
+++ b/redis.c
@@ -704,8 +704,9 @@ static void substrCommand(redisClient *c);
static void zrankCommand(redisClient *c);
static void zrevrankCommand(redisClient *c);
static void hsetCommand(redisClient *c);
-static void hmsetCommand(redisClient *c);
static void hgetCommand(redisClient *c);
+static void hmsetCommand(redisClient *c);
+static void hmgetCommand(redisClient *c);
static void hdelCommand(redisClient *c);
static void hlenCommand(redisClient *c);
static void zremrangebyrankCommand(redisClient *c);
@@ -781,9 +782,10 @@ static struct redisCommand cmdTable[] = {
{"zrank",zrankCommand,3,REDIS_CMD_BULK,NULL,1,1,1},
{"zrevrank",zrevrankCommand,3,REDIS_CMD_BULK,NULL,1,1,1},
{"hset",hsetCommand,4,REDIS_CMD_BULK|REDIS_CMD_DENYOOM,NULL,1,1,1},
+ {"hget",hgetCommand,3,REDIS_CMD_BULK,NULL,1,1,1},
{"hmset",hmsetCommand,-4,REDIS_CMD_BULK|REDIS_CMD_DENYOOM,NULL,1,1,1},
+ {"hmget",hmgetCommand,-3,REDIS_CMD_BULK,NULL,1,1,1},
{"hincrby",hincrbyCommand,4,REDIS_CMD_INLINE|REDIS_CMD_DENYOOM,NULL,1,1,1},
- {"hget",hgetCommand,3,REDIS_CMD_BULK,NULL,1,1,1},
{"hdel",hdelCommand,3,REDIS_CMD_BULK,NULL,1,1,1},
{"hlen",hlenCommand,2,REDIS_CMD_INLINE,NULL,1,1,1},
{"hkeys",hkeysCommand,2,REDIS_CMD_INLINE,NULL,1,1,1},
@@ -6253,6 +6255,55 @@ static void hgetCommand(redisClient *c) {
}
}
+static void hmgetCommand(redisClient *c) {
+ int i;
+
+ robj *o = lookupKeyRead(c->db, c->argv[1]);
+ if (o == NULL) {
+ addReplySds(c,sdscatprintf(sdsempty(),"*%d\r\n",c->argc-2));
+ for (i = 2; i < c->argc; i++) {
+ addReply(c,shared.nullbulk);
+ }
+ return;
+ } else {
+ if (o->type != REDIS_HASH) {
+ addReply(c,shared.wrongtypeerr);
+ return;
+ }
+ }
+
+ addReplySds(c,sdscatprintf(sdsempty(),"*%d\r\n",c->argc-2));
+ if (o->encoding == REDIS_ENCODING_ZIPMAP) {
+ unsigned char *zm = o->ptr;
+ unsigned char *v;
+ unsigned int vlen;
+ robj *field;
+
+ for (i = 2; i < c->argc; i++) {
+ field = getDecodedObject(c->argv[i]);
+ if (zipmapGet(zm,field->ptr,sdslen(field->ptr),&v,&vlen)) {
+ addReplySds(c,sdscatprintf(sdsempty(),"$%u\r\n", vlen));
+ addReplySds(c,sdsnewlen(v,vlen));
+ addReply(c,shared.crlf);
+ } else {
+ addReply(c,shared.nullbulk);
+ }
+ decrRefCount(field);
+ }
+ } else {
+ dictEntry *de;
+
+ for (i = 2; i < c->argc; i++) {
+ de = dictFind(o->ptr,c->argv[i]);
+ if (de != NULL) {
+ addReplyBulk(c,(robj*)dictGetEntryVal(de));
+ } else {
+ addReply(c,shared.nullbulk);
+ }
+ }
+ }
+}
+
static void hdelCommand(redisClient *c) {
robj *o;
int deleted = 0;
diff --git a/redis.tcl b/redis.tcl
index 233e2c9fe..b4a8ae22e 100644
--- a/redis.tcl
+++ b/redis.tcl
@@ -46,7 +46,7 @@ foreach redis_bulk_cmd {
# Flag commands requiring last argument as a bulk write operation
foreach redis_multibulk_cmd {
- mset msetnx hset hmset
+ mset msetnx hset hmset hmget
} {
set ::redis::multibulkarg($redis_multibulk_cmd) {}
}
diff --git a/test-redis.tcl b/test-redis.tcl
index f45c47382..f321258a5 100644
--- a/test-redis.tcl
+++ b/test-redis.tcl
@@ -1671,6 +1671,46 @@ proc main {server port} {
$r hmset bighash {*}$args
} {OK}
+ test {HMGET against non existing key and fields} {
+ set rv {}
+ lappend rv [$r hmget doesntexist __123123123__ __456456456__]
+ lappend rv [$r hmget smallhash __123123123__ __456456456__]
+ lappend rv [$r hmget bighash __123123123__ __456456456__]
+ set _ $rv
+ } {{{} {}} {{} {}} {{} {}}}
+
+ test {HMGET - small hash} {
+ set keys {}
+ set vals {}
+ foreach {k v} [array get smallhash] {
+ lappend keys $k
+ lappend vals $v
+ }
+ set err {}
+ set result [$r hmget smallhash {*}$keys]
+ if {$vals ne $result} {
+ set err "$vals != $result"
+ break
+ }
+ set _ $err
+ } {}
+
+ test {HMGET - big hash} {
+ set keys {}
+ set vals {}
+ foreach {k v} [array get bighash] {
+ lappend keys $k
+ lappend vals $v
+ }
+ set err {}
+ set result [$r hmget bighash {*}$keys]
+ if {$vals ne $result} {
+ set err "$vals != $result"
+ break
+ }
+ set _ $err
+ } {}
+
test {HKEYS - small hash} {
lsort [$r hkeys smallhash]
} [lsort [array names smallhash *]]