Skip to content

Commit a62d12a

Browse files
committed
Add lPushx, rPushx and lInsert commands
1 parent ead9e60 commit a62d12a

File tree

4 files changed

+146
-0
lines changed

4 files changed

+146
-0
lines changed

README.markdown

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,42 @@ $redis->rPush('key1', 'C'); // returns 3
336336
/* key1 now points to the following list: [ 'A', 'B', 'C' ] */
337337
</pre>
338338

339+
## lPushx
340+
##### Description
341+
Adds the string value to the head (left) of the list if the list exists.
342+
##### Parameters
343+
*key*
344+
*value* String, value to push in key
345+
##### Return value
346+
*LONG* The new length of the list in case of success, `FALSE` in case of Failure.
347+
##### Examples
348+
<pre>
349+
$redis->delete('key1');
350+
$redis->lPushx('key1', 'A'); // returns 0
351+
$redis->lPush('key1', 'A'); // returns 1
352+
$redis->lPushx('key1', 'B'); // returns 2
353+
$redis->lPushx('key1', 'C'); // returns 3
354+
/* key1 now points to the following list: [ 'A', 'B', 'C' ] */
355+
</pre>
356+
357+
## rPushx
358+
##### Description
359+
Adds the string value to the tail (right) of the list if the ist exists. `FALSE` in case of Failure.
360+
##### Parameters
361+
*key*
362+
*value* String, value to push in key
363+
##### Return value
364+
*LONG* The new length of the list in case of success, `FALSE` in case of Failure.
365+
##### Examples
366+
<pre>
367+
$redis->delete('key1');
368+
$redis->rPushx('key1', 'A'); // returns 0
369+
$redis->rPush('key1', 'A'); // returns 1
370+
$redis->rPushx('key1', 'B'); // returns 2
371+
$redis->rPushx('key1', 'C'); // returns 3
372+
/* key1 now points to the following list: [ 'A', 'B', 'C' ] */
373+
</pre>
374+
339375
## lPop
340376
##### *Description*
341377
Return and remove the first element of the list.
@@ -493,6 +529,38 @@ $redis->lRemove('key1', 'A', 2); /* 2 */
493529
$redis->lGetRange('key1', 0, -1); /* array('C', 'B', 'A') */
494530
</pre>
495531

532+
## lInsert
533+
##### *Description*
534+
Insert value in the list before or after the pivot value. the parameter options specify the position of the insert (before or after).
535+
If the list didn't exists, or the pivot didn't exists, the value is not inserted.
536+
##### *Parameters*
537+
*key*
538+
*position* Redis::BEFORE | Redis::AFTER
539+
*pivot*
540+
*value*
541+
542+
##### *Return value*
543+
The number of the elements in the list, -1 if the pivot didn't exists.
544+
545+
##### *Example*
546+
<pre>
547+
$redis->delete('key1');
548+
$redis->lInsert('key1', Redis::AFTER, 'A', 'X'); /* 0 */
549+
550+
$redis->lPush('key1', 'A');
551+
$redis->lPush('key1', 'B');
552+
$redis->lPush('key1', 'C');
553+
554+
$redis->lInsert('key1', Redis::BEFORE, 'C', 'X'); /* 4 */
555+
$redis->lGetRange('key1', 0, -1); /* array('A', 'B', 'X', 'C') */
556+
557+
$redis->lInsert('key1', Redis::AFTER, 'C', 'Y'); /* 5 */
558+
$redis->lGetRange('key1', 0, -1); /* array('A', 'B', 'X', 'C', 'Y') */
559+
560+
$redis->lInsert('key1', Redis::AFTER, 'W', 'value'); /* -1 */
561+
562+
</pre>
563+
496564
## sAdd
497565
##### *Description*
498566
Adds a value to the set value stored at key. If this value is already in the set, `FALSE` is returned.

php_redis.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,9 @@ PHP_METHOD(Redis, sortAscAlpha);
4646
PHP_METHOD(Redis, sortDesc);
4747
PHP_METHOD(Redis, sortDescAlpha);
4848
PHP_METHOD(Redis, lPush);
49+
PHP_METHOD(Redis, lPushx);
4950
PHP_METHOD(Redis, rPush);
51+
PHP_METHOD(Redis, rPushx);
5052
PHP_METHOD(Redis, lPop);
5153
PHP_METHOD(Redis, rPop);
5254
PHP_METHOD(Redis, lSize);
@@ -55,6 +57,7 @@ PHP_METHOD(Redis, listTrim);
5557
PHP_METHOD(Redis, lGet);
5658
PHP_METHOD(Redis, lGetRange);
5759
PHP_METHOD(Redis, lSet);
60+
PHP_METHOD(Redis, lInsert);
5861
PHP_METHOD(Redis, sAdd);
5962
PHP_METHOD(Redis, sSize);
6063
PHP_METHOD(Redis, sRemove);

redis.c

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,8 @@ static zend_function_entry redis_functions[] = {
6969
PHP_ME(Redis, sortDescAlpha, NULL, ZEND_ACC_PUBLIC)
7070
PHP_ME(Redis, lPush, NULL, ZEND_ACC_PUBLIC)
7171
PHP_ME(Redis, rPush, NULL, ZEND_ACC_PUBLIC)
72+
PHP_ME(Redis, lPushx, NULL, ZEND_ACC_PUBLIC)
73+
PHP_ME(Redis, rPushx, NULL, ZEND_ACC_PUBLIC)
7274
PHP_ME(Redis, lPop, NULL, ZEND_ACC_PUBLIC)
7375
PHP_ME(Redis, rPop, NULL, ZEND_ACC_PUBLIC)
7476
PHP_ME(Redis, lSize, NULL, ZEND_ACC_PUBLIC)
@@ -77,6 +79,7 @@ static zend_function_entry redis_functions[] = {
7779
PHP_ME(Redis, lGet, NULL, ZEND_ACC_PUBLIC)
7880
PHP_ME(Redis, lGetRange, NULL, ZEND_ACC_PUBLIC)
7981
PHP_ME(Redis, lSet, NULL, ZEND_ACC_PUBLIC)
82+
PHP_ME(Redis, lInsert, NULL, ZEND_ACC_PUBLIC)
8083
PHP_ME(Redis, sAdd, NULL, ZEND_ACC_PUBLIC)
8184
PHP_ME(Redis, sSize, NULL, ZEND_ACC_PUBLIC)
8285
PHP_ME(Redis, sRemove, NULL, ZEND_ACC_PUBLIC)
@@ -279,6 +282,9 @@ PHP_MINIT_FUNCTION(redis)
279282
add_constant_long(redis_ce, "MULTI", MULTI);
280283
add_constant_long(redis_ce, "PIPELINE", PIPELINE);
281284

285+
zend_declare_class_constant_stringl(redis_ce, "AFTER", 5, "after", 5 TSRMLS_CC);
286+
zend_declare_class_constant_stringl(redis_ce, "BEFORE", 6, "before", 6 TSRMLS_CC);
287+
282288
return SUCCESS;
283289
}
284290

@@ -968,6 +974,52 @@ PHP_METHOD(Redis, rPush)
968974
}
969975
/* }}} */
970976

977+
PHP_METHOD(Redis, lInsert)
978+
{
979+
980+
zval *object;
981+
RedisSock *redis_sock;
982+
zval *z_array, **z_curr;
983+
char *pivot, *position, *key, *val, *cmd;
984+
int pivot_len, position_len, key_len, val_len, cmd_len;
985+
986+
987+
if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Ossss",
988+
&object, redis_ce,
989+
&key, &key_len,
990+
&position, &position_len,
991+
&pivot, &pivot_len,
992+
&val, &val_len) == FAILURE) {
993+
RETURN_NULL();
994+
}
995+
996+
if (redis_sock_get(object, &redis_sock TSRMLS_CC) < 0) {
997+
RETURN_FALSE;
998+
}
999+
1000+
if(strncasecmp(position, "after", 5) == 0 || strncasecmp(position, "before", 6) == 0) {
1001+
cmd_len = redis_cmd_format_static(&cmd, "LINSERT", "ssss", key, key_len, position, position_len, pivot, pivot_len, val, val_len);
1002+
REDIS_PROCESS_REQUEST(redis_sock, cmd, cmd_len);
1003+
IF_ATOMIC() {
1004+
redis_long_response(INTERNAL_FUNCTION_PARAM_PASSTHRU, redis_sock, NULL, NULL);
1005+
}
1006+
REDIS_PROCESS_RESPONSE(redis_long_response);
1007+
} else {
1008+
php_error_docref(NULL TSRMLS_CC, E_ERROR, "Error on position");
1009+
}
1010+
1011+
}
1012+
1013+
PHP_METHOD(Redis, lPushx)
1014+
{
1015+
generic_push_function(INTERNAL_FUNCTION_PARAM_PASSTHRU, "LPUSHX", sizeof("LPUSHX")-1);
1016+
}
1017+
1018+
PHP_METHOD(Redis, rPushx)
1019+
{
1020+
generic_push_function(INTERNAL_FUNCTION_PARAM_PASSTHRU, "RPUSHX", sizeof("RPUSHX")-1);
1021+
}
1022+
9711023
PHPAPI void
9721024
generic_pop_function(INTERNAL_FUNCTION_PARAMETERS, char *keyword, int keyword_len) {
9731025

tests/TestRedis.php

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -498,6 +498,29 @@ public function testlSize()
498498
$this->assertEquals(FALSE, $this->redis->lSize('list'));// not a list returns FALSE
499499
}
500500

501+
//lInsert, lPopx, rPopx
502+
public function testlPopx() {
503+
//test lPushx/rPushx
504+
$this->redis->delete('keyNotExists');
505+
$this->assertTrue($this->redis->lPushx('keyNotExists', 'value') === 0);
506+
$this->assertTrue($this->redis->rPushx('keyNotExists', 'value') === 0);
507+
508+
$this->redis->delete('key');
509+
$this->redis->lPush('key', 'val0');
510+
$this->assertTrue($this->redis->lPushx('key', 'val1') === 2);
511+
$this->assertTrue($this->redis->rPushx('key', 'val2') === 3);
512+
$this->assertTrue($this->redis->lGetRange('key', 0, -1) === array('val1', 'val0', 'val2'));
513+
514+
//test linsert
515+
$this->redis->delete('key');
516+
$this->redis->lPush('key', 'val0');
517+
$this->assertTrue($this->redis->lInsert('keyNotExists', Redis::AFTER, 'val1', 'val2') === 0);
518+
$this->assertTrue($this->redis->lInsert('key', Redis::BEFORE, 'valX', 'val2') === -1);
519+
520+
$this->assertTrue($this->redis->lInsert('key', Redis::AFTER, 'val0', 'val1') === 2);
521+
$this->assertTrue($this->redis->lInsert('key', Redis::BEFORE, 'val0', 'val2') === 3);
522+
$this->assertTrue($this->redis->lGetRange('key', 0, -1) === array('val2', 'val0', 'val1'));
523+
}
501524

502525
// ltrim, lsize, lpop
503526
public function testlistTrim()

0 commit comments

Comments
 (0)