Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/phpredis/phpredis.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormichael-grunder <michael-grunder@github.com>2012-05-04 23:12:03 +0400
committermichael-grunder <michael-grunder@github.com>2012-05-04 23:12:03 +0400
commitd59b53b6b5779113ef8bf4d6f951bddd75e7f99d (patch)
tree9a8e68ef3c88dc4ad03e31389311db70b46b95a8
parent3160a64a17fc8824fcdbbcc5d17b8c18bc77ff52 (diff)
Implemented INCRBYFLOAT and HINCRBYFLOAT
-rw-r--r--library.c2
-rwxr-xr-xphp_redis.h2
-rwxr-xr-xredis.c89
-rw-r--r--tests/TestRedis.php47
4 files changed, 130 insertions, 10 deletions
diff --git a/library.c b/library.c
index faef6232..667a5970 100644
--- a/library.c
+++ b/library.c
@@ -566,6 +566,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) {
/*
diff --git a/php_redis.h b/php_redis.h
index 82ed17f5..6392c375 100755
--- a/php_redis.h
+++ b/php_redis.h
@@ -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);
@@ -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);
diff --git a/redis.c b/redis.c
index d1f5e5d1..51ac86ea 100755
--- a/redis.c
+++ b/redis.c
@@ -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)
@@ -189,6 +190,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)
@@ -1048,6 +1050,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)
@@ -4506,6 +4540,59 @@ 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, val_len, key_free;
+ double val;
+ int i, dcount;
+
+ // 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;
+ }
+
+ // Start at the begining unless the first character is '-'
+ /*i = val_len && val[0] == '-' ? 1 : 0;
+
+ // Initially we have no '.' characters
+ dcount = 0;
+
+ // Iterate our string
+ for(; i<val_len; ++i) {
+ // Increment our decimal count and skip this iteration if we're on one
+ if(val[i] == '.') {
+ ++dcount;
+ continue;
+ }
+
+ // We're invalid if this character isn't numeric, or if we have too many decimals
+ if((val[i] < '0' || val[i] > '9') || dcount > 1) {
+ 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;
@@ -4535,8 +4622,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);
diff --git a/tests/TestRedis.php b/tests/TestRedis.php
index 80810ddf..5a19e31d 100644
--- a/tests/TestRedis.php
+++ b/tests/TestRedis.php
@@ -354,7 +354,7 @@ class Redis_Test extends TestSuite
$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);
@@ -376,6 +376,28 @@ class Redis_Test extends TestSuite
$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()
@@ -627,16 +649,16 @@ class Redis_Test extends TestSuite
// 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.');
@@ -645,11 +667,11 @@ class Redis_Test extends TestSuite
// }
// $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"));
// }
// }
@@ -684,8 +706,8 @@ class Redis_Test extends TestSuite
}
//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);
@@ -1909,6 +1931,15 @@ class Redis_Test extends TestSuite
$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')));