Skip to content

Commit

Permalink
Added hmsetnx command
Browse files Browse the repository at this point in the history
  • Loading branch information
sammyyu committed May 22, 2015
1 parent 9c0a688 commit 02e58ce
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/redis.c
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,7 @@ struct redisCommand redisCommandTable[] = {
{"hsetnx",hsetnxCommand,4,"wmF",0,NULL,1,1,1,0,0},
{"hget",hgetCommand,3,"rF",0,NULL,1,1,1,0,0},
{"hmset",hmsetCommand,-4,"wm",0,NULL,1,1,1,0,0},
{"hmsetnx",hmsetnxCommand,-4,"wm",0,NULL,1,1,1,0,0},
{"hmget",hmgetCommand,-3,"r",0,NULL,1,1,1,0,0},
{"hincrby",hincrbyCommand,4,"wmF",0,NULL,1,1,1,0,0},
{"hincrbyfloat",hincrbyfloatCommand,4,"wmF",0,NULL,1,1,1,0,0},
Expand Down
1 change: 1 addition & 0 deletions src/redis.h
Original file line number Diff line number Diff line change
Expand Up @@ -1485,6 +1485,7 @@ void hsetCommand(redisClient *c);
void hsetnxCommand(redisClient *c);
void hgetCommand(redisClient *c);
void hmsetCommand(redisClient *c);
void hmsetnxCommand(redisClient *c);
void hmgetCommand(redisClient *c);
void hdelCommand(redisClient *c);
void hlenCommand(redisClient *c);
Expand Down
34 changes: 34 additions & 0 deletions src/t_hash.c
Original file line number Diff line number Diff line change
Expand Up @@ -513,6 +513,40 @@ void hmsetCommand(redisClient *c) {
server.dirty++;
}

void hmsetnxCommand(redisClient *c) {
int i, busykeys = 0;
robj *o;

if ((c->argc % 2) == 1) {
addReplyError(c,"wrong number of arguments for HMSETNX");
return;
}

if ((o = hashTypeLookupWriteOrCreate(c,c->argv[1])) == NULL) return;
hashTypeTryConversion(o,c->argv,2,c->argc-1);

/* Handle the NX flag. The HMSETNX semantic is to return zero and don't
* set nothing at all if at least one already key exists. */
for (i = 2; i < c->argc; i += 2) {
if (hashTypeExists(o, c->argv[i])) {
busykeys++;
}
if (busykeys) {
addReply(c, shared.czero);
return;
}
}

for (i = 2; i < c->argc; i += 2) {
hashTypeTryObjectEncoding(o,&c->argv[i], &c->argv[i+1]);
hashTypeSet(o,c->argv[i],c->argv[i+1]);
}
addReply(c, shared.cone);
signalModifiedKey(c->db,c->argv[1]);
notifyKeyspaceEvent(REDIS_NOTIFY_HASH,"hset",c->argv[1],c->db->id);
server.dirty++;
}

void hincrbyCommand(redisClient *c) {
long long value, incr, oldvalue;
robj *o, *current, *new;
Expand Down
16 changes: 16 additions & 0 deletions tests/unit/type/hash.tcl
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,22 @@ start_server {tags {"hash"}} {
r hmset bighash {*}$args
} {OK}

test "HMSETNX - set empty hash" {
r del hash
assert_equal 1 [r hmsetnx hash key1 value1]
assert_equal "value1" [r hmget hash key1]
}

test "HMSETNX - set existing hash" {
r del hash
assert_equal 1 [r hmsetnx hash key1 value1]
assert_equal 0 [r hmsetnx hash key1 newvalue1 key2 value2]
assert_equal "value1" [r hmget hash key1]
assert_equal 0 [r hexists hash key2]
assert_equal 1 [r hmsetnx hash key2 value2]
assert_equal 1 [r hexists hash key2]
}

test {HMGET against non existing key and fields} {
set rv {}
lappend rv [r hmget doesntexist __123123123__ __456456456__]
Expand Down

0 comments on commit 02e58ce

Please sign in to comment.