HEXISTS and tests implemented
authorantirez <antirez@gmail.com>
Wed, 17 Mar 2010 12:34:27 +0000 (13:34 +0100)
committerantirez <antirez@gmail.com>
Wed, 17 Mar 2010 12:34:27 +0000 (13:34 +0100)
redis-cli.c
redis.c
redis.tcl
test-redis.tcl

index 03755efaca89a7af35d239c21bd539ad288496ae..e22eb356d1d77344a34a97e45a0408760dfb47c0 100644 (file)
@@ -153,6 +153,7 @@ static struct redisCommand cmdTable[] = {
     {"hkeys",2,REDIS_CMD_INLINE},
     {"hvals",2,REDIS_CMD_INLINE},
     {"hgetall",2,REDIS_CMD_INLINE},
+    {"hexists",3,REDIS_CMD_BULK},
     {NULL,0,0}
 };
 
diff --git a/redis.c b/redis.c
index 3f9c4c964915363192d55088663116203a98cc8f..87575ee3f529eb617660021cdc2abf34903e414b 100644 (file)
--- a/redis.c
+++ b/redis.c
@@ -689,6 +689,7 @@ static void zinterCommand(redisClient *c);
 static void hkeysCommand(redisClient *c);
 static void hvalsCommand(redisClient *c);
 static void hgetallCommand(redisClient *c);
+static void hexistsCommand(redisClient *c);
 
 /*================================= Globals ================================= */
 
@@ -754,6 +755,7 @@ static struct redisCommand cmdTable[] = {
     {"hkeys",hkeysCommand,2,REDIS_CMD_INLINE,1,1,1},
     {"hvals",hvalsCommand,2,REDIS_CMD_INLINE,1,1,1},
     {"hgetall",hgetallCommand,2,REDIS_CMD_INLINE,1,1,1},
+    {"hexists",hexistsCommand,3,REDIS_CMD_BULK,1,1,1},
     {"incrby",incrbyCommand,3,REDIS_CMD_INLINE|REDIS_CMD_DENYOOM,1,1,1},
     {"decrby",decrbyCommand,3,REDIS_CMD_INLINE|REDIS_CMD_DENYOOM,1,1,1},
     {"getset",getsetCommand,3,REDIS_CMD_BULK|REDIS_CMD_DENYOOM,1,1,1},
@@ -5995,6 +5997,26 @@ static void hgetallCommand(redisClient *c) {
     genericHgetallCommand(c,REDIS_GETALL_KEYS|REDIS_GETALL_VALS);
 }
 
+static void hexistsCommand(redisClient *c) {
+    robj *o;
+    int exists = 0;
+
+    if ((o = lookupKeyReadOrReply(c,c->argv[1],shared.czero)) == NULL ||
+        checkType(c,o,REDIS_HASH)) return;
+
+    if (o->encoding == REDIS_ENCODING_ZIPMAP) {
+        robj *field;
+        unsigned char *zm = o->ptr;
+
+        field = getDecodedObject(c->argv[2]);
+        exists = zipmapExists(zm,field->ptr,sdslen(field->ptr));
+        decrRefCount(field);
+    } else {
+        exists = dictFind(o->ptr,c->argv[2]) != NULL;
+    }
+    addReply(c,exists ? shared.cone : shared.czero);
+}
+
 static void convertToRealHash(robj *o) {
     unsigned char *key, *val, *p, *zm = o->ptr;
     unsigned int klen, vlen;
index ac9f860184c060e5c65c4c11c67a9bde01b516af..ef210cbdb87a657c04180fe863b94984ab8a1571 100644 (file)
--- a/redis.tcl
+++ b/redis.tcl
@@ -20,7 +20,7 @@ array set ::redis::multibulkarg {}
 
 # Flag commands requiring last argument as a bulk write operation
 foreach redis_bulk_cmd {
-    set setnx rpush lpush lset lrem sadd srem sismember echo getset smove zadd zrem zscore zincrby append zrank zrevrank hget hdel
+    set setnx rpush lpush lset lrem sadd srem sismember echo getset smove zadd zrem zscore zincrby append zrank zrevrank hget hdel hexists
 } {
     set ::redis::bulkarg($redis_bulk_cmd) {}
 }
index 0cf1c410bbcb1f5a01fd4d061cc5577aedb70972..5022eee1ac1c283a4db40b35bb760330cd45c5ab 100644 (file)
@@ -1644,13 +1644,25 @@ proc main {server port} {
         lappend rv [$r hdel smallhash $k]
         lappend rv [$r hdel smallhash $k]
         lappend rv [$r hget smallhash $k]
+        unset smallhash($k)
         set k [lindex [array names bighash *] 0]
         lappend rv [$r hdel bighash $k]
         lappend rv [$r hdel bighash $k]
         lappend rv [$r hget bighash $k]
+        unset bighash($k)
         set _ $rv
     } {0 0 1 0 {} 1 0 {}}
 
+    test {HEXISTS} {
+        set rv {}
+        set k [lindex [array names smallhash *] 0]
+        lappend rv [$r hexists smallhash $k]
+        lappend rv [$r hexists smallhash nokey]
+        set k [lindex [array names bighash *] 0]
+        lappend rv [$r hexists bighash $k]
+        lappend rv [$r hexists bighash nokey]
+    } {1 0 1 0}
+
     test {Is a zipmap encoded Hash promoted on big payload?} {
         $r hset smallhash foo [string repeat a 1024]
         $r debug object smallhash