Skip to content

Commit

Permalink
Merge pull request phpredis#175 from michael-grunder/master
Browse files Browse the repository at this point in the history
INCRBYFLOAT and HINCRBYFLOAT
  • Loading branch information
nicolasff committed May 6, 2012
2 parents 3160a64 + d66c893 commit ad7de59
Show file tree
Hide file tree
Showing 4 changed files with 122 additions and 12 deletions.
12 changes: 12 additions & 0 deletions library.c
Expand Up @@ -278,6 +278,16 @@ redis_cmd_format_static(char **ret, char *keyword, char *format, ...) {
smart_str_appendl(&buf, tmp, tmp_len);
}
break;
case 'l':
case 'L': {
long l = va_arg(ap, long);
char tmp[32];
int tmp_len = snprintf(tmp, sizeof(tmp), "%ld", l);
smart_str_append_long(&buf, tmp_len);
smart_str_appendl(&buf, _NL, sizeof(_NL) -1);
smart_str_appendl(&buf, tmp, tmp_len);
}
break;
}
p++;
smart_str_appendl(&buf, _NL, sizeof(_NL) - 1);
Expand Down Expand Up @@ -566,6 +576,8 @@ PHPAPI void redis_long_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_s
}
}



PHPAPI int redis_sock_read_multibulk_reply_zipped_with_flag(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, int flag) {

/*
Expand Down
2 changes: 2 additions & 0 deletions php_redis.h
Expand Up @@ -44,6 +44,7 @@ PHP_METHOD(Redis, exists);
PHP_METHOD(Redis, delete);
PHP_METHOD(Redis, incr);
PHP_METHOD(Redis, incrBy);
PHP_METHOD(Redis, incrByFloat);
PHP_METHOD(Redis, decr);
PHP_METHOD(Redis, decrBy);
PHP_METHOD(Redis, type);
Expand Down Expand Up @@ -141,6 +142,7 @@ PHP_METHOD(Redis, hVals);
PHP_METHOD(Redis, hGetAll);
PHP_METHOD(Redis, hExists);
PHP_METHOD(Redis, hIncrBy);
PHP_METHOD(Redis, hIncrByFloat);
PHP_METHOD(Redis, hMset);
PHP_METHOD(Redis, hMget);

Expand Down
70 changes: 67 additions & 3 deletions redis.c
Expand Up @@ -91,6 +91,7 @@ static zend_function_entry redis_functions[] = {
PHP_ME(Redis, delete, NULL, ZEND_ACC_PUBLIC)
PHP_ME(Redis, incr, NULL, ZEND_ACC_PUBLIC)
PHP_ME(Redis, incrBy, NULL, ZEND_ACC_PUBLIC)
PHP_ME(Redis, incrByFloat, NULL, ZEND_ACC_PUBLIC)
PHP_ME(Redis, decr, NULL, ZEND_ACC_PUBLIC)
PHP_ME(Redis, decrBy, NULL, ZEND_ACC_PUBLIC)
PHP_ME(Redis, type, NULL, ZEND_ACC_PUBLIC)
Expand Down Expand Up @@ -176,6 +177,7 @@ static zend_function_entry redis_functions[] = {
PHP_ME(Redis, zUnion, NULL, ZEND_ACC_PUBLIC)
PHP_ME(Redis, zIncrBy, NULL, ZEND_ACC_PUBLIC)
PHP_ME(Redis, expireAt, NULL, ZEND_ACC_PUBLIC)
PHP_ME(Redis, pexpire, NULL, ZEND_ACC_PUBLIC)
PHP_ME(Redis, pexpireAt, NULL, ZEND_ACC_PUBLIC)

/* 1.2 */
Expand All @@ -189,6 +191,7 @@ static zend_function_entry redis_functions[] = {
PHP_ME(Redis, hGetAll, NULL, ZEND_ACC_PUBLIC)
PHP_ME(Redis, hExists, NULL, ZEND_ACC_PUBLIC)
PHP_ME(Redis, hIncrBy, NULL, ZEND_ACC_PUBLIC)
PHP_ME(Redis, hIncrByFloat, NULL, ZEND_ACC_PUBLIC)
PHP_ME(Redis, hMset, NULL, ZEND_ACC_PUBLIC)
PHP_ME(Redis, hMget, NULL, ZEND_ACC_PUBLIC)

Expand Down Expand Up @@ -1048,6 +1051,38 @@ PHP_METHOD(Redis, incrBy){
}
/* }}} */

/* {{{ proto float Redis::incrByFloat(string key, float value)
*/
PHP_METHOD(Redis, incrByFloat) {
zval *object;
RedisSock *redis_sock;
char *key = NULL, *cmd;
int key_len, cmd_len, key_free;
double val;

if(zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Osd",
&object, redis_ce, &key, &key_len, &val) == FAILURE) {
RETURN_FALSE;
}

if(redis_sock_get(object, &redis_sock TSRMLS_CC, 0) < 0) {
RETURN_FALSE;
}

// Prefix our key, free it if we have
key_free = redis_key_prefix(redis_sock, &key, &key_len TSRMLS_CC);
if(key_free) efree(key);

// Format our INCRBYFLOAT command
cmd_len = redis_cmd_format_static(&cmd, "INCRBYFLOAT", "sf", key, key_len, val);

REDIS_PROCESS_REQUEST(redis_sock, cmd, cmd_len);
IF_ATOMIC() {
redis_bulk_double_response(INTERNAL_FUNCTION_PARAM_PASSTHRU, redis_sock, NULL, NULL);
}
REDIS_PROCESS_RESPONSE(redis_bulk_double_response);
}

/* {{{ proto boolean Redis::decr(string key [,int value])
*/
PHP_METHOD(Redis, decr)
Expand Down Expand Up @@ -2858,7 +2893,7 @@ PHPAPI void generic_expire_cmd(INTERNAL_FUNCTION_PARAMETERS, char *keyword, int
}

key_free = redis_key_prefix(redis_sock, &key, &key_len TSRMLS_CC);
cmd_len = redis_cmd_format_static(&cmd, keyword, "sd", key, key_len, t);
cmd_len = redis_cmd_format_static(&cmd, keyword, "sl", key, key_len, t);
if(key_free) efree(key);

REDIS_PROCESS_REQUEST(redis_sock, cmd, cmd_len);
Expand Down Expand Up @@ -4506,6 +4541,37 @@ PHPAPI void array_zip_values_and_scores(RedisSock *redis_sock, zval *z_tab, int
efree(z_ret);
}

PHP_METHOD(Redis, hIncrByFloat)
{
zval *object;
RedisSock *redis_sock;
char *key = NULL, *cmd, *member;
int key_len, member_len, cmd_len, key_free;
double val;

// Validate we have the right number of arguments
if(zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Ossd",
&object, redis_ce,
&key, &key_len, &member, &member_len, &val) == FAILURE) {
RETURN_FALSE;
}

// Grab our socket
if(redis_sock_get(object, &redis_sock TSRMLS_CC, 0) < 0) {
RETURN_FALSE;
}

key_free = redis_key_prefix(redis_sock, &key, &key_len TSRMLS_CC);
cmd_len = redis_cmd_format_static(&cmd, "HINCRBYFLOAT", "ssf", key, key_len, member, member_len, val);
if(key_free) efree(key);

REDIS_PROCESS_REQUEST(redis_sock, cmd, cmd_len);
IF_ATOMIC() {
redis_bulk_double_response(INTERNAL_FUNCTION_PARAM_PASSTHRU, redis_sock, NULL, NULL);
}
REDIS_PROCESS_RESPONSE(redis_bulk_double_response);
}

PHP_METHOD(Redis, hIncrBy)
{
zval *object;
Expand Down Expand Up @@ -4535,8 +4601,6 @@ PHP_METHOD(Redis, hIncrBy)
}
}



/* HINCRBY key member amount */
key_free = redis_key_prefix(redis_sock, &key, &key_len TSRMLS_CC);
cmd_len = redis_cmd_format_static(&cmd, "HINCRBY", "sss", key, key_len, member, member_len, val, val_len);
Expand Down
50 changes: 41 additions & 9 deletions tests/TestRedis.php
Expand Up @@ -354,7 +354,7 @@ public function testIncr()
$this->redis->incr('key');
$this->assertEquals(2, (int)$this->redis->get('key'));

$this->redis->incr('key', 3);
$this->redis->incr('key', 3);
$this->assertEquals(5, (int)$this->redis->get('key'));

$this->redis->incrBy('key', 3);
Expand All @@ -376,6 +376,28 @@ public function testIncr()
$this->redis->incr('key');
$this->assertTrue("abc" === $this->redis->get('key'));

// incrbyfloat

$this->redis->delete('key');

$this->redis->set('key', 0);

$this->redis->incrbyfloat('key', 1.5);
$this->assertEquals('1.5', $this->redis->get('key'));

$this->redis->incrbyfloat('key', 2.25);
$this->assertEquals('3.75', $this->redis->get('key'));

$this->redis->incrbyfloat('key', -2.25);
$this->assertEquals('1.5', $this->redis->get('key'));

$this->redis->set('key', 'abc');

$this->redis->incrbyfloat('key', 1.5);
$this->assertTrue("abc" === $this->redis->get('key'));

$this->redis->incrbyfloat('key', -1.5);
$this->assertTrue("abc" === $this->redis->get('key'));
}

public function testDecr()
Expand Down Expand Up @@ -627,16 +649,16 @@ public function testblockingPop() {
// TODO: fix this broken test.
// $this->redis->delete('list');
// $params = array(
// 0 => array("pipe", "r"),
// 0 => array("pipe", "r"),
// 1 => array("pipe", "w"),
// 2 => array("file", "/dev/null", "w")
// );
// if(function_exists('proc_open')) {
// $env = array('PHPREDIS_key' =>'list', 'PHPREDIS_value' => 'value');
// $process = proc_open('php', $params, $pipes, '/tmp', $env);
//
//
// if (is_resource($process)) {
// fwrite($pipes[0], '<?php
// fwrite($pipes[0], '<?php
// sleep(2);
// $r = new Redis;
// $r->connect("'.self::HOST.'", '.self::PORT.');
Expand All @@ -645,11 +667,11 @@ public function testblockingPop() {
// }
// $r->lPush($_ENV["PHPREDIS_key"], $_ENV["PHPREDIS_value"]);
// ?' . '>');
//
//
// fclose($pipes[0]);
// fclose($pipes[1]);
// $re = proc_close($process);
//
//
// $this->assertTrue($this->redis->blPop(array('list'), 5) === array("list", "value"));
// }
// }
Expand Down Expand Up @@ -684,8 +706,8 @@ public function testlSize()
}

//lInsert, lPopx, rPopx
public function testlPopx() {
//test lPushx/rPushx
public function testlPopx() {
//test lPushx/rPushx
$this->redis->delete('keyNotExists');
$this->assertTrue($this->redis->lPushx('keyNotExists', 'value') === 0);
$this->assertTrue($this->redis->rPushx('keyNotExists', 'value') === 0);
Expand Down Expand Up @@ -1831,7 +1853,7 @@ public function testZX() {
$this->redis->delete('z');
$this->redis->zadd('z', 1, 'one');
$this->redis->zadd('z', 2, 'two');
$this->redis->zadd('z', 5, 'five');
$this->redis->zadd('z', 5, 'five');

$this->assertTrue(0 === $this->redis->zRank('z', 'one'));
$this->assertTrue(1 === $this->redis->zRank('z', 'two'));
Expand All @@ -1840,6 +1862,7 @@ public function testZX() {
$this->assertTrue(2 === $this->redis->zRevRank('z', 'one'));
$this->assertTrue(1 === $this->redis->zRevRank('z', 'two'));
$this->assertTrue(0 === $this->redis->zRevRank('z', 'five'));

}

public function testHashes() {
Expand Down Expand Up @@ -1909,6 +1932,15 @@ public function testHashes() {
$this->redis->hSet('h', 'y', 'not-a-number');
$this->assertTrue(FALSE === $this->redis->hIncrBy('h', 'y', 1));

// hIncrByFloat
$this->redis->delete('h');
$this->assertTrue(1.5 === $this->redis->hIncrByFloat('h','x', 1.5));
$this->assertTrue(3.0 === $this->redis->hincrByFloat('h','x', 1.5));
$this->assertTrue(1.5 === $this->redis->hincrByFloat('h','x', -1.5));

$this->redis->hset('h','y','not-a-number');
$this->assertTrue(FALSE === $this->redis->hIncrByFloat('h', 'y', 1.5));

// hmset
$this->redis->delete('h');
$this->assertTrue(TRUE === $this->redis->hMset('h', array('x' => 123, 'y' => 456, 'z' => 'abc')));
Expand Down

0 comments on commit ad7de59

Please sign in to comment.