Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 40a2c25

Browse files
Implement COPY for RedisCluster
* Refactor `redis_copy_cmd` to use the new argument parsing macros. * Add a handler in `RedisCluster`. See #1894
1 parent e222b85 commit 40a2c25

7 files changed

Lines changed: 70 additions & 34 deletions

redis_cluster.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3142,5 +3142,9 @@ PHP_METHOD(RedisCluster, command) {
31423142
CLUSTER_PROCESS_CMD(command, cluster_variant_resp, 0);
31433143
}
31443144

3145+
PHP_METHOD(RedisCluster, copy) {
3146+
CLUSTER_PROCESS_CMD(copy, cluster_1_resp, 0)
3147+
}
3148+
31453149
/* vim: set tabstop=4 softtabstop=4 expandtab shiftwidth=4: */
31463150

redis_cluster.stub.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,11 @@ public function config(string|array $key_or_address, string $subcommand, mixed .
227227
*/
228228
public function dbsize(string|array $key_or_address): RedisCluster|int;
229229

230+
/**
231+
* @see https://redis.io/commands/copy
232+
*/
233+
public function copy(string $src, string $dst, array $options = null): RedisCluster|bool;
234+
230235
/**
231236
* @see Redis::decr()
232237
*/

redis_cluster_arginfo.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/* This is a generated file, edit the .stub.php file instead.
2-
* Stub hash: 2225d10403eb94c52ad017310e783115b9ea869e */
2+
* Stub hash: e6c2d8efa4150e1cb198470d8106e693661c1e4f */
33

44
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_RedisCluster___construct, 0, 0, 1)
55
ZEND_ARG_TYPE_INFO(0, name, IS_STRING, 1)
@@ -165,6 +165,12 @@ ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_class_RedisCluster_dbsize, 0
165165
ZEND_ARG_TYPE_MASK(0, key_or_address, MAY_BE_STRING|MAY_BE_ARRAY, NULL)
166166
ZEND_END_ARG_INFO()
167167

168+
ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_class_RedisCluster_copy, 0, 2, RedisCluster, MAY_BE_BOOL)
169+
ZEND_ARG_TYPE_INFO(0, src, IS_STRING, 0)
170+
ZEND_ARG_TYPE_INFO(0, dst, IS_STRING, 0)
171+
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, options, IS_ARRAY, 0, "null")
172+
ZEND_END_ARG_INFO()
173+
168174
ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_class_RedisCluster_decr, 0, 1, RedisCluster, MAY_BE_LONG|MAY_BE_FALSE)
169175
ZEND_ARG_TYPE_INFO(0, key, IS_STRING, 0)
170176
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, by, IS_LONG, 0, "1")
@@ -1042,6 +1048,7 @@ ZEND_METHOD(RedisCluster, cluster);
10421048
ZEND_METHOD(RedisCluster, command);
10431049
ZEND_METHOD(RedisCluster, config);
10441050
ZEND_METHOD(RedisCluster, dbsize);
1051+
ZEND_METHOD(RedisCluster, copy);
10451052
ZEND_METHOD(RedisCluster, decr);
10461053
ZEND_METHOD(RedisCluster, decrby);
10471054
ZEND_METHOD(RedisCluster, decrbyfloat);
@@ -1260,6 +1267,7 @@ static const zend_function_entry class_RedisCluster_methods[] = {
12601267
ZEND_ME(RedisCluster, command, arginfo_class_RedisCluster_command, ZEND_ACC_PUBLIC)
12611268
ZEND_ME(RedisCluster, config, arginfo_class_RedisCluster_config, ZEND_ACC_PUBLIC)
12621269
ZEND_ME(RedisCluster, dbsize, arginfo_class_RedisCluster_dbsize, ZEND_ACC_PUBLIC)
1270+
ZEND_ME(RedisCluster, copy, arginfo_class_RedisCluster_copy, ZEND_ACC_PUBLIC)
12631271
ZEND_ME(RedisCluster, decr, arginfo_class_RedisCluster_decr, ZEND_ACC_PUBLIC)
12641272
ZEND_ME(RedisCluster, decrby, arginfo_class_RedisCluster_decrby, ZEND_ACC_PUBLIC)
12651273
ZEND_ME(RedisCluster, decrbyfloat, arginfo_class_RedisCluster_decrbyfloat, ZEND_ACC_PUBLIC)

redis_cluster_legacy_arginfo.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/* This is a generated file, edit the .stub.php file instead.
2-
* Stub hash: 2225d10403eb94c52ad017310e783115b9ea869e */
2+
* Stub hash: e6c2d8efa4150e1cb198470d8106e693661c1e4f */
33

44
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_RedisCluster___construct, 0, 0, 1)
55
ZEND_ARG_INFO(0, name)
@@ -151,6 +151,12 @@ ZEND_END_ARG_INFO()
151151

152152
#define arginfo_class_RedisCluster_dbsize arginfo_class_RedisCluster_bgrewriteaof
153153

154+
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_RedisCluster_copy, 0, 0, 2)
155+
ZEND_ARG_INFO(0, src)
156+
ZEND_ARG_INFO(0, dst)
157+
ZEND_ARG_INFO(0, options)
158+
ZEND_END_ARG_INFO()
159+
154160
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_RedisCluster_decr, 0, 0, 1)
155161
ZEND_ARG_INFO(0, key)
156162
ZEND_ARG_INFO(0, by)
@@ -886,6 +892,7 @@ ZEND_METHOD(RedisCluster, cluster);
886892
ZEND_METHOD(RedisCluster, command);
887893
ZEND_METHOD(RedisCluster, config);
888894
ZEND_METHOD(RedisCluster, dbsize);
895+
ZEND_METHOD(RedisCluster, copy);
889896
ZEND_METHOD(RedisCluster, decr);
890897
ZEND_METHOD(RedisCluster, decrby);
891898
ZEND_METHOD(RedisCluster, decrbyfloat);
@@ -1104,6 +1111,7 @@ static const zend_function_entry class_RedisCluster_methods[] = {
11041111
ZEND_ME(RedisCluster, command, arginfo_class_RedisCluster_command, ZEND_ACC_PUBLIC)
11051112
ZEND_ME(RedisCluster, config, arginfo_class_RedisCluster_config, ZEND_ACC_PUBLIC)
11061113
ZEND_ME(RedisCluster, dbsize, arginfo_class_RedisCluster_dbsize, ZEND_ACC_PUBLIC)
1114+
ZEND_ME(RedisCluster, copy, arginfo_class_RedisCluster_copy, ZEND_ACC_PUBLIC)
11071115
ZEND_ME(RedisCluster, decr, arginfo_class_RedisCluster_decr, ZEND_ACC_PUBLIC)
11081116
ZEND_ME(RedisCluster, decrby, arginfo_class_RedisCluster_decrby, ZEND_ACC_PUBLIC)
11091117
ZEND_ME(RedisCluster, decrbyfloat, arginfo_class_RedisCluster_decrbyfloat, ZEND_ACC_PUBLIC)

redis_commands.c

Lines changed: 34 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -5345,44 +5345,56 @@ int
53455345
redis_copy_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
53465346
char **cmd, int *cmd_len, short *slot, void **ctx)
53475347
{
5348+
zend_string *src = NULL, *dst = NULL;
53485349
smart_string cmdstr = {0};
5349-
char *src, *dst;
5350-
size_t src_len, dst_len;
5351-
zend_long db = -1;
5350+
HashTable *opts = NULL;
53525351
zend_bool replace = 0;
5353-
zval *opts = NULL, *z_ele;
53545352
zend_string *zkey;
5353+
zend_long db = -1;
5354+
short slot2;
5355+
zval *zv;
53555356

5356-
if (zend_parse_parameters(ZEND_NUM_ARGS(), "ss|a",
5357-
&src, &src_len, &dst, &dst_len, &opts) == FAILURE)
5358-
{
5359-
return FAILURE;
5360-
}
5357+
ZEND_PARSE_PARAMETERS_START(2, 3)
5358+
Z_PARAM_STR(src)
5359+
Z_PARAM_STR(dst)
5360+
Z_PARAM_OPTIONAL
5361+
Z_PARAM_ARRAY_HT_OR_NULL(opts)
5362+
ZEND_PARSE_PARAMETERS_END_EX(return FAILURE);
53615363

53625364
if (opts != NULL) {
5363-
ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(opts), zkey, z_ele) {
5364-
if (zkey != NULL) {
5365-
ZVAL_DEREF(z_ele);
5366-
if (zend_string_equals_literal_ci(zkey, "db")) {
5367-
db = zval_get_long(z_ele);
5368-
} else if (zend_string_equals_literal_ci(zkey, "replace")) {
5369-
replace = zval_is_true(z_ele);
5370-
}
5365+
ZEND_HASH_FOREACH_STR_KEY_VAL(opts, zkey, zv) {
5366+
if (zkey == NULL)
5367+
continue;
5368+
5369+
ZVAL_DEREF(zv);
5370+
if (zend_string_equals_literal_ci(zkey, "db")) {
5371+
db = zval_get_long(zv);
5372+
} else if (zend_string_equals_literal_ci(zkey, "replace")) {
5373+
replace = zval_is_true(zv);
53715374
}
53725375
} ZEND_HASH_FOREACH_END();
53735376
}
53745377

5378+
if (slot && db != -1) {
5379+
php_error_docref(NULL, E_WARNING, "Cant copy to a specific DB in cluster mode");
5380+
return FAILURE;
5381+
}
5382+
53755383
REDIS_CMD_INIT_SSTR_STATIC(&cmdstr, 2 + (db > -1 ? 2 : 0) + replace, "COPY");
5376-
redis_cmd_append_sstr(&cmdstr, src, src_len);
5377-
redis_cmd_append_sstr(&cmdstr, dst, dst_len);
5384+
redis_cmd_append_sstr_key_zstr(&cmdstr, src, redis_sock, slot);
5385+
redis_cmd_append_sstr_key_zstr(&cmdstr, dst, redis_sock, slot ? &slot2 : NULL);
5386+
5387+
if (slot && *slot != slot2) {
5388+
php_error_docref(NULL, E_WARNING, "Keys must hash to the same slot!");
5389+
efree(cmdstr.c);
5390+
return FAILURE;
5391+
}
53785392

53795393
if (db > -1) {
53805394
REDIS_CMD_APPEND_SSTR_STATIC(&cmdstr, "DB");
53815395
redis_cmd_append_sstr_long(&cmdstr, db);
53825396
}
5383-
if (replace) {
5384-
REDIS_CMD_APPEND_SSTR_STATIC(&cmdstr, "REPLACE");
5385-
}
5397+
REDIS_CMD_APPEND_SSTR_OPT_STATIC(&cmdstr, replace, "REPLACE");
53865398

53875399
*cmd = cmdstr.c;
53885400
*cmd_len = cmdstr.len;

tests/RedisClusterTest.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,6 @@ public function testzUnion() { return $this->markTestSkipped(); }
5757
public function testzDiffStore() { return $this->markTestSkipped(); }
5858
public function testzMscore() { return $this->marktestSkipped(); }
5959
public function testZRandMember() { return $this->marktestSkipped(); }
60-
public function testCopy() { return $this->marktestSkipped(); }
6160
public function testConfig() { return $this->markTestSkipped(); }
6261
public function testFlushDB() { return $this->markTestSkipped(); }
6362

tests/RedisTest.php

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7531,17 +7531,17 @@ public function testCopy()
75317531
return;
75327532
}
75337533

7534-
$this->redis->del('key2');
7535-
$this->redis->set('key', 'foo');
7536-
$this->assertTrue($this->redis->copy('key', 'key2'));
7537-
$this->assertEquals('foo', $this->redis->get('key2'));
7534+
$this->redis->del('{key}dst');
7535+
$this->redis->set('{key}src', 'foo');
7536+
$this->assertTrue($this->redis->copy('{key}src', '{key}dst'));
7537+
$this->assertEquals('foo', $this->redis->get('{key}dst'));
75387538

7539-
$this->redis->set('key', 'bar');
7540-
$this->assertFalse($this->redis->copy('key', 'key2'));
7541-
$this->assertEquals('foo', $this->redis->get('key2'));
7539+
$this->redis->set('{key}src', 'bar');
7540+
$this->assertFalse($this->redis->copy('{key}src', '{key}dst'));
7541+
$this->assertEquals('foo', $this->redis->get('{key}dst'));
75427542

7543-
$this->assertTrue($this->redis->copy('key', 'key2', ['replace' => true]));
7544-
$this->assertEquals('bar', $this->redis->get('key2'));
7543+
$this->assertTrue($this->redis->copy('{key}src', '{key}dst', ['replace' => true]));
7544+
$this->assertEquals('bar', $this->redis->get('{key}dst'));
75457545
}
75467546

75477547
public function testCommand()

0 commit comments

Comments
 (0)