Skip to content

Commit 1d56b20

Browse files
committed
Multi/Exec support for MGET, MSET, and DEL.
1 parent 9160752 commit 1d56b20

File tree

2 files changed

+74
-0
lines changed

2 files changed

+74
-0
lines changed

redis_array.c

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -559,6 +559,29 @@ PHP_METHOD(RedisArray, setOption)
559559
efree(z_args[0]);
560560
efree(z_args[1]);
561561
}
562+
#define HANDLE_MULTI_EXEC(cmd) do {\
563+
if (redis_array_get(getThis(), &ra TSRMLS_CC) >= 0 && ra->z_multi_exec) {\
564+
int i, num_varargs;\
565+
zval ***varargs = NULL;\
566+
zval z_arg_array;\
567+
if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O*",\
568+
&object, redis_array_ce, &varargs, &num_varargs) == FAILURE) {\
569+
RETURN_FALSE;\
570+
}\
571+
/* copy all args into a zval hash table */\
572+
array_init(&z_arg_array);\
573+
for(i = 0; i < num_varargs; ++i) {\
574+
add_next_index_zval(&z_arg_array, *varargs[i]);\
575+
}\
576+
/* call */\
577+
ra_forward_call(INTERNAL_FUNCTION_PARAM_PASSTHRU, ra, cmd, sizeof(cmd)-1, &z_arg_array, NULL);\
578+
zval_dtor(&z_arg_array);\
579+
if(varargs) {\
580+
efree(varargs);\
581+
}\
582+
return;\
583+
}\
584+
}while(0)
562585

563586
/* MGET will distribute the call to several nodes and regroup the values. */
564587
PHP_METHOD(RedisArray, mget)
@@ -571,6 +594,9 @@ PHP_METHOD(RedisArray, mget)
571594
HashPosition pointer;
572595
zval **redis_instances, *redis_inst, **argv;
573596

597+
/* Multi/exec support */
598+
HANDLE_MULTI_EXEC("MGET");
599+
574600
if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Oa",
575601
&object, redis_array_ce, &z_keys) == FAILURE) {
576602
RETURN_FALSE;
@@ -691,6 +717,9 @@ PHP_METHOD(RedisArray, mset)
691717
int key_len, type, *key_lens;
692718
long idx;
693719

720+
/* Multi/exec support */
721+
HANDLE_MULTI_EXEC("MSET");
722+
694723
if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Oa",
695724
&object, redis_array_ce, &z_keys) == FAILURE) {
696725
RETURN_FALSE;
@@ -792,6 +821,9 @@ PHP_METHOD(RedisArray, del)
792821
long total = 0;
793822
int free_zkeys = 0;
794823

824+
/* Multi/exec support */
825+
HANDLE_MULTI_EXEC("DEL");
826+
795827
/* get all args in z_args */
796828
z_args = emalloc(ZEND_NUM_ARGS() * sizeof(zval*));
797829
if(zend_get_parameters_array(ht, ZEND_NUM_ARGS(), z_args) == FAILURE) {

tests/array-rehash.php

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,7 @@ public function testKeyDistribution() {
278278

279279
public function testMultiExec() {
280280

281+
// Joe gets a promotion
281282
$newGroup = $this->ra->get('group:executives');
282283
$newSalary = 4000;
283284

@@ -291,6 +292,47 @@ public function testMultiExec() {
291292
// check that the group and salary have been changed
292293
$this->assertTrue($this->ra->get('1_{employee:joe}_group') === $newGroup);
293294
$this->assertTrue($this->ra->get('1_{employee:joe}_salary') == $newSalary);
295+
296+
}
297+
298+
public function testMultiExecMSet() {
299+
300+
global $newGroup, $newSalary;
301+
$newGroup = 1;
302+
$newSalary = 10000;
303+
304+
// test MSET, making Joe a top-level executive
305+
$out = $this->ra->multi($this->ra->_target('{employee:joe}'))
306+
->mset(array('1_{employee:joe}_group' => $newGroup, '1_{employee:joe}_salary' => $newSalary))
307+
->exec();
308+
309+
$this->assertTrue($out[0] === TRUE);
310+
311+
}
312+
313+
public function testMultiExecMGet() {
314+
315+
global $newGroup, $newSalary;
316+
317+
// test MGET
318+
$out = $this->ra->multi($this->ra->_target('{employee:joe}'))
319+
->mget(array('1_{employee:joe}_group', '1_{employee:joe}_salary'))
320+
->exec();
321+
322+
$this->assertTrue($out[0][0] == $newGroup);
323+
$this->assertTrue($out[0][1] == $newSalary);
324+
}
325+
326+
public function testMultiExecDel() {
327+
328+
// test DEL
329+
$out = $this->ra->multi($this->ra->_target('{employee:joe}'))
330+
->del('1_{employee:joe}_group', '1_{employee:joe}_salary')
331+
->exec();
332+
333+
$this->assertTrue($out[0] === 2);
334+
$this->assertTrue($this->ra->exists('1_{employee:joe}_group') === FALSE);
335+
$this->assertTrue($this->ra->exists('1_{employee:joe}_salary') === FALSE);
294336
}
295337

296338
}

0 commit comments

Comments
 (0)