]> git.saurik.com Git - redis.git/commitdiff
implemented HMGET
authorPieter Noordhuis <pcnoordhuis@gmail.com>
Mon, 12 Apr 2010 12:53:25 +0000 (14:53 +0200)
committerPieter Noordhuis <pcnoordhuis@gmail.com>
Mon, 12 Apr 2010 12:57:38 +0000 (14:57 +0200)
redis-cli.c
redis.c
redis.tcl
test-redis.tcl

index febc7cec08317cfbc51d48178a92c3f6c5d84b34..b34c42773364b0e868a068c544f7cbc610bbea09 100644 (file)
@@ -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 6b23c7bc3b17a80ca305d1c79e1538ee7f9eb5c7..095a02e44f834a87b28929aabfbd4b2b888705ea 100644 (file)
--- 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},
@@ -6177,6 +6179,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;
index 233e2c9fe1d17c5e0d98bbdd75c2f86b47193da2..b4a8ae22e87039421fcecdbf615b6438f3897843 100644 (file)
--- 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) {}
 }
index c986baff7bd27ee2785a2a22ed562242c0780ae0..6ebcb039f15f9f18bbfc94f4754ce6c26705bd6d 100644 (file)
@@ -1663,6 +1663,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 *]]