diff --git a/php_redis.h b/php_redis.h index 3a0cf6f6..db7ad5a2 100755 --- a/php_redis.h +++ b/php_redis.h @@ -27,6 +27,7 @@ PHP_METHOD(Redis, close); PHP_METHOD(Redis, ping); PHP_METHOD(Redis, get); PHP_METHOD(Redis, set); +PHP_METHOD(Redis, setnx); PHP_METHOD(Redis, add); PHP_METHOD(Redis, getMultiple); PHP_METHOD(Redis, exists); diff --git a/redis.c b/redis.c index 27c95971..3368a9f5 100755 --- a/redis.c +++ b/redis.c @@ -41,6 +41,7 @@ zend_function_entry redis_functions[] = { PHP_ME(Redis, ping, NULL, ZEND_ACC_PUBLIC) PHP_ME(Redis, get, NULL, ZEND_ACC_PUBLIC) PHP_ME(Redis, set, NULL, ZEND_ACC_PUBLIC) + PHP_ME(Redis, setnx, NULL, ZEND_ACC_PUBLIC) PHP_ME(Redis, add, NULL, ZEND_ACC_PUBLIC) PHP_ME(Redis, getMultiple, NULL, ZEND_ACC_PUBLIC) PHP_ME(Redis, exists, NULL, ZEND_ACC_PUBLIC) @@ -604,6 +605,7 @@ PHP_METHOD(Redis, set) RedisSock *redis_sock; char *key = NULL, *val = NULL, *cmd, *response; int key_len, val_len, cmd_len, response_len, count; + char ret = 0; if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Oss", &object, redis_ce, &key, &key_len, @@ -625,8 +627,50 @@ PHP_METHOD(Redis, set) if ((response = redis_sock_read(redis_sock, &response_len TSRMLS_CC)) == NULL) { RETURN_FALSE; } + ret = response[0]; + efree(response); - if (response[0] == 0x2b) { + if (ret == '+') { + RETURN_TRUE; + } else { + RETURN_FALSE; + } +} +/* {{{ proto boolean Redis::setnx(string key, string value) + */ +PHP_METHOD(Redis, setnx) +{ + + zval *object; + RedisSock *redis_sock; + char *key = NULL, *val = NULL, *cmd, *response; + int key_len, val_len, cmd_len, response_len, count; + int ret = 0; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Oss", + &object, redis_ce, &key, &key_len, + &val, &val_len) == FAILURE) { + RETURN_FALSE; + } + + if (redis_sock_get(object, &redis_sock TSRMLS_CC) < 0) { + RETURN_FALSE; + } + + cmd_len = redis_cmd_format(&cmd, "SETNX %s %d\r\n%s\r\n", key, key_len, val_len, val, val_len); + + if (redis_sock_write(redis_sock, cmd, cmd_len) < 0) { + efree(cmd); + RETURN_FALSE; + } + efree(cmd); + if ((response = redis_sock_read(redis_sock, &response_len TSRMLS_CC)) == NULL) { + RETURN_FALSE; + } + ret = atoi(response + 1); + efree(response); + + if (ret == 1) { RETURN_TRUE; } else { RETURN_FALSE; diff --git a/tests/TestRedis.php b/tests/TestRedis.php index ec4d57c2..4fbe47dc 100644 --- a/tests/TestRedis.php +++ b/tests/TestRedis.php @@ -154,6 +154,17 @@ class Redis_Test extends PHPUnit_Framework_TestCase $this->assertEquals(False, $this->redis->get('key')); } + public function testSetNX() { + + $this->redis->set('key', 42); + $this->assertTrue($this->redis->setnx('key', 'err') === FALSE); + $this->assertTrue($this->redis->get('key') === '42'); + + $this->redis->delete('key'); + $this->assertTrue($this->redis->setnx('key', '42') === TRUE); + $this->assertTrue($this->redis->get('key') === '42'); + } + public function testAdd() { $key = 'key' . rand();