Skip to content

Commit b783d7e

Browse files
committed
Better variadic function, variadic HDEL.
1 parent 5c65c03 commit b783d7e

File tree

3 files changed

+56
-38
lines changed

3 files changed

+56
-38
lines changed

php_redis.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ PHP_MINFO_FUNCTION(redis);
172172
PHPAPI int redis_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent);
173173
PHPAPI void redis_atomic_increment(INTERNAL_FUNCTION_PARAMETERS, char *keyword, int count);
174174
PHPAPI int generic_multiple_args_cmd(INTERNAL_FUNCTION_PARAMETERS, char *keyword, int keyword_len,
175-
int min_argc, RedisSock **redis_sock, int has_timeout);
175+
int min_argc, RedisSock **redis_sock, int has_timeout, int all_keys);
176176
PHPAPI void generic_sort_cmd(INTERNAL_FUNCTION_PARAMETERS, char *sort, int use_alpha);
177177
PHPAPI void generic_empty_cmd(INTERNAL_FUNCTION_PARAMETERS, char *cmd, int cmd_len, ...);
178178
PHPAPI void generic_empty_long_cmd(INTERNAL_FUNCTION_PARAMETERS, char *cmd, int cmd_len, ...);

redis.c

Lines changed: 48 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1074,7 +1074,7 @@ PHP_METHOD(Redis, delete)
10741074

10751075
generic_multiple_args_cmd(INTERNAL_FUNCTION_PARAM_PASSTHRU,
10761076
"DEL", sizeof("DEL") - 1,
1077-
1, &redis_sock, 0);
1077+
1, &redis_sock, 0, 1);
10781078
IF_ATOMIC() {
10791079
redis_long_response(INTERNAL_FUNCTION_PARAM_PASSTHRU, redis_sock, NULL, NULL);
10801080
}
@@ -1091,7 +1091,7 @@ PHP_METHOD(Redis, watch)
10911091

10921092
generic_multiple_args_cmd(INTERNAL_FUNCTION_PARAM_PASSTHRU,
10931093
"WATCH", sizeof("WATCH") - 1,
1094-
1, &redis_sock, 0);
1094+
1, &redis_sock, 0, 1);
10951095
IF_ATOMIC() {
10961096
redis_boolean_response(INTERNAL_FUNCTION_PARAM_PASSTHRU, redis_sock, NULL, NULL);
10971097
}
@@ -1504,7 +1504,7 @@ PHP_METHOD(Redis, blPop)
15041504

15051505
generic_multiple_args_cmd(INTERNAL_FUNCTION_PARAM_PASSTHRU,
15061506
"BLPOP", sizeof("BLPOP") - 1,
1507-
2, &redis_sock, 1);
1507+
2, &redis_sock, 1, 1);
15081508

15091509
IF_ATOMIC() {
15101510
if (redis_sock_read_multibulk_reply(INTERNAL_FUNCTION_PARAM_PASSTHRU,
@@ -1524,7 +1524,7 @@ PHP_METHOD(Redis, brPop)
15241524

15251525
generic_multiple_args_cmd(INTERNAL_FUNCTION_PARAM_PASSTHRU,
15261526
"BRPOP", sizeof("BRPOP") - 1,
1527-
2, &redis_sock, 1);
1527+
2, &redis_sock, 1, 1);
15281528

15291529
IF_ATOMIC() {
15301530
if (redis_sock_read_multibulk_reply(INTERNAL_FUNCTION_PARAM_PASSTHRU,
@@ -1936,7 +1936,7 @@ PHP_METHOD(Redis, sMembers)
19361936

19371937

19381938
PHPAPI int generic_multiple_args_cmd(INTERNAL_FUNCTION_PARAMETERS, char *keyword, int keyword_len,
1939-
int min_argc, RedisSock **out_sock, int has_timeout)
1939+
int min_argc, RedisSock **out_sock, int has_timeout, int all_keys)
19401940
{
19411941
zval *object, **z_args, *z_array;
19421942
char **keys, *cmd;
@@ -2004,9 +2004,9 @@ PHPAPI int generic_multiple_args_cmd(INTERNAL_FUNCTION_PARAMETERS, char *keyword
20042004
if(single_array) { /* loop over the array */
20052005
HashTable *keytable = Z_ARRVAL_P(z_array);
20062006

2007-
for(i = 0, j = 0, zend_hash_internal_pointer_reset(keytable);
2007+
for(j = 0, zend_hash_internal_pointer_reset(keytable);
20082008
zend_hash_has_more_elements(keytable) == SUCCESS;
2009-
zend_hash_move_forward(keytable), i++) {
2009+
zend_hash_move_forward(keytable)) {
20102010

20112011
char *key;
20122012
unsigned int key_len;
@@ -2019,17 +2019,24 @@ PHPAPI int generic_multiple_args_cmd(INTERNAL_FUNCTION_PARAMETERS, char *keyword
20192019
continue; /* this should never happen, according to the PHP people. */
20202020
}
20212021

2022-
if(Z_TYPE_PP(z_value_pp) == IS_STRING) {
2022+
2023+
if(!all_keys && j != 0) { /* not just operating on keys */
2024+
2025+
redis_serialize(redis_sock, *z_value_pp, &keys[j], &keys_len[j] TSRMLS_CC);
2026+
2027+
} else if(Z_TYPE_PP(z_value_pp) == IS_STRING) {
20232028
/* get current value */
20242029
keys[j] = Z_STRVAL_PP(z_value_pp);
20252030
keys_len[j] = Z_STRLEN_PP(z_value_pp);
20262031

20272032
redis_key_prefix(redis_sock, &keys[j], &keys_len[j] TSRMLS_CC); /* add optional prefix */
2033+
} else {
2034+
continue;
2035+
}
20282036

2029-
cmd_len += 1 + integer_length(keys_len[j]) + 2 + keys_len[j] + 2; /* $ + size + NL + string + NL */
2030-
j++;
2031-
real_argc++;
2032-
}
2037+
cmd_len += 1 + integer_length(keys_len[j]) + 2 + keys_len[j] + 2; /* $ + size + NL + string + NL */
2038+
j++;
2039+
real_argc++;
20332040
}
20342041
if(has_timeout) {
20352042
keys_len[j] = spprintf(&keys[j], 0, "%d", timeout);
@@ -2048,16 +2055,23 @@ PHPAPI int generic_multiple_args_cmd(INTERNAL_FUNCTION_PARAMETERS, char *keyword
20482055
}
20492056

20502057
for(i = 0, j = 0; i < argc; ++i) { /* store each key */
2051-
if(Z_TYPE_P(z_args[i]) == IS_STRING) {
2058+
if(!all_keys && j != 0) { /* not just operating on keys */
2059+
2060+
redis_serialize(redis_sock, z_args[i], &keys[j], &keys_len[j] TSRMLS_CC);
2061+
2062+
} else if(Z_TYPE_P(z_args[i]) == IS_STRING) {
20522063
keys[j] = Z_STRVAL_P(z_args[i]);
20532064
keys_len[j] = Z_STRLEN_P(z_args[i]);
20542065

20552066
redis_key_prefix(redis_sock, &keys[j], &keys_len[j] TSRMLS_CC); /* add optional prefix TSRMLS_CC*/
20562067

2057-
cmd_len += 1 + integer_length(keys_len[j]) + 2 + keys_len[j] + 2; /* $ + size + NL + string + NL */
2058-
j++;
2059-
real_argc++;
2060-
}
2068+
} else {
2069+
continue;
2070+
}
2071+
2072+
cmd_len += 1 + integer_length(keys_len[j]) + 2 + keys_len[j] + 2; /* $ + size + NL + string + NL */
2073+
j++;
2074+
real_argc++;
20612075
}
20622076
if(has_timeout) {
20632077
keys_len[j] = spprintf(&keys[j], 0, "%ld", Z_LVAL_P(z_args[j]));
@@ -2089,7 +2103,9 @@ PHPAPI int generic_multiple_args_cmd(INTERNAL_FUNCTION_PARAMETERS, char *keyword
20892103
/* cleanup prefixed keys. */
20902104
if(redis_sock->prefix && redis_sock->prefix_len) {
20912105
for(i = 0; i < real_argc + (has_timeout?-1:0); ++i) {
2092-
efree(keys[i]);
2106+
if(all_keys || i == 0) {
2107+
efree(keys[i]);
2108+
}
20932109
}
20942110
}
20952111
if(has_timeout) { /* cleanup string created to contain timeout value */
@@ -2102,6 +2118,7 @@ PHPAPI int generic_multiple_args_cmd(INTERNAL_FUNCTION_PARAMETERS, char *keyword
21022118
if(z_args) efree(z_args);
21032119

21042120
object = getThis();
2121+
//php_printf("cmd=[%s]\n", cmd);
21052122
REDIS_PROCESS_REQUEST(redis_sock, cmd, cmd_len);
21062123

21072124
return 0;
@@ -2115,7 +2132,7 @@ PHP_METHOD(Redis, sInter) {
21152132

21162133
generic_multiple_args_cmd(INTERNAL_FUNCTION_PARAM_PASSTHRU,
21172134
"SINTER", sizeof("SINTER") - 1,
2118-
0, &redis_sock, 0);
2135+
0, &redis_sock, 0, 1);
21192136

21202137
IF_ATOMIC() {
21212138
if (redis_sock_read_multibulk_reply(INTERNAL_FUNCTION_PARAM_PASSTHRU,
@@ -2135,7 +2152,7 @@ PHP_METHOD(Redis, sInterStore) {
21352152

21362153
generic_multiple_args_cmd(INTERNAL_FUNCTION_PARAM_PASSTHRU,
21372154
"SINTERSTORE", sizeof("SINTERSTORE") - 1,
2138-
1, &redis_sock, 0);
2155+
1, &redis_sock, 0, 1);
21392156

21402157
IF_ATOMIC() {
21412158
redis_long_response(INTERNAL_FUNCTION_PARAM_PASSTHRU, redis_sock, NULL, NULL);
@@ -2154,7 +2171,7 @@ PHP_METHOD(Redis, sUnion) {
21542171

21552172
generic_multiple_args_cmd(INTERNAL_FUNCTION_PARAM_PASSTHRU,
21562173
"SUNION", sizeof("SUNION") - 1,
2157-
0, &redis_sock, 0);
2174+
0, &redis_sock, 0, 1);
21582175

21592176
IF_ATOMIC() {
21602177
if (redis_sock_read_multibulk_reply(INTERNAL_FUNCTION_PARAM_PASSTHRU,
@@ -2173,7 +2190,7 @@ PHP_METHOD(Redis, sUnionStore) {
21732190

21742191
generic_multiple_args_cmd(INTERNAL_FUNCTION_PARAM_PASSTHRU,
21752192
"SUNIONSTORE", sizeof("SUNIONSTORE") - 1,
2176-
1, &redis_sock, 0);
2193+
1, &redis_sock, 0, 1);
21772194

21782195
IF_ATOMIC() {
21792196
redis_long_response(INTERNAL_FUNCTION_PARAM_PASSTHRU, redis_sock, NULL, NULL);
@@ -2191,7 +2208,7 @@ PHP_METHOD(Redis, sDiff) {
21912208

21922209
generic_multiple_args_cmd(INTERNAL_FUNCTION_PARAM_PASSTHRU,
21932210
"SDIFF", sizeof("SDIFF") - 1,
2194-
0, &redis_sock, 0);
2211+
0, &redis_sock, 0, 1);
21952212

21962213
IF_ATOMIC() {
21972214
/* read multibulk reply */
@@ -2212,7 +2229,7 @@ PHP_METHOD(Redis, sDiffStore) {
22122229

22132230
generic_multiple_args_cmd(INTERNAL_FUNCTION_PARAM_PASSTHRU,
22142231
"SDIFFSTORE", sizeof("SDIFFSTORE") - 1,
2215-
1, &redis_sock, 0);
2232+
1, &redis_sock, 0, 1);
22162233

22172234
IF_ATOMIC() {
22182235
redis_long_response(INTERNAL_FUNCTION_PARAM_PASSTHRU, redis_sock, NULL, NULL);
@@ -4026,15 +4043,16 @@ generic_hash_command_2(INTERNAL_FUNCTION_PARAMETERS, char *keyword, int keyword_
40264043
/* hDel */
40274044
PHP_METHOD(Redis, hDel)
40284045
{
4029-
char *cmd;
4030-
int cmd_len;
4031-
RedisSock *redis_sock = generic_hash_command_2(INTERNAL_FUNCTION_PARAM_PASSTHRU, "HDEL", 4, &cmd, &cmd_len);
4046+
RedisSock *redis_sock;
4047+
4048+
generic_multiple_args_cmd(INTERNAL_FUNCTION_PARAM_PASSTHRU,
4049+
"HDEL", sizeof("HDEL") - 1,
4050+
2, &redis_sock, 0, 0);
40324051

4033-
REDIS_PROCESS_REQUEST(redis_sock, cmd, cmd_len);
40344052
IF_ATOMIC() {
4035-
redis_1_response(INTERNAL_FUNCTION_PARAM_PASSTHRU, redis_sock, NULL, NULL);
4053+
redis_long_response(INTERNAL_FUNCTION_PARAM_PASSTHRU, redis_sock, NULL, NULL);
40364054
}
4037-
REDIS_PROCESS_RESPONSE(redis_1_response);
4055+
REDIS_PROCESS_RESPONSE(redis_long_response);
40384056

40394057
}
40404058

tests/TestRedis.php

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1681,10 +1681,9 @@ public function testZX() {
16811681
$this->assertTrue(0 === $this->redis->zUnion('keyU', array('X', 'Y')));
16821682
$this->assertTrue(array() === $this->redis->zRange('keyU', 0, -1));
16831683

1684-
// !Exist U Exist → 0
1684+
// !Exist U Exist → copy of existing zset.
16851685
$this->redis->delete('keyU', 'X');
1686-
var_dump($this->redis->zUnion('keyU', array('key1', 'X')));
1687-
$this->assertTrue(0 === $this->redis->zUnion('keyU', array('key1', 'X')));
1686+
$this->assertTrue(2 === $this->redis->zUnion('keyU', array('key1', 'X')));
16881687

16891688
// test weighted zUnion
16901689
$this->redis->delete('keyZ');
@@ -1796,12 +1795,13 @@ public function testHashes() {
17961795
$this->assertTrue(FALSE === $this->redis->hGet('key', 'c')); // unknownkey
17971796

17981797
// hDel
1799-
$this->assertTrue(TRUE === $this->redis->hDel('h', 'a')); // TRUE on success
1800-
$this->assertTrue(FALSE === $this->redis->hDel('h', 'a')); // FALSE on failure
1798+
$this->assertTrue(1 === $this->redis->hDel('h', 'a')); // 1 on success
1799+
$this->assertTrue(0 === $this->redis->hDel('h', 'a')); // 0 on failure
18011800

18021801
$this->redis->delete('h');
18031802
$this->redis->hSet('h', 'x', 'a');
18041803
$this->redis->hSet('h', 'y', 'b');
1804+
$this->assertTrue(2 === $this->redis->hDel('h', 'x', 'y')); // variadic
18051805

18061806
// hsetnx
18071807
$this->redis->delete('h');
@@ -2508,8 +2508,8 @@ protected function sequence($mode) {
25082508
$this->assertTrue($ret[$i++] === array('key1' => 'value1', 'key2' => 'value2', 'key3' => 'value3')); // hmget, 3 elements
25092509
$this->assertTrue($ret[$i++] === 'value1'); // hget
25102510
$this->assertTrue($ret[$i++] === 3); // hlen
2511-
$this->assertTrue($ret[$i++] === TRUE); // hdel succeeded
2512-
$this->assertTrue($ret[$i++] === FALSE); // hdel failed
2511+
$this->assertTrue($ret[$i++] === 1); // hdel succeeded
2512+
$this->assertTrue($ret[$i++] === 0); // hdel failed
25132513
$this->assertTrue($ret[$i++] === FALSE); // hexists didn't find the deleted key
25142514
$this->assertTrue($ret[$i] === array('key1', 'key3') || $ret[$i] === array('key3', 'key1')); $i++; // hkeys
25152515
$this->assertTrue($ret[$i] === array('value1', 'value3') || $ret[$i] === array('value3', 'value1')); $i++; // hvals

0 commit comments

Comments
 (0)