Add Redis::copy command
This commit is contained in:
Pavlo Yatsukhnenko
2021-02-27 23:12:23 +02:00
parent 1f2a7ef6b5
commit 037dbbf93d
5 changed files with 88 additions and 0 deletions
+1
View File
@@ -41,6 +41,7 @@ PHP_METHOD(Redis, bzPopMax);
PHP_METHOD(Redis, bzPopMin);
PHP_METHOD(Redis, close);
PHP_METHOD(Redis, connect);
PHP_METHOD(Redis, copy);
PHP_METHOD(Redis, dbSize);
PHP_METHOD(Redis, decr);
PHP_METHOD(Redis, decrBy);
+13
View File
@@ -134,6 +134,12 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_config, 0, 0, 2)
ZEND_ARG_INFO(0, value)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(arginfo_copy, 0, 0, 2)
ZEND_ARG_INFO(0, source)
ZEND_ARG_INFO(0, destination)
ZEND_ARG_ARRAY_INFO(0, options, 0)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(arginfo_flush, 0, 0, 0)
ZEND_ARG_INFO(0, async)
ZEND_END_ARG_INFO()
@@ -283,6 +289,7 @@ static zend_function_entry redis_functions[] = {
PHP_ME(Redis, command, arginfo_command, ZEND_ACC_PUBLIC)
PHP_ME(Redis, config, arginfo_config, ZEND_ACC_PUBLIC)
PHP_ME(Redis, connect, arginfo_connect, ZEND_ACC_PUBLIC)
PHP_ME(Redis, copy, arginfo_copy, ZEND_ACC_PUBLIC)
PHP_ME(Redis, dbSize, arginfo_void, ZEND_ACC_PUBLIC)
PHP_ME(Redis, debug, arginfo_key, ZEND_ACC_PUBLIC)
PHP_ME(Redis, decr, arginfo_key, ZEND_ACC_PUBLIC)
@@ -3535,6 +3542,12 @@ PHP_METHOD(Redis, command) {
}
/* }}} */
/* {{{ proto array Redis::copy(string $source, string $destination, array $options = null) */
PHP_METHOD(Redis, copy) {
REDIS_PROCESS_CMD(copy, redis_1_response)
}
/* }}} */
/* Helper to format any combination of SCAN arguments */
PHP_REDIS_API int
redis_build_scan_cmd(char **cmd, REDIS_SCAN_TYPE type, char *key, int key_len,
+50
View File
@@ -3299,6 +3299,56 @@ int redis_command_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
return SUCCESS;
}
int
redis_copy_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
char **cmd, int *cmd_len, short *slot, void **ctx)
{
smart_string cmdstr = {0};
char *src, *dst;
size_t src_len, dst_len;
zend_long db = -1;
zend_bool replace = 0;
zval *opts = NULL;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "ss|a",
&src, &src_len, &dst, &dst_len, &opts) == FAILURE)
{
return FAILURE;
}
if (opts != NULL && Z_TYPE_P(opts) == IS_ARRAY) {
zend_ulong idx;
zend_string *zkey;
zval *z_ele;
ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(opts), idx, zkey, z_ele) {
if (zkey != NULL) {
ZVAL_DEREF(z_ele);
if (zend_string_equals_literal_ci(zkey, "db")) {
db = zval_get_long(z_ele);
} else if (zend_string_equals_literal_ci(zkey, "replace")) {
replace = zval_is_true(z_ele);
}
}
} ZEND_HASH_FOREACH_END();
}
REDIS_CMD_INIT_SSTR_STATIC(&cmdstr, 2 + (db > -1) + replace, "COPY");
redis_cmd_append_sstr(&cmdstr, src, src_len);
redis_cmd_append_sstr(&cmdstr, dst, dst_len);
if (db > -1) {
REDIS_CMD_APPEND_SSTR_STATIC(&cmdstr, "DB");
redis_cmd_append_sstr_long(&cmdstr, db);
}
if (replace) {
REDIS_CMD_APPEND_SSTR_STATIC(&cmdstr, "REPLACE");
}
*cmd = cmdstr.c;
*cmd_len = cmdstr.len;
return SUCCESS;
}
/* XADD */
int redis_xadd_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
char **cmd, int *cmd_len, short *slot, void **ctx)
+3
View File
@@ -259,6 +259,9 @@ int redis_sdiffstore_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
int redis_command_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
char **cmd, int *cmd_len, short *slot, void **ctx);
int redis_copy_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
char **cmd, int *cmd_len, short *slot, void **ctx);
int redis_fmt_scan_cmd(char **cmd, REDIS_SCAN_TYPE type, char *key, int key_len,
long it, char *pat, int pat_len, long count);
+21
View File
@@ -6571,6 +6571,27 @@ class Redis_Test extends TestSuite
}
}
public function testCopy()
{
// Only available since 6.2.0
if (version_compare($this->version, '6.2.0') < 0) {
$this->markTestSkipped();
return;
}
$this->redis->del('key2');
$this->redis->set('key', 'foo');
$this->assertTrue($this->redis->copy('key', 'key2'));
$this->assertEquals('foo', $this->redis->get('key2'));
$this->redis->set('key', 'bar');
$this->assertFalse($this->redis->copy('key', 'key2'));
$this->assertEquals('foo', $this->redis->get('key2'));
$this->assertTrue($this->redis->copy('key', 'key2', ['replace' => true]));
$this->assertEquals('bar', $this->redis->get('key2'));
}
public function testSession_regenerateSessionId_noLock_noDestroy() {
$this->setSessionHandler();
$sessionId = $this->generateSessionId();