Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/phpredis/phpredis.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--php_redis.h1
-rw-r--r--redis.c13
-rw-r--r--redis_commands.c50
-rw-r--r--redis_commands.h3
-rw-r--r--tests/RedisTest.php21
5 files changed, 88 insertions, 0 deletions
diff --git a/php_redis.h b/php_redis.h
index e3ed29c8..9d44e513 100644
--- a/php_redis.h
+++ b/php_redis.h
@@ -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);
diff --git a/redis.c b/redis.c
index d65699c1..91eba589 100644
--- a/redis.c
+++ b/redis.c
@@ -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)
@@ -3534,6 +3541,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,
diff --git a/redis_commands.c b/redis_commands.c
index 85e23e46..027fbda0 100644
--- a/redis_commands.c
+++ b/redis_commands.c
@@ -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)
diff --git a/redis_commands.h b/redis_commands.h
index a641851e..3a3e0491 100644
--- a/redis_commands.h
+++ b/redis_commands.h
@@ -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);
diff --git a/tests/RedisTest.php b/tests/RedisTest.php
index f00f38ac..c8443e65 100644
--- a/tests/RedisTest.php
+++ b/tests/RedisTest.php
@@ -6579,6 +6579,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();