diff options
author | Nasreddine Bouafif <nasreddine.bouafif@gmail.com> | 2010-09-29 17:49:22 +0400 |
---|---|---|
committer | Nasreddine Bouafif <nasreddine.bouafif@gmail.com> | 2010-09-29 17:49:22 +0400 |
commit | a62d12a38b391099230de5e41cf214f4b8bb7542 (patch) | |
tree | 29973bd75771b70b0352be5ed41d11cde49d1272 | |
parent | ead9e60a03ee92b7ca05644437df56777bd92da8 (diff) |
Add lPushx, rPushx and lInsert commands
-rw-r--r-- | README.markdown | 68 | ||||
-rwxr-xr-x | php_redis.h | 3 | ||||
-rwxr-xr-x | redis.c | 52 | ||||
-rw-r--r-- | tests/TestRedis.php | 23 |
4 files changed, 146 insertions, 0 deletions
diff --git a/README.markdown b/README.markdown index c6613245..98063978 100644 --- a/README.markdown +++ b/README.markdown @@ -336,6 +336,42 @@ $redis->rPush('key1', 'C'); // returns 3 /* key1 now points to the following list: [ 'A', 'B', 'C' ] */ </pre> +## lPushx +##### Description +Adds the string value to the head (left) of the list if the list exists. +##### Parameters +*key* +*value* String, value to push in key +##### Return value +*LONG* The new length of the list in case of success, `FALSE` in case of Failure. +##### Examples +<pre> +$redis->delete('key1'); +$redis->lPushx('key1', 'A'); // returns 0 +$redis->lPush('key1', 'A'); // returns 1 +$redis->lPushx('key1', 'B'); // returns 2 +$redis->lPushx('key1', 'C'); // returns 3 +/* key1 now points to the following list: [ 'A', 'B', 'C' ] */ +</pre> + +## rPushx +##### Description +Adds the string value to the tail (right) of the list if the ist exists. `FALSE` in case of Failure. +##### Parameters +*key* +*value* String, value to push in key +##### Return value +*LONG* The new length of the list in case of success, `FALSE` in case of Failure. +##### Examples +<pre> +$redis->delete('key1'); +$redis->rPushx('key1', 'A'); // returns 0 +$redis->rPush('key1', 'A'); // returns 1 +$redis->rPushx('key1', 'B'); // returns 2 +$redis->rPushx('key1', 'C'); // returns 3 +/* key1 now points to the following list: [ 'A', 'B', 'C' ] */ +</pre> + ## lPop ##### *Description* Return and remove the first element of the list. @@ -493,6 +529,38 @@ $redis->lRemove('key1', 'A', 2); /* 2 */ $redis->lGetRange('key1', 0, -1); /* array('C', 'B', 'A') */ </pre> +## lInsert +##### *Description* +Insert value in the list before or after the pivot value. the parameter options specify the position of the insert (before or after). +If the list didn't exists, or the pivot didn't exists, the value is not inserted. +##### *Parameters* +*key* +*position* Redis::BEFORE | Redis::AFTER +*pivot* +*value* + +##### *Return value* +The number of the elements in the list, -1 if the pivot didn't exists. + +##### *Example* +<pre> +$redis->delete('key1'); +$redis->lInsert('key1', Redis::AFTER, 'A', 'X'); /* 0 */ + +$redis->lPush('key1', 'A'); +$redis->lPush('key1', 'B'); +$redis->lPush('key1', 'C'); + +$redis->lInsert('key1', Redis::BEFORE, 'C', 'X'); /* 4 */ +$redis->lGetRange('key1', 0, -1); /* array('A', 'B', 'X', 'C') */ + +$redis->lInsert('key1', Redis::AFTER, 'C', 'Y'); /* 5 */ +$redis->lGetRange('key1', 0, -1); /* array('A', 'B', 'X', 'C', 'Y') */ + +$redis->lInsert('key1', Redis::AFTER, 'W', 'value'); /* -1 */ + +</pre> + ## sAdd ##### *Description* Adds a value to the set value stored at key. If this value is already in the set, `FALSE` is returned. diff --git a/php_redis.h b/php_redis.h index 203df39e..c9fea012 100755 --- a/php_redis.h +++ b/php_redis.h @@ -46,7 +46,9 @@ PHP_METHOD(Redis, sortAscAlpha); PHP_METHOD(Redis, sortDesc); PHP_METHOD(Redis, sortDescAlpha); PHP_METHOD(Redis, lPush); +PHP_METHOD(Redis, lPushx); PHP_METHOD(Redis, rPush); +PHP_METHOD(Redis, rPushx); PHP_METHOD(Redis, lPop); PHP_METHOD(Redis, rPop); PHP_METHOD(Redis, lSize); @@ -55,6 +57,7 @@ PHP_METHOD(Redis, listTrim); PHP_METHOD(Redis, lGet); PHP_METHOD(Redis, lGetRange); PHP_METHOD(Redis, lSet); +PHP_METHOD(Redis, lInsert); PHP_METHOD(Redis, sAdd); PHP_METHOD(Redis, sSize); PHP_METHOD(Redis, sRemove); @@ -69,6 +69,8 @@ static zend_function_entry redis_functions[] = { PHP_ME(Redis, sortDescAlpha, NULL, ZEND_ACC_PUBLIC) PHP_ME(Redis, lPush, NULL, ZEND_ACC_PUBLIC) PHP_ME(Redis, rPush, NULL, ZEND_ACC_PUBLIC) + PHP_ME(Redis, lPushx, NULL, ZEND_ACC_PUBLIC) + PHP_ME(Redis, rPushx, NULL, ZEND_ACC_PUBLIC) PHP_ME(Redis, lPop, NULL, ZEND_ACC_PUBLIC) PHP_ME(Redis, rPop, NULL, ZEND_ACC_PUBLIC) PHP_ME(Redis, lSize, NULL, ZEND_ACC_PUBLIC) @@ -77,6 +79,7 @@ static zend_function_entry redis_functions[] = { PHP_ME(Redis, lGet, NULL, ZEND_ACC_PUBLIC) PHP_ME(Redis, lGetRange, NULL, ZEND_ACC_PUBLIC) PHP_ME(Redis, lSet, NULL, ZEND_ACC_PUBLIC) + PHP_ME(Redis, lInsert, NULL, ZEND_ACC_PUBLIC) PHP_ME(Redis, sAdd, NULL, ZEND_ACC_PUBLIC) PHP_ME(Redis, sSize, NULL, ZEND_ACC_PUBLIC) PHP_ME(Redis, sRemove, NULL, ZEND_ACC_PUBLIC) @@ -279,6 +282,9 @@ PHP_MINIT_FUNCTION(redis) add_constant_long(redis_ce, "MULTI", MULTI); add_constant_long(redis_ce, "PIPELINE", PIPELINE); + zend_declare_class_constant_stringl(redis_ce, "AFTER", 5, "after", 5 TSRMLS_CC); + zend_declare_class_constant_stringl(redis_ce, "BEFORE", 6, "before", 6 TSRMLS_CC); + return SUCCESS; } @@ -968,6 +974,52 @@ PHP_METHOD(Redis, rPush) } /* }}} */ +PHP_METHOD(Redis, lInsert) +{ + + zval *object; + RedisSock *redis_sock; + zval *z_array, **z_curr; + char *pivot, *position, *key, *val, *cmd; + int pivot_len, position_len, key_len, val_len, cmd_len; + + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Ossss", + &object, redis_ce, + &key, &key_len, + &position, &position_len, + &pivot, &pivot_len, + &val, &val_len) == FAILURE) { + RETURN_NULL(); + } + + if (redis_sock_get(object, &redis_sock TSRMLS_CC) < 0) { + RETURN_FALSE; + } + + if(strncasecmp(position, "after", 5) == 0 || strncasecmp(position, "before", 6) == 0) { + cmd_len = redis_cmd_format_static(&cmd, "LINSERT", "ssss", key, key_len, position, position_len, pivot, pivot_len, val, val_len); + REDIS_PROCESS_REQUEST(redis_sock, cmd, cmd_len); + IF_ATOMIC() { + redis_long_response(INTERNAL_FUNCTION_PARAM_PASSTHRU, redis_sock, NULL, NULL); + } + REDIS_PROCESS_RESPONSE(redis_long_response); + } else { + php_error_docref(NULL TSRMLS_CC, E_ERROR, "Error on position"); + } + +} + +PHP_METHOD(Redis, lPushx) +{ + generic_push_function(INTERNAL_FUNCTION_PARAM_PASSTHRU, "LPUSHX", sizeof("LPUSHX")-1); +} + +PHP_METHOD(Redis, rPushx) +{ + generic_push_function(INTERNAL_FUNCTION_PARAM_PASSTHRU, "RPUSHX", sizeof("RPUSHX")-1); +} + PHPAPI void generic_pop_function(INTERNAL_FUNCTION_PARAMETERS, char *keyword, int keyword_len) { diff --git a/tests/TestRedis.php b/tests/TestRedis.php index d918d864..de2729e3 100644 --- a/tests/TestRedis.php +++ b/tests/TestRedis.php @@ -498,6 +498,29 @@ class Redis_Test extends PHPUnit_Framework_TestCase $this->assertEquals(FALSE, $this->redis->lSize('list'));// not a list returns FALSE } + //lInsert, lPopx, rPopx + 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); + + $this->redis->delete('key'); + $this->redis->lPush('key', 'val0'); + $this->assertTrue($this->redis->lPushx('key', 'val1') === 2); + $this->assertTrue($this->redis->rPushx('key', 'val2') === 3); + $this->assertTrue($this->redis->lGetRange('key', 0, -1) === array('val1', 'val0', 'val2')); + + //test linsert + $this->redis->delete('key'); + $this->redis->lPush('key', 'val0'); + $this->assertTrue($this->redis->lInsert('keyNotExists', Redis::AFTER, 'val1', 'val2') === 0); + $this->assertTrue($this->redis->lInsert('key', Redis::BEFORE, 'valX', 'val2') === -1); + + $this->assertTrue($this->redis->lInsert('key', Redis::AFTER, 'val0', 'val1') === 2); + $this->assertTrue($this->redis->lInsert('key', Redis::BEFORE, 'val0', 'val2') === 3); + $this->assertTrue($this->redis->lGetRange('key', 0, -1) === array('val2', 'val0', 'val1')); + } // ltrim, lsize, lpop public function testlistTrim() |