This is an automated email from the ASF dual-hosted git repository.
hulk pushed a commit to branch unstable
in repository https://gitbox.apache.org/repos/asf/kvrocks.git
The following commit(s) were added to refs/heads/unstable by this push:
new ed5937ce Add support of the command COPY (#2238)
ed5937ce is described below
commit ed5937ce391c3949439d58ceba89908bf0c2c34d
Author: Chiro11 <[email protected]>
AuthorDate: Fri Apr 12 21:03:11 2024 +0800
Add support of the command COPY (#2238)
---
src/commands/cmd_key.cc | 84 +++-
src/storage/redis_db.cc | 16 +-
src/storage/redis_db.h | 8 +-
.../{rename/rename_test.go => copy/copy_test.go} | 531 ++++++++++++---------
tests/gocase/unit/rename/rename_test.go | 22 +-
5 files changed, 391 insertions(+), 270 deletions(-)
diff --git a/src/commands/cmd_key.cc b/src/commands/cmd_key.cc
index 8576db4f..589fa1ed 100644
--- a/src/commands/cmd_key.cc
+++ b/src/commands/cmd_key.cc
@@ -83,14 +83,13 @@ class CommandMoveX : public Commander {
break;
}
- bool ret = true;
- bool key_exist = true;
+ Database::CopyResult res = Database::CopyResult::DONE;
std::string ns_key = redis.AppendNamespacePrefix(key);
std::string new_ns_key = ComposeNamespaceKey(ns, key,
srv->storage->IsSlotIdEncoded());
- auto s = redis.Move(ns_key, new_ns_key, true, &ret, &key_exist);
+ auto s = redis.Copy(ns_key, new_ns_key, true, true, &res);
if (!s.ok()) return {Status::RedisExecErr, s.ToString()};
- if (ret && key_exist) {
+ if (res == Database::CopyResult::DONE) {
*output = redis::Integer(1);
} else {
*output = redis::Integer(0);
@@ -222,7 +221,7 @@ class CommandExpireAt : public Commander {
timestamp_ = *parse_result;
- return Commander::Parse(args);
+ return Status::OK();
}
Status Execute(Server *srv, Connection *conn, std::string *output) override {
@@ -346,14 +345,12 @@ class CommandRename : public Commander {
public:
Status Execute(Server *srv, Connection *conn, std::string *output) override {
redis::Database redis(srv->storage, conn->GetNamespace());
- bool ret = true;
- bool key_exist = true;
+ Database::CopyResult res = Database::CopyResult::DONE;
std::string ns_key = redis.AppendNamespacePrefix(args_[1]);
std::string new_ns_key = redis.AppendNamespacePrefix(args_[2]);
- auto s = redis.Move(ns_key, new_ns_key, false, &ret, &key_exist);
+ auto s = redis.Copy(ns_key, new_ns_key, false, true, &res);
if (!s.ok()) return {Status::RedisExecErr, s.ToString()};
- if (!key_exist) return {Status::RedisExecErr,
rocksdb::Status::InvalidArgument("ERR no such key").ToString()};
-
+ if (res == Database::CopyResult::KEY_NOT_EXIST) return
{Status::RedisExecErr, "no such key"};
*output = redis::SimpleString("OK");
return Status::OK();
}
@@ -363,20 +360,68 @@ class CommandRenameNX : public Commander {
public:
Status Execute(Server *srv, Connection *conn, std::string *output) override {
redis::Database redis(srv->storage, conn->GetNamespace());
- bool ret = true;
- bool key_exist = true;
+ Database::CopyResult res = Database::CopyResult::DONE;
std::string ns_key = redis.AppendNamespacePrefix(args_[1]);
std::string new_ns_key = redis.AppendNamespacePrefix(args_[2]);
- auto s = redis.Move(ns_key, new_ns_key, true, &ret, &key_exist);
+ auto s = redis.Copy(ns_key, new_ns_key, true, true, &res);
if (!s.ok()) return {Status::RedisExecErr, s.ToString()};
- if (!key_exist) return {Status::RedisExecErr,
rocksdb::Status::InvalidArgument("ERR no such key").ToString()};
- if (ret) {
- *output = redis::Integer(1);
- } else {
- *output = redis::Integer(0);
+ switch (res) {
+ case Database::CopyResult::KEY_NOT_EXIST:
+ return {Status::RedisExecErr, "no such key"};
+ case Database::CopyResult::DONE:
+ *output = redis::Integer(1);
+ break;
+ case Database::CopyResult::KEY_ALREADY_EXIST:
+ *output = redis::Integer(0);
+ break;
+ }
+ return Status::OK();
+ }
+};
+
+class CommandCopy : public Commander {
+ public:
+ Status Parse(const std::vector<std::string> &args) override {
+ CommandParser parser(args, 3);
+ while (parser.Good()) {
+ if (parser.EatEqICase("db")) {
+ auto db_num = GET_OR_RET(parser.TakeInt());
+ // There's only one database in Kvrocks, so the DB must be 0 here.
+ if (db_num != 0) {
+ return {Status::RedisParseErr, errInvalidSyntax};
+ }
+ } else if (parser.EatEqICase("replace")) {
+ replace_ = true;
+ } else {
+ return parser.InvalidSyntax();
+ }
}
+
return Status::OK();
}
+
+ Status Execute(Server *srv, Connection *conn, std::string *output) override {
+ redis::Database redis(srv->storage, conn->GetNamespace());
+ Database::CopyResult res = Database::CopyResult::DONE;
+ std::string ns_key = redis.AppendNamespacePrefix(args_[1]);
+ std::string new_ns_key = redis.AppendNamespacePrefix(args_[2]);
+ auto s = redis.Copy(ns_key, new_ns_key, !replace_, false, &res);
+ if (!s.ok()) return {Status::RedisExecErr, s.ToString()};
+ switch (res) {
+ case Database::CopyResult::KEY_NOT_EXIST:
+ return {Status::RedisExecErr, "no such key"};
+ case Database::CopyResult::DONE:
+ *output = redis::Integer(1);
+ break;
+ case Database::CopyResult::KEY_ALREADY_EXIST:
+ *output = redis::Integer(0);
+ break;
+ }
+ return Status::OK();
+ }
+
+ private:
+ bool replace_ = false;
};
REDIS_REGISTER_COMMANDS(MakeCmdAttr<CommandTTL>("ttl", 2, "read-only", 1, 1,
1),
@@ -396,6 +441,7 @@ REDIS_REGISTER_COMMANDS(MakeCmdAttr<CommandTTL>("ttl", 2,
"read-only", 1, 1, 1),
MakeCmdAttr<CommandDel>("del", -2, "write
no-dbsize-check", 1, -1, 1),
MakeCmdAttr<CommandDel>("unlink", -2, "write
no-dbsize-check", 1, -1, 1),
MakeCmdAttr<CommandRename>("rename", 3, "write", 1, 2,
1),
- MakeCmdAttr<CommandRenameNX>("renamenx", 3, "write",
1, 2, 1), )
+ MakeCmdAttr<CommandRenameNX>("renamenx", 3, "write",
1, 2, 1),
+ MakeCmdAttr<CommandCopy>("copy", -3, "write", 1, 2,
1), )
} // namespace redis
diff --git a/src/storage/redis_db.cc b/src/storage/redis_db.cc
index 49b6ab2a..fab6562b 100644
--- a/src/storage/redis_db.cc
+++ b/src/storage/redis_db.cc
@@ -708,10 +708,8 @@ rocksdb::Status Database::typeInternal(const Slice &key,
RedisType *type) {
return rocksdb::Status::OK();
}
-rocksdb::Status Database::Move(const std::string &key, const std::string
&new_key, bool nx, bool *ret,
- bool *key_exist) {
- *ret = true;
- *key_exist = true;
+rocksdb::Status Database::Copy(const std::string &key, const std::string
&new_key, bool nx, bool delete_old,
+ CopyResult *res) {
std::vector<std::string> lock_keys = {key, new_key};
MultiLockGuard guard(storage_->GetLockManager(), lock_keys);
@@ -719,7 +717,7 @@ rocksdb::Status Database::Move(const std::string &key,
const std::string &new_ke
auto s = typeInternal(key, &type);
if (!s.ok()) return s;
if (type == kRedisNone) {
- *key_exist = false;
+ *res = CopyResult::KEY_NOT_EXIST;
return rocksdb::Status::OK();
}
@@ -727,11 +725,13 @@ rocksdb::Status Database::Move(const std::string &key,
const std::string &new_ke
int exist = 0;
if (s = existsInternal({new_key}, &exist), !s.ok()) return s;
if (exist > 0) {
- *ret = false;
+ *res = CopyResult::KEY_ALREADY_EXIST;
return rocksdb::Status::OK();
}
}
+ *res = CopyResult::DONE;
+
if (key == new_key) return rocksdb::Status::OK();
auto batch = storage_->GetWriteBatchBase();
@@ -741,8 +741,10 @@ rocksdb::Status Database::Move(const std::string &key,
const std::string &new_ke
engine::DBIterator iter(storage_, rocksdb::ReadOptions());
iter.Seek(key);
+ if (delete_old) {
+ batch->Delete(metadata_cf_handle_, key);
+ }
// copy metadata
- batch->Delete(metadata_cf_handle_, key);
batch->Put(metadata_cf_handle_, new_key, iter.Value());
auto subkey_iter = iter.GetSubKeyIterator();
diff --git a/src/storage/redis_db.h b/src/storage/redis_db.h
index 909e967b..31de41dc 100644
--- a/src/storage/redis_db.h
+++ b/src/storage/redis_db.h
@@ -101,9 +101,11 @@ class Database {
rocksdb::ColumnFamilyHandle *cf_handle = nullptr);
[[nodiscard]] rocksdb::Status ClearKeysOfSlot(const rocksdb::Slice &ns, int
slot);
[[nodiscard]] rocksdb::Status KeyExist(const std::string &key);
- // Move <key,value> to <new_key,value> (already an internal key)
- [[nodiscard]] rocksdb::Status Move(const std::string &key, const std::string
&new_key, bool nx, bool *ret,
- bool *key_exist);
+
+ // Copy <key,value> to <new_key,value> (already an internal key)
+ enum class CopyResult { KEY_NOT_EXIST, KEY_ALREADY_EXIST, DONE };
+ [[nodiscard]] rocksdb::Status Copy(const std::string &key, const std::string
&new_key, bool nx, bool delete_old,
+ CopyResult *res);
protected:
engine::Storage *storage_;
diff --git a/tests/gocase/unit/rename/rename_test.go
b/tests/gocase/unit/copy/copy_test.go
similarity index 68%
copy from tests/gocase/unit/rename/rename_test.go
copy to tests/gocase/unit/copy/copy_test.go
index 7bbd4a52..869c9d93 100644
--- a/tests/gocase/unit/rename/rename_test.go
+++ b/tests/gocase/unit/copy/copy_test.go
@@ -17,7 +17,7 @@
* under the License.
*/
-package rename
+package copycmd
import (
"context"
@@ -30,7 +30,7 @@ import (
"github.com/stretchr/testify/require"
)
-func TestRename_String(t *testing.T) {
+func TestCopyString(t *testing.T) {
srv := util.StartServer(t, map[string]string{})
defer srv.Close()
@@ -38,11 +38,11 @@ func TestRename_String(t *testing.T) {
rdb := srv.NewClient()
defer func() { require.NoError(t, rdb.Close()) }()
- t.Run("Rename string", func(t *testing.T) {
+ t.Run("Copy string replace", func(t *testing.T) {
require.NoError(t, rdb.Del(ctx, "a", "a1").Err())
require.NoError(t, rdb.Set(ctx, "a", "hello", 0).Err())
- require.NoError(t, rdb.Rename(ctx, "a", "a1").Err())
- require.EqualValues(t, "", rdb.Get(ctx, "a").Val())
+ require.NoError(t, rdb.Copy(ctx, "a", "a1", 0, true).Err())
+ require.EqualValues(t, "hello", rdb.Get(ctx, "a").Val())
require.EqualValues(t, "hello", rdb.Get(ctx, "a1").Val())
require.EqualValues(t, -1, rdb.TTL(ctx, "a1").Val())
@@ -50,8 +50,8 @@ func TestRename_String(t *testing.T) {
require.NoError(t, rdb.Del(ctx, "a", "a1").Err())
require.NoError(t, rdb.Set(ctx, "a", "hello", 0).Err())
require.NoError(t, rdb.Set(ctx, "a1", "world", 0).Err())
- require.NoError(t, rdb.Rename(ctx, "a", "a1").Err())
- require.EqualValues(t, "", rdb.Get(ctx, "a").Val())
+ require.NoError(t, rdb.Copy(ctx, "a", "a1", 0, true).Err())
+ require.EqualValues(t, "hello", rdb.Get(ctx, "a").Val())
require.EqualValues(t, "hello", rdb.Get(ctx, "a1").Val())
require.EqualValues(t, -1, rdb.TTL(ctx, "a1").Val())
@@ -59,8 +59,8 @@ func TestRename_String(t *testing.T) {
require.NoError(t, rdb.Del(ctx, "a", "a1").Err())
require.NoError(t, rdb.Set(ctx, "a", "hello",
10*time.Second).Err())
require.NoError(t, rdb.Set(ctx, "a1", "world",
1000*time.Second).Err())
- require.NoError(t, rdb.Rename(ctx, "a", "a1").Err())
- require.EqualValues(t, "", rdb.Get(ctx, "a").Val())
+ require.NoError(t, rdb.Copy(ctx, "a", "a1", 0, true).Err())
+ require.EqualValues(t, "hello", rdb.Get(ctx, "a").Val())
require.EqualValues(t, "hello", rdb.Get(ctx, "a1").Val())
util.BetweenValues(t, rdb.TTL(ctx, "a1").Val(), time.Second,
10*time.Second)
@@ -68,56 +68,56 @@ func TestRename_String(t *testing.T) {
require.NoError(t, rdb.Del(ctx, "a", "a1").Err())
require.NoError(t, rdb.Set(ctx, "a", "hello", 0).Err())
require.NoError(t, rdb.LPush(ctx, "a1", "world").Err())
- require.NoError(t, rdb.Rename(ctx, "a", "a1").Err())
- require.EqualValues(t, "", rdb.Get(ctx, "a").Val())
+ require.NoError(t, rdb.Copy(ctx, "a", "a1", 0, true).Err())
+ require.EqualValues(t, "hello", rdb.Get(ctx, "a").Val())
require.EqualValues(t, "hello", rdb.Get(ctx, "a1").Val())
require.EqualValues(t, -1, rdb.TTL(ctx, "a1").Val())
// key == newkey
require.NoError(t, rdb.Del(ctx, "a").Err())
require.NoError(t, rdb.Set(ctx, "a", "hello", 0).Err())
- require.NoError(t, rdb.Rename(ctx, "a", "a").Err())
+ require.NoError(t, rdb.Copy(ctx, "a", "a", 0, true).Err())
require.EqualValues(t, "hello", rdb.Get(ctx, "a").Val())
- // rename*3
+ // copy * 3
require.NoError(t, rdb.Del(ctx, "a", "a1", "a2", "a3").Err())
require.NoError(t, rdb.Set(ctx, "a", "hello", 0).Err())
require.NoError(t, rdb.Set(ctx, "a1", "world1", 0).Err())
require.NoError(t, rdb.Set(ctx, "a2", "world2", 0).Err())
require.NoError(t, rdb.Set(ctx, "a3", "world3", 0).Err())
- require.NoError(t, rdb.Rename(ctx, "a", "a1").Err())
- require.NoError(t, rdb.Rename(ctx, "a1", "a2").Err())
- require.NoError(t, rdb.Rename(ctx, "a2", "a3").Err())
- require.EqualValues(t, "", rdb.Get(ctx, "a").Val())
- require.EqualValues(t, "", rdb.Get(ctx, "a1").Val())
- require.EqualValues(t, "", rdb.Get(ctx, "a2").Val())
+ require.NoError(t, rdb.Copy(ctx, "a", "a1", 0, true).Err())
+ require.NoError(t, rdb.Copy(ctx, "a1", "a2", 0, true).Err())
+ require.NoError(t, rdb.Copy(ctx, "a2", "a3", 0, true).Err())
+ require.EqualValues(t, "hello", rdb.Get(ctx, "a").Val())
+ require.EqualValues(t, "hello", rdb.Get(ctx, "a1").Val())
+ require.EqualValues(t, "hello", rdb.Get(ctx, "a2").Val())
require.EqualValues(t, "hello", rdb.Get(ctx, "a3").Val())
})
- t.Run("RenameNX string", func(t *testing.T) {
+ t.Run("Copy string not replace", func(t *testing.T) {
require.NoError(t, rdb.Del(ctx, "a", "a1").Err())
require.NoError(t, rdb.Set(ctx, "a", "hello", 0).Err())
require.NoError(t, rdb.Set(ctx, "a1", "world", 0).Err())
- require.EqualValues(t, false, rdb.RenameNX(ctx, "a",
"a1").Val())
+ require.EqualValues(t, int64(0), rdb.Copy(ctx, "a", "a1", 0,
false).Val())
require.EqualValues(t, "hello", rdb.Get(ctx, "a").Val())
require.EqualValues(t, "world", rdb.Get(ctx, "a1").Val())
require.NoError(t, rdb.Del(ctx, "a", "a1").Err())
require.NoError(t, rdb.Set(ctx, "a", "hello", 0).Err())
- require.EqualValues(t, true, rdb.RenameNX(ctx, "a", "a1").Val())
- require.EqualValues(t, "", rdb.Get(ctx, "a").Val())
+ require.EqualValues(t, int64(1), rdb.Copy(ctx, "a", "a1", 0,
false).Val())
+ require.EqualValues(t, "hello", rdb.Get(ctx, "a").Val())
require.EqualValues(t, "hello", rdb.Get(ctx, "a1").Val())
// key == newkey
require.NoError(t, rdb.Del(ctx, "a", "a1").Err())
require.NoError(t, rdb.Set(ctx, "a", "hello", 0).Err())
- require.EqualValues(t, false, rdb.RenameNX(ctx, "a", "a").Val())
+ require.EqualValues(t, int64(0), rdb.Copy(ctx, "a", "a", 0,
false).Val())
require.EqualValues(t, "hello", rdb.Get(ctx, "a").Val())
})
}
-func TestRename_JSON(t *testing.T) {
+func TestCopyJSON(t *testing.T) {
srv := util.StartServer(t, map[string]string{})
defer srv.Close()
@@ -130,12 +130,12 @@ func TestRename_JSON(t *testing.T) {
jsonA := `{"x":1,"y":2}`
jsonB := `{"x":1}`
- t.Run("Rename json", func(t *testing.T) {
+ t.Run("Copy json replace", func(t *testing.T) {
require.NoError(t, rdb.Del(ctx, "a", "a1").Err())
require.NoError(t, rdb.Do(ctx, setCmd, "a", "$", jsonA).Err())
require.EqualValues(t, jsonA, rdb.Do(ctx, getCmd, "a").Val())
- require.NoError(t, rdb.Rename(ctx, "a", "a1").Err())
- require.EqualValues(t, nil, rdb.Do(ctx, getCmd, "a").Val())
+ require.NoError(t, rdb.Copy(ctx, "a", "a1", 0, true).Err())
+ require.EqualValues(t, jsonA, rdb.Do(ctx, getCmd, "a").Val())
require.EqualValues(t, jsonA, rdb.Do(ctx, getCmd, "a1").Val())
require.EqualValues(t, -1, rdb.TTL(ctx, "a1").Val())
@@ -143,8 +143,8 @@ func TestRename_JSON(t *testing.T) {
require.NoError(t, rdb.Del(ctx, "a", "a1").Err())
require.NoError(t, rdb.Do(ctx, setCmd, "a", "$", jsonA).Err())
require.NoError(t, rdb.Do(ctx, setCmd, "a1", "$", jsonB).Err())
- require.NoError(t, rdb.Rename(ctx, "a", "a1").Err())
- require.EqualValues(t, nil, rdb.Do(ctx, getCmd, "a").Val())
+ require.NoError(t, rdb.Copy(ctx, "a", "a1", 0, true).Err())
+ require.EqualValues(t, jsonA, rdb.Do(ctx, getCmd, "a").Val())
require.EqualValues(t, jsonA, rdb.Do(ctx, getCmd, "a1").Val())
require.EqualValues(t, -1, rdb.TTL(ctx, "a1").Val())
@@ -154,8 +154,8 @@ func TestRename_JSON(t *testing.T) {
require.NoError(t, rdb.Expire(ctx, "a", 10*time.Second).Err())
require.NoError(t, rdb.Do(ctx, setCmd, "a1", "$", jsonA).Err())
require.NoError(t, rdb.Expire(ctx, "a1",
1000*time.Second).Err())
- require.NoError(t, rdb.Rename(ctx, "a", "a1").Err())
- require.EqualValues(t, nil, rdb.Do(ctx, getCmd, "a").Val())
+ require.NoError(t, rdb.Copy(ctx, "a", "a1", 0, true).Err())
+ require.EqualValues(t, jsonA, rdb.Do(ctx, getCmd, "a").Val())
require.EqualValues(t, jsonA, rdb.Do(ctx, getCmd, "a1").Val())
util.BetweenValues(t, rdb.TTL(ctx, "a1").Val(), time.Second,
10*time.Second)
@@ -163,56 +163,56 @@ func TestRename_JSON(t *testing.T) {
require.NoError(t, rdb.Del(ctx, "a", "a1").Err())
require.NoError(t, rdb.Do(ctx, setCmd, "a", "$", jsonA).Err())
require.NoError(t, rdb.LPush(ctx, "a1", "world").Err())
- require.NoError(t, rdb.Rename(ctx, "a", "a1").Err())
- require.EqualValues(t, nil, rdb.Do(ctx, getCmd, "a").Val())
+ require.NoError(t, rdb.Copy(ctx, "a", "a1", 0, true).Err())
+ require.EqualValues(t, jsonA, rdb.Do(ctx, getCmd, "a").Val())
require.EqualValues(t, jsonA, rdb.Do(ctx, getCmd, "a1").Val())
require.EqualValues(t, -1, rdb.TTL(ctx, "a1").Val())
// key == newkey
require.NoError(t, rdb.Del(ctx, "a").Err())
require.NoError(t, rdb.Do(ctx, setCmd, "a", "$", jsonA).Err())
- require.NoError(t, rdb.Rename(ctx, "a", "a").Err())
+ require.NoError(t, rdb.Copy(ctx, "a", "a", 0, true).Err())
require.EqualValues(t, jsonA, rdb.Do(ctx, getCmd, "a").Val())
- // rename*3
+ // copy * 3
require.NoError(t, rdb.Del(ctx, "a", "a1", "a2", "a3").Err())
require.NoError(t, rdb.Do(ctx, setCmd, "a", "$", jsonA).Err())
require.NoError(t, rdb.Do(ctx, setCmd, "a1", "$", jsonB).Err())
require.NoError(t, rdb.Do(ctx, setCmd, "a2", "$", jsonB).Err())
require.NoError(t, rdb.Do(ctx, setCmd, "a3", "$", jsonB).Err())
- require.NoError(t, rdb.Rename(ctx, "a", "a1").Err())
- require.NoError(t, rdb.Rename(ctx, "a1", "a2").Err())
- require.NoError(t, rdb.Rename(ctx, "a2", "a3").Err())
- require.EqualValues(t, nil, rdb.Do(ctx, getCmd, "a").Val())
- require.EqualValues(t, nil, rdb.Do(ctx, getCmd, "a1").Val())
- require.EqualValues(t, nil, rdb.Do(ctx, getCmd, "a2").Val())
+ require.NoError(t, rdb.Copy(ctx, "a", "a1", 0, true).Err())
+ require.NoError(t, rdb.Copy(ctx, "a1", "a2", 0, true).Err())
+ require.NoError(t, rdb.Copy(ctx, "a2", "a3", 0, true).Err())
+ require.EqualValues(t, jsonA, rdb.Do(ctx, getCmd, "a").Val())
+ require.EqualValues(t, jsonA, rdb.Do(ctx, getCmd, "a1").Val())
+ require.EqualValues(t, jsonA, rdb.Do(ctx, getCmd, "a2").Val())
require.EqualValues(t, jsonA, rdb.Do(ctx, getCmd, "a3").Val())
})
- t.Run("RenameNX json", func(t *testing.T) {
+ t.Run("Copy json not replace", func(t *testing.T) {
require.NoError(t, rdb.Del(ctx, "a", "a1").Err())
require.NoError(t, rdb.Do(ctx, setCmd, "a", "$", jsonA).Err())
require.NoError(t, rdb.Do(ctx, setCmd, "a1", "$", jsonB).Err())
- require.EqualValues(t, false, rdb.RenameNX(ctx, "a",
"a1").Val())
+ require.EqualValues(t, int64(0), rdb.Copy(ctx, "a", "a1", 0,
false).Val())
require.EqualValues(t, jsonA, rdb.Do(ctx, getCmd, "a").Val())
require.EqualValues(t, jsonB, rdb.Do(ctx, getCmd, "a1").Val())
require.NoError(t, rdb.Del(ctx, "a", "a1").Err())
require.NoError(t, rdb.Do(ctx, setCmd, "a", "$", jsonA).Err())
- require.EqualValues(t, true, rdb.RenameNX(ctx, "a", "a1").Val())
- require.EqualValues(t, nil, rdb.Do(ctx, getCmd, "a").Val())
+ require.EqualValues(t, int64(1), rdb.Copy(ctx, "a", "a1", 0,
false).Val())
+ require.EqualValues(t, jsonA, rdb.Do(ctx, getCmd, "a").Val())
require.EqualValues(t, jsonA, rdb.Do(ctx, getCmd, "a1").Val())
// key == newkey
require.NoError(t, rdb.Del(ctx, "a", "a1").Err())
require.NoError(t, rdb.Do(ctx, setCmd, "a", "$", jsonA).Err())
- require.EqualValues(t, false, rdb.RenameNX(ctx, "a", "a").Val())
+ require.EqualValues(t, int64(0), rdb.Copy(ctx, "a", "a", 0,
false).Val())
require.EqualValues(t, jsonA, rdb.Do(ctx, getCmd, "a").Val())
})
}
-func TestRename_List(t *testing.T) {
+func TestCopyList(t *testing.T) {
srv := util.StartServer(t, map[string]string{})
defer srv.Close()
@@ -227,11 +227,11 @@ func TestRename_List(t *testing.T) {
}
}
- t.Run("Rename string", func(t *testing.T) {
+ t.Run("Copy string replace", func(t *testing.T) {
require.NoError(t, rdb.Del(ctx, "a", "a1").Err())
require.NoError(t, rdb.LPush(ctx, "a", "1", "2", "3").Err())
- require.NoError(t, rdb.Rename(ctx, "a", "a1").Err())
- require.EqualValues(t, "", rdb.Get(ctx, "a").Val())
+ require.NoError(t, rdb.Copy(ctx, "a", "a1", 0, true).Err())
+ require.EqualValues(t, 3, rdb.LLen(ctx, "a").Val())
require.EqualValues(t, 3, rdb.LLen(ctx, "a1").Val())
EqualListValues(t, "a1", []string{"3", "2", "1"})
require.EqualValues(t, -1, rdb.TTL(ctx, "a1").Val())
@@ -240,8 +240,8 @@ func TestRename_List(t *testing.T) {
require.NoError(t, rdb.Del(ctx, "a", "a1").Err())
require.NoError(t, rdb.LPush(ctx, "a", "1", "2", "3").Err())
require.NoError(t, rdb.LPush(ctx, "a1", "a").Err())
- require.NoError(t, rdb.Rename(ctx, "a", "a1").Err())
- require.EqualValues(t, "", rdb.Get(ctx, "a").Val())
+ require.NoError(t, rdb.Copy(ctx, "a", "a1", 0, true).Err())
+ EqualListValues(t, "a", []string{"3", "2", "1"})
EqualListValues(t, "a1", []string{"3", "2", "1"})
require.EqualValues(t, -1, rdb.TTL(ctx, "a1").Val())
@@ -251,8 +251,8 @@ func TestRename_List(t *testing.T) {
require.NoError(t, rdb.Expire(ctx, "a", 10*time.Second).Err())
require.NoError(t, rdb.LPush(ctx, "a1", "a").Err())
require.NoError(t, rdb.Expire(ctx, "a1",
1000*time.Second).Err())
- require.NoError(t, rdb.Rename(ctx, "a", "a1").Err())
- require.EqualValues(t, "", rdb.Get(ctx, "a").Val())
+ require.NoError(t, rdb.Copy(ctx, "a", "a1", 0, true).Err())
+ EqualListValues(t, "a", []string{"3", "2", "1"})
EqualListValues(t, "a1", []string{"3", "2", "1"})
util.BetweenValues(t, rdb.TTL(ctx, "a1").Val(), time.Second,
10*time.Second)
@@ -260,56 +260,56 @@ func TestRename_List(t *testing.T) {
require.NoError(t, rdb.Del(ctx, "a", "a1").Err())
require.NoError(t, rdb.LPush(ctx, "a", "1", "2", "3").Err())
require.NoError(t, rdb.Set(ctx, "a1", "world", 0).Err())
- require.NoError(t, rdb.Rename(ctx, "a", "a1").Err())
- require.EqualValues(t, "", rdb.Get(ctx, "a").Val())
+ require.NoError(t, rdb.Copy(ctx, "a", "a1", 0, true).Err())
+ EqualListValues(t, "a", []string{"3", "2", "1"})
EqualListValues(t, "a1", []string{"3", "2", "1"})
require.EqualValues(t, -1, rdb.TTL(ctx, "a1").Val())
// key == newkey
require.NoError(t, rdb.Del(ctx, "a").Err())
require.NoError(t, rdb.LPush(ctx, "a", "1", "2", "3").Err())
- require.NoError(t, rdb.Rename(ctx, "a", "a").Err())
+ require.NoError(t, rdb.Copy(ctx, "a", "a", 0, true).Err())
EqualListValues(t, "a1", []string{"3", "2", "1"})
- // rename*3
+ // coopy * 3
require.NoError(t, rdb.Del(ctx, "a", "a1", "a2", "a3").Err())
require.NoError(t, rdb.LPush(ctx, "a", "1", "2", "3").Err())
require.NoError(t, rdb.LPush(ctx, "a1", "2").Err())
require.NoError(t, rdb.LPush(ctx, "a2", "3").Err())
require.NoError(t, rdb.LPush(ctx, "a3", "1").Err())
- require.NoError(t, rdb.Rename(ctx, "a", "a1").Err())
- require.NoError(t, rdb.Rename(ctx, "a1", "a2").Err())
- require.NoError(t, rdb.Rename(ctx, "a2", "a3").Err())
- require.EqualValues(t, "", rdb.Get(ctx, "a").Val())
- require.EqualValues(t, "", rdb.Get(ctx, "a1").Val())
- require.EqualValues(t, "", rdb.Get(ctx, "a2").Val())
+ require.NoError(t, rdb.Copy(ctx, "a", "a1", 0, true).Err())
+ require.NoError(t, rdb.Copy(ctx, "a1", "a2", 0, true).Err())
+ require.NoError(t, rdb.Copy(ctx, "a2", "a3", 0, true).Err())
+ EqualListValues(t, "a", []string{"3", "2", "1"})
+ EqualListValues(t, "a1", []string{"3", "2", "1"})
+ EqualListValues(t, "a2", []string{"3", "2", "1"})
EqualListValues(t, "a3", []string{"3", "2", "1"})
})
- t.Run("RenameNX string", func(t *testing.T) {
+ t.Run("Copy string not replace", func(t *testing.T) {
require.NoError(t, rdb.Del(ctx, "a", "a1").Err())
require.NoError(t, rdb.LPush(ctx, "a", "1", "2", "3").Err())
require.NoError(t, rdb.LPush(ctx, "a1", "3").Err())
- require.EqualValues(t, false, rdb.RenameNX(ctx, "a",
"a1").Val())
+ require.EqualValues(t, int64(0), rdb.Copy(ctx, "a", "a1", 0,
false).Val())
EqualListValues(t, "a", []string{"3", "2", "1"})
EqualListValues(t, "a1", []string{"3"})
require.NoError(t, rdb.Del(ctx, "a", "a1").Err())
require.NoError(t, rdb.LPush(ctx, "a", "1", "2", "3").Err())
- require.EqualValues(t, true, rdb.RenameNX(ctx, "a", "a1").Val())
+ require.EqualValues(t, int64(1), rdb.Copy(ctx, "a", "a1", 0,
false).Val())
+ EqualListValues(t, "a", []string{"3", "2", "1"})
EqualListValues(t, "a1", []string{"3", "2", "1"})
- require.EqualValues(t, "", rdb.Get(ctx, "a").Val())
// key == newkey
require.NoError(t, rdb.Del(ctx, "a", "a1").Err())
require.NoError(t, rdb.LPush(ctx, "a", "1", "2", "3").Err())
- require.EqualValues(t, false, rdb.RenameNX(ctx, "a", "a").Val())
+ require.EqualValues(t, int64(0), rdb.Copy(ctx, "a", "a", 0,
false).Val())
EqualListValues(t, "a", []string{"3", "2", "1"})
})
}
-func TestRename_hash(t *testing.T) {
+func TestCopyHash(t *testing.T) {
srv := util.StartServer(t, map[string]string{})
defer srv.Close()
@@ -324,11 +324,15 @@ func TestRename_hash(t *testing.T) {
}
}
- t.Run("Rename hash", func(t *testing.T) {
+ t.Run("Copy hash replace", func(t *testing.T) {
require.NoError(t, rdb.Del(ctx, "a", "a1").Err())
require.NoError(t, rdb.HSet(ctx, "a", "a", "1", "b", "2", "c",
"3").Err())
- require.NoError(t, rdb.Rename(ctx, "a", "a1").Err())
- require.EqualValues(t, "", rdb.Get(ctx, "a").Val())
+ require.NoError(t, rdb.Copy(ctx, "a", "a1", 0, true).Err())
+ EqualListValues(t, "a", map[string]string{
+ "a": "1",
+ "b": "2",
+ "c": "3",
+ })
EqualListValues(t, "a1", map[string]string{
"a": "1",
"b": "2",
@@ -340,8 +344,12 @@ func TestRename_hash(t *testing.T) {
require.NoError(t, rdb.Del(ctx, "a", "a1").Err())
require.NoError(t, rdb.HSet(ctx, "a", "a", "1", "b", "2", "c",
"3").Err())
require.NoError(t, rdb.HSet(ctx, "a1", "a", "1").Err())
- require.NoError(t, rdb.Rename(ctx, "a", "a1").Err())
- require.EqualValues(t, "", rdb.Get(ctx, "a").Val())
+ require.NoError(t, rdb.Copy(ctx, "a", "a1", 0, true).Err())
+ EqualListValues(t, "a", map[string]string{
+ "a": "1",
+ "b": "2",
+ "c": "3",
+ })
EqualListValues(t, "a1", map[string]string{
"a": "1",
"b": "2",
@@ -355,8 +363,12 @@ func TestRename_hash(t *testing.T) {
require.NoError(t, rdb.Expire(ctx, "a", 10*time.Second).Err())
require.NoError(t, rdb.HSet(ctx, "a1", "a", "1").Err())
require.NoError(t, rdb.Expire(ctx, "a1",
1000*time.Second).Err())
- require.NoError(t, rdb.Rename(ctx, "a", "a1").Err())
- require.EqualValues(t, "", rdb.Get(ctx, "a").Val())
+ require.NoError(t, rdb.Copy(ctx, "a", "a1", 0, true).Err())
+ EqualListValues(t, "a", map[string]string{
+ "a": "1",
+ "b": "2",
+ "c": "3",
+ })
EqualListValues(t, "a1", map[string]string{
"a": "1",
"b": "2",
@@ -368,8 +380,12 @@ func TestRename_hash(t *testing.T) {
require.NoError(t, rdb.Del(ctx, "a", "a1").Err())
require.NoError(t, rdb.HSet(ctx, "a", "a", "1", "b", "2", "c",
"3").Err())
require.NoError(t, rdb.LPush(ctx, "a1", "a", "1").Err())
- require.NoError(t, rdb.Rename(ctx, "a", "a1").Err())
- require.EqualValues(t, "", rdb.Get(ctx, "a").Val())
+ require.NoError(t, rdb.Copy(ctx, "a", "a1", 0, true).Err())
+ EqualListValues(t, "a", map[string]string{
+ "a": "1",
+ "b": "2",
+ "c": "3",
+ })
EqualListValues(t, "a1", map[string]string{
"a": "1",
"b": "2",
@@ -380,25 +396,37 @@ func TestRename_hash(t *testing.T) {
// key == newkey
require.NoError(t, rdb.Del(ctx, "a").Err())
require.NoError(t, rdb.HSet(ctx, "a", "a", "1", "b", "2", "c",
"3").Err())
- require.NoError(t, rdb.Rename(ctx, "a", "a").Err())
+ require.NoError(t, rdb.Copy(ctx, "a", "a", 0, true).Err())
EqualListValues(t, "a1", map[string]string{
"a": "1",
"b": "2",
"c": "3",
})
- // rename*3
+ // copy * 3
require.NoError(t, rdb.Del(ctx, "a", "a1", "a2", "a3").Err())
require.NoError(t, rdb.HSet(ctx, "a", "a", "1", "b", "2", "c",
"3").Err())
require.NoError(t, rdb.HSet(ctx, "a1", "a", "1").Err())
require.NoError(t, rdb.HSet(ctx, "a2", "a", "1").Err())
require.NoError(t, rdb.HSet(ctx, "a3", "a", "1").Err())
- require.NoError(t, rdb.Rename(ctx, "a", "a1").Err())
- require.NoError(t, rdb.Rename(ctx, "a1", "a2").Err())
- require.NoError(t, rdb.Rename(ctx, "a2", "a3").Err())
- require.EqualValues(t, "", rdb.Get(ctx, "a").Val())
- require.EqualValues(t, "", rdb.Get(ctx, "a1").Val())
- require.EqualValues(t, "", rdb.Get(ctx, "a2").Val())
+ require.NoError(t, rdb.Copy(ctx, "a", "a1", 0, true).Err())
+ require.NoError(t, rdb.Copy(ctx, "a1", "a2", 0, true).Err())
+ require.NoError(t, rdb.Copy(ctx, "a2", "a3", 0, true).Err())
+ EqualListValues(t, "a", map[string]string{
+ "a": "1",
+ "b": "2",
+ "c": "3",
+ })
+ EqualListValues(t, "a1", map[string]string{
+ "a": "1",
+ "b": "2",
+ "c": "3",
+ })
+ EqualListValues(t, "a2", map[string]string{
+ "a": "1",
+ "b": "2",
+ "c": "3",
+ })
EqualListValues(t, "a3", map[string]string{
"a": "1",
"b": "2",
@@ -406,11 +434,11 @@ func TestRename_hash(t *testing.T) {
})
})
- t.Run("RenameNX hash", func(t *testing.T) {
+ t.Run("Copy hash not replace", func(t *testing.T) {
require.NoError(t, rdb.Del(ctx, "a", "a1").Err())
require.NoError(t, rdb.HSet(ctx, "a", "a", "1", "b", "2", "c",
"3").Err())
require.NoError(t, rdb.HSet(ctx, "a1", "a", "1").Err())
- require.EqualValues(t, false, rdb.RenameNX(ctx, "a",
"a1").Val())
+ require.EqualValues(t, int64(0), rdb.Copy(ctx, "a", "a1", 0,
false).Val())
EqualListValues(t, "a", map[string]string{
"a": "1",
"b": "2",
@@ -422,18 +450,22 @@ func TestRename_hash(t *testing.T) {
require.NoError(t, rdb.Del(ctx, "a", "a1").Err())
require.NoError(t, rdb.HSet(ctx, "a", "a", "1", "b", "2", "c",
"3").Err())
- require.EqualValues(t, true, rdb.RenameNX(ctx, "a", "a1").Val())
+ require.EqualValues(t, int64(1), rdb.Copy(ctx, "a", "a1", 0,
false).Val())
+ EqualListValues(t, "a", map[string]string{
+ "a": "1",
+ "b": "2",
+ "c": "3",
+ })
EqualListValues(t, "a1", map[string]string{
"a": "1",
"b": "2",
"c": "3",
})
- require.EqualValues(t, "", rdb.Get(ctx, "a").Val())
// key == newkey
require.NoError(t, rdb.Del(ctx, "a").Err())
require.NoError(t, rdb.HSet(ctx, "a", "a", "1", "b", "2", "c",
"3").Err())
- require.EqualValues(t, false, rdb.RenameNX(ctx, "a", "a").Val())
+ require.EqualValues(t, int64(0), rdb.Copy(ctx, "a", "a", 0,
false).Val())
EqualListValues(t, "a", map[string]string{
"a": "1",
"b": "2",
@@ -443,7 +475,7 @@ func TestRename_hash(t *testing.T) {
}
-func TestRename_set(t *testing.T) {
+func TestCopySet(t *testing.T) {
srv := util.StartServer(t, map[string]string{})
defer srv.Close()
@@ -458,11 +490,11 @@ func TestRename_set(t *testing.T) {
}
}
- t.Run("Rename set", func(t *testing.T) {
+ t.Run("Copy set replace", func(t *testing.T) {
require.NoError(t, rdb.Del(ctx, "a", "a1").Err())
require.NoError(t, rdb.SAdd(ctx, "a", "1", "2", "3").Err())
- require.NoError(t, rdb.Rename(ctx, "a", "a1").Err())
- require.EqualValues(t, "", rdb.Get(ctx, "a").Val())
+ require.NoError(t, rdb.Copy(ctx, "a", "a1", 0, true).Err())
+ EqualSetValues(t, "a", []string{"1", "2", "3"})
EqualSetValues(t, "a1", []string{"1", "2", "3"})
require.EqualValues(t, -1, rdb.TTL(ctx, "a1").Val())
@@ -470,8 +502,8 @@ func TestRename_set(t *testing.T) {
require.NoError(t, rdb.Del(ctx, "a", "a1").Err())
require.NoError(t, rdb.SAdd(ctx, "a", "1", "2", "3").Err())
require.NoError(t, rdb.SAdd(ctx, "a1", "a", "1").Err())
- require.NoError(t, rdb.Rename(ctx, "a", "a1").Err())
- require.EqualValues(t, "", rdb.Get(ctx, "a").Val())
+ require.NoError(t, rdb.Copy(ctx, "a", "a1", 0, true).Err())
+ EqualSetValues(t, "a", []string{"1", "2", "3"})
EqualSetValues(t, "a1", []string{"1", "2", "3"})
require.EqualValues(t, -1, rdb.TTL(ctx, "a1").Val())
@@ -481,8 +513,8 @@ func TestRename_set(t *testing.T) {
require.NoError(t, rdb.Expire(ctx, "a", 10*time.Second).Err())
require.NoError(t, rdb.SAdd(ctx, "a1", "1").Err())
require.NoError(t, rdb.Expire(ctx, "a1",
1000*time.Second).Err())
- require.NoError(t, rdb.Rename(ctx, "a", "a1").Err())
- require.EqualValues(t, "", rdb.Get(ctx, "a").Val())
+ require.NoError(t, rdb.Copy(ctx, "a", "a1", 0, true).Err())
+ EqualSetValues(t, "a", []string{"1", "2", "3"})
EqualSetValues(t, "a1", []string{"1", "2", "3"})
util.BetweenValues(t, rdb.TTL(ctx, "a1").Val(), time.Second,
10*time.Second)
@@ -490,57 +522,57 @@ func TestRename_set(t *testing.T) {
require.NoError(t, rdb.Del(ctx, "a", "a1").Err())
require.NoError(t, rdb.SAdd(ctx, "a", "1", "2", "3").Err())
require.NoError(t, rdb.LPush(ctx, "a1", "1").Err())
- require.NoError(t, rdb.Rename(ctx, "a", "a1").Err())
- require.EqualValues(t, "", rdb.Get(ctx, "a").Val())
+ require.NoError(t, rdb.Copy(ctx, "a", "a1", 0, true).Err())
+ EqualSetValues(t, "a", []string{"1", "2", "3"})
EqualSetValues(t, "a1", []string{"1", "2", "3"})
require.EqualValues(t, -1, rdb.TTL(ctx, "a1").Val())
// key == newkey
require.NoError(t, rdb.Del(ctx, "a").Err())
require.NoError(t, rdb.SAdd(ctx, "a", "1", "2", "3").Err())
- require.NoError(t, rdb.Rename(ctx, "a", "a").Err())
+ require.NoError(t, rdb.Copy(ctx, "a", "a", 0, true).Err())
EqualSetValues(t, "a1", []string{"1", "2", "3"})
- // rename*3
+ // copy * 3
require.NoError(t, rdb.Del(ctx, "a", "a1", "a2", "a3").Err())
require.NoError(t, rdb.SAdd(ctx, "a", "1", "2", "3").Err())
require.NoError(t, rdb.SAdd(ctx, "a1", "1").Err())
require.NoError(t, rdb.SAdd(ctx, "a2", "a2", "1").Err())
require.NoError(t, rdb.SAdd(ctx, "a3", "a3", "1").Err())
- require.NoError(t, rdb.Rename(ctx, "a", "a1").Err())
- require.NoError(t, rdb.Rename(ctx, "a1", "a2").Err())
- require.NoError(t, rdb.Rename(ctx, "a2", "a3").Err())
- require.EqualValues(t, "", rdb.Get(ctx, "a").Val())
- require.EqualValues(t, "", rdb.Get(ctx, "a1").Val())
- require.EqualValues(t, "", rdb.Get(ctx, "a2").Val())
+ require.NoError(t, rdb.Copy(ctx, "a", "a1", 0, true).Err())
+ require.NoError(t, rdb.Copy(ctx, "a1", "a2", 0, true).Err())
+ require.NoError(t, rdb.Copy(ctx, "a2", "a3", 0, true).Err())
+ EqualSetValues(t, "a", []string{"1", "2", "3"})
+ EqualSetValues(t, "a1", []string{"1", "2", "3"})
+ EqualSetValues(t, "a2", []string{"1", "2", "3"})
EqualSetValues(t, "a3", []string{"1", "2", "3"})
})
- t.Run("RenameNX set", func(t *testing.T) {
+ t.Run("Copy set not replace", func(t *testing.T) {
require.NoError(t, rdb.Del(ctx, "a", "a1").Err())
require.NoError(t, rdb.SAdd(ctx, "a", "1", "2", "3").Err())
require.NoError(t, rdb.SAdd(ctx, "a1", "1").Err())
- require.EqualValues(t, false, rdb.RenameNX(ctx, "a",
"a1").Val())
+ require.EqualValues(t, int64(0), rdb.Copy(ctx, "a", "a1", 0,
false).Val())
EqualSetValues(t, "a", []string{"1", "2", "3"})
EqualSetValues(t, "a1", []string{"1"})
require.NoError(t, rdb.Del(ctx, "a", "a1").Err())
require.NoError(t, rdb.SAdd(ctx, "a", "1", "2", "3").Err())
- require.EqualValues(t, true, rdb.RenameNX(ctx, "a", "a1").Val())
+ require.EqualValues(t, int64(1), rdb.Copy(ctx, "a", "a1", 0,
false).Val())
EqualSetValues(t, "a1", []string{"1", "2", "3"})
- require.EqualValues(t, "", rdb.Get(ctx, "a").Val())
+ EqualSetValues(t, "a", []string{"1", "2", "3"})
// key == newkey
require.NoError(t, rdb.Del(ctx, "a").Err())
require.NoError(t, rdb.SAdd(ctx, "a", "1", "2", "3").Err())
- require.EqualValues(t, false, rdb.RenameNX(ctx, "a", "a").Val())
+ require.EqualValues(t, int64(0), rdb.Copy(ctx, "a", "a", 0,
false).Val())
EqualSetValues(t, "a", []string{"1", "2", "3"})
})
}
-func TestRename_zset(t *testing.T) {
+func TestCopyZset(t *testing.T) {
srv := util.StartServer(t, map[string]string{})
defer srv.Close()
@@ -561,11 +593,15 @@ func TestRename_zset(t *testing.T) {
zMember := []redis.Z{{Member: "a", Score: 1}, {Member: "b", Score: 2},
{Member: "c", Score: 3}}
zMember2 := []redis.Z{{Member: "a", Score: 2}}
- t.Run("Rename zset", func(t *testing.T) {
+ t.Run("Copy zset", func(t *testing.T) {
require.NoError(t, rdb.Del(ctx, "a", "a1").Err())
require.NoError(t, rdb.ZAdd(ctx, "a", zMember...).Err())
- require.NoError(t, rdb.Rename(ctx, "a", "a1").Err())
- require.EqualValues(t, "", rdb.Get(ctx, "a").Val())
+ require.NoError(t, rdb.Copy(ctx, "a", "a1", 0, true).Err())
+ EqualZSetValues(t, "a", map[string]int{
+ "a": 1,
+ "b": 2,
+ "c": 3,
+ })
EqualZSetValues(t, "a1", map[string]int{
"a": 1,
"b": 2,
@@ -577,8 +613,12 @@ func TestRename_zset(t *testing.T) {
require.NoError(t, rdb.Del(ctx, "a", "a1").Err())
require.NoError(t, rdb.ZAdd(ctx, "a", zMember...).Err())
require.NoError(t, rdb.ZAdd(ctx, "a1", zMember2...).Err())
- require.NoError(t, rdb.Rename(ctx, "a", "a1").Err())
- require.EqualValues(t, "", rdb.Get(ctx, "a").Val())
+ require.NoError(t, rdb.Copy(ctx, "a", "a1", 0, true).Err())
+ EqualZSetValues(t, "a", map[string]int{
+ "a": 1,
+ "b": 2,
+ "c": 3,
+ })
EqualZSetValues(t, "a1", map[string]int{
"a": 1,
"b": 2,
@@ -592,8 +632,12 @@ func TestRename_zset(t *testing.T) {
require.NoError(t, rdb.Expire(ctx, "a", 10*time.Second).Err())
require.NoError(t, rdb.ZAdd(ctx, "a1", zMember2...).Err())
require.NoError(t, rdb.Expire(ctx, "a1",
1000*time.Second).Err())
- require.NoError(t, rdb.Rename(ctx, "a", "a1").Err())
- require.EqualValues(t, "", rdb.Get(ctx, "a").Val())
+ require.NoError(t, rdb.Copy(ctx, "a", "a1", 0, true).Err())
+ EqualZSetValues(t, "a", map[string]int{
+ "a": 1,
+ "b": 2,
+ "c": 3,
+ })
EqualZSetValues(t, "a1", map[string]int{
"a": 1,
"b": 2,
@@ -605,8 +649,12 @@ func TestRename_zset(t *testing.T) {
require.NoError(t, rdb.Del(ctx, "a", "a1").Err())
require.NoError(t, rdb.ZAdd(ctx, "a", zMember...).Err())
require.NoError(t, rdb.LPush(ctx, "a1", 1, 2, 3).Err())
- require.NoError(t, rdb.Rename(ctx, "a", "a1").Err())
- require.EqualValues(t, "", rdb.Get(ctx, "a").Val())
+ require.NoError(t, rdb.Copy(ctx, "a", "a1", 0, true).Err())
+ EqualZSetValues(t, "a", map[string]int{
+ "a": 1,
+ "b": 2,
+ "c": 3,
+ })
EqualZSetValues(t, "a1", map[string]int{
"a": 1,
"b": 2,
@@ -617,37 +665,48 @@ func TestRename_zset(t *testing.T) {
// key == newkey
require.NoError(t, rdb.Del(ctx, "a").Err())
require.NoError(t, rdb.ZAdd(ctx, "a", zMember...).Err())
- require.NoError(t, rdb.Rename(ctx, "a", "a").Err())
+ require.NoError(t, rdb.Copy(ctx, "a", "a", 0, true).Err())
EqualZSetValues(t, "a1", map[string]int{
"a": 1,
"b": 2,
"c": 3,
})
- // rename*3
+ // copy * 3
require.NoError(t, rdb.Del(ctx, "a", "a1", "a2", "a3").Err())
require.NoError(t, rdb.ZAdd(ctx, "a", zMember...).Err())
require.NoError(t, rdb.ZAdd(ctx, "a1", zMember2...).Err())
require.NoError(t, rdb.ZAdd(ctx, "a2", zMember2...).Err())
require.NoError(t, rdb.ZAdd(ctx, "a3", zMember2...).Err())
- require.NoError(t, rdb.Rename(ctx, "a", "a1").Err())
- require.NoError(t, rdb.Rename(ctx, "a1", "a2").Err())
- require.NoError(t, rdb.Rename(ctx, "a2", "a3").Err())
- require.EqualValues(t, "", rdb.Get(ctx, "a").Val())
- require.EqualValues(t, "", rdb.Get(ctx, "a1").Val())
- require.EqualValues(t, "", rdb.Get(ctx, "a2").Val())
+ require.NoError(t, rdb.Copy(ctx, "a", "a1", 0, true).Err())
+ require.NoError(t, rdb.Copy(ctx, "a1", "a2", 0, true).Err())
+ require.NoError(t, rdb.Copy(ctx, "a2", "a3", 0, true).Err())
+ EqualZSetValues(t, "a", map[string]int{
+ "a": 1,
+ "b": 2,
+ "c": 3,
+ })
+ EqualZSetValues(t, "a1", map[string]int{
+ "a": 1,
+ "b": 2,
+ "c": 3,
+ })
+ EqualZSetValues(t, "a2", map[string]int{
+ "a": 1,
+ "b": 2,
+ "c": 3,
+ })
EqualZSetValues(t, "a3", map[string]int{
"a": 1,
"b": 2,
"c": 3,
})
-
})
- t.Run("RenameNX zset", func(t *testing.T) {
+ t.Run("Copy zset not replace", func(t *testing.T) {
require.NoError(t, rdb.Del(ctx, "a", "a1").Err())
require.NoError(t, rdb.ZAdd(ctx, "a", zMember...).Err())
require.NoError(t, rdb.ZAdd(ctx, "a1", zMember2...).Err())
- require.EqualValues(t, false, rdb.RenameNX(ctx, "a",
"a1").Val())
+ require.EqualValues(t, int64(0), rdb.Copy(ctx, "a", "a1", 0,
false).Val())
EqualZSetValues(t, "a", map[string]int{
"a": 1,
"b": 2,
@@ -659,29 +718,32 @@ func TestRename_zset(t *testing.T) {
require.NoError(t, rdb.Del(ctx, "a", "a1").Err())
require.NoError(t, rdb.ZAdd(ctx, "a", zMember...).Err())
- require.EqualValues(t, true, rdb.RenameNX(ctx, "a", "a1").Val())
+ require.EqualValues(t, int64(1), rdb.Copy(ctx, "a", "a1", 0,
false).Val())
+ EqualZSetValues(t, "a", map[string]int{
+ "a": 1,
+ "b": 2,
+ "c": 3,
+ })
EqualZSetValues(t, "a1", map[string]int{
"a": 1,
"b": 2,
"c": 3,
})
- require.EqualValues(t, "", rdb.Get(ctx, "a").Val())
// key == newkey
require.NoError(t, rdb.Del(ctx, "a").Err())
require.NoError(t, rdb.ZAdd(ctx, "a", zMember...).Err())
- require.EqualValues(t, false, rdb.RenameNX(ctx, "a", "a").Val())
+ require.EqualValues(t, int64(0), rdb.Copy(ctx, "a", "a", 0,
false).Val())
EqualZSetValues(t, "a", map[string]int{
"a": 1,
"b": 2,
"c": 3,
})
-
})
}
-func TestRename_Bitmap(t *testing.T) {
+func TestCopyBitmap(t *testing.T) {
srv := util.StartServer(t, map[string]string{})
defer srv.Close()
@@ -703,11 +765,11 @@ func TestRename_Bitmap(t *testing.T) {
bitSetA := []int64{16, 1024 * 8 * 2, 1024 * 8 * 12}
bitSetB := []int64{1}
- t.Run("Rename Bitmap", func(t *testing.T) {
+ t.Run("Copy bitmap replace", func(t *testing.T) {
require.NoError(t, rdb.Del(ctx, "a", "a1").Err())
SetBits(t, "a", bitSetA)
- require.NoError(t, rdb.Rename(ctx, "a", "a1").Err())
- require.EqualValues(t, "", rdb.Get(ctx, "a").Val())
+ require.NoError(t, rdb.Copy(ctx, "a", "a1", 0, true).Err())
+ EqualBitSetValues(t, "a", bitSetA)
EqualBitSetValues(t, "a1", bitSetA)
require.EqualValues(t, -1, rdb.TTL(ctx, "a1").Val())
@@ -717,8 +779,8 @@ func TestRename_Bitmap(t *testing.T) {
SetBits(t, "a1", bitSetB)
require.NoError(t, rdb.Expire(ctx, "a", 10*time.Second).Err())
require.NoError(t, rdb.Expire(ctx, "a1",
1000*time.Second).Err())
- require.NoError(t, rdb.Rename(ctx, "a", "a1").Err())
- require.EqualValues(t, "", rdb.Get(ctx, "a").Val())
+ require.NoError(t, rdb.Copy(ctx, "a", "a1", 0, true).Err())
+ EqualBitSetValues(t, "a", bitSetA)
EqualBitSetValues(t, "a1", bitSetA)
util.BetweenValues(t, rdb.TTL(ctx, "a1").Val(), time.Second,
10*time.Second)
@@ -726,57 +788,56 @@ func TestRename_Bitmap(t *testing.T) {
require.NoError(t, rdb.Del(ctx, "a", "a1").Err())
SetBits(t, "a", bitSetA)
require.NoError(t, rdb.LPush(ctx, "a1", "a").Err())
- require.NoError(t, rdb.Rename(ctx, "a", "a1").Err())
- require.EqualValues(t, "", rdb.Get(ctx, "a").Val())
+ require.NoError(t, rdb.Copy(ctx, "a", "a1", 0, true).Err())
+ EqualBitSetValues(t, "a", bitSetA)
EqualBitSetValues(t, "a1", bitSetA)
require.EqualValues(t, -1, rdb.TTL(ctx, "a1").Val())
// key == newkey
require.NoError(t, rdb.Del(ctx, "a").Err())
SetBits(t, "a", bitSetA)
- require.NoError(t, rdb.Rename(ctx, "a", "a").Err())
+ require.NoError(t, rdb.Copy(ctx, "a", "a", 0, true).Err())
EqualBitSetValues(t, "a", bitSetA)
- // rename*3
+ // copy * 3
require.NoError(t, rdb.Del(ctx, "a", "a1", "a2", "a3").Err())
SetBits(t, "a", bitSetA)
SetBits(t, "a1", bitSetB)
SetBits(t, "a2", bitSetB)
SetBits(t, "a3", bitSetB)
- require.NoError(t, rdb.Rename(ctx, "a", "a1").Err())
- require.NoError(t, rdb.Rename(ctx, "a1", "a2").Err())
- require.NoError(t, rdb.Rename(ctx, "a2", "a3").Err())
- require.EqualValues(t, "", rdb.Get(ctx, "a").Val())
- require.EqualValues(t, "", rdb.Get(ctx, "a1").Val())
- require.EqualValues(t, "", rdb.Get(ctx, "a2").Val())
+ require.NoError(t, rdb.Copy(ctx, "a", "a1", 0, true).Err())
+ require.NoError(t, rdb.Copy(ctx, "a1", "a2", 0, true).Err())
+ require.NoError(t, rdb.Copy(ctx, "a2", "a3", 0, true).Err())
+ EqualBitSetValues(t, "a", bitSetA)
+ EqualBitSetValues(t, "a1", bitSetA)
+ EqualBitSetValues(t, "a2", bitSetA)
EqualBitSetValues(t, "a3", bitSetA)
})
- t.Run("RenameNX Bitmap", func(t *testing.T) {
+ t.Run("Copy bitmap not replace", func(t *testing.T) {
require.NoError(t, rdb.Del(ctx, "a", "a1").Err())
SetBits(t, "a", bitSetA)
SetBits(t, "a1", bitSetB)
- require.EqualValues(t, false, rdb.RenameNX(ctx, "a",
"a1").Val())
+ require.EqualValues(t, int64(0), rdb.Copy(ctx, "a", "a1", 0,
false).Val())
EqualBitSetValues(t, "a", bitSetA)
EqualBitSetValues(t, "a1", bitSetB)
require.NoError(t, rdb.Del(ctx, "a", "a1").Err())
SetBits(t, "a", bitSetA)
- require.EqualValues(t, true, rdb.RenameNX(ctx, "a", "a1").Val())
+ require.EqualValues(t, int64(1), rdb.Copy(ctx, "a", "a1", 0,
false).Val())
+ EqualBitSetValues(t, "a", bitSetA)
EqualBitSetValues(t, "a1", bitSetA)
- require.EqualValues(t, "", rdb.Get(ctx, "a").Val())
// key == newkey
require.NoError(t, rdb.Del(ctx, "a", "a1").Err())
SetBits(t, "a", bitSetA)
- require.EqualValues(t, false, rdb.RenameNX(ctx, "a", "a").Val())
+ require.EqualValues(t, int64(0), rdb.Copy(ctx, "a", "a", 0,
false).Val())
EqualBitSetValues(t, "a", bitSetA)
-
})
}
-func TestRename_SInt(t *testing.T) {
+func TestCopySint(t *testing.T) {
srv := util.StartServer(t, map[string]string{})
defer srv.Close()
@@ -791,11 +852,11 @@ func TestRename_SInt(t *testing.T) {
}
}
- t.Run("Rename SInt", func(t *testing.T) {
+ t.Run("Copy sint replace", func(t *testing.T) {
require.NoError(t, rdb.Del(ctx, "a", "a1").Err())
require.NoError(t, rdb.Do(ctx, "SIADD", "a", 3, 4, 5, 123,
245).Err())
- require.NoError(t, rdb.Rename(ctx, "a", "a1").Err())
- require.EqualValues(t, "", rdb.Get(ctx, "a").Val())
+ require.NoError(t, rdb.Copy(ctx, "a", "a1", 0, true).Err())
+ EqualSIntValues(t, "a", []int{3, 4, 5, 123, 245})
EqualSIntValues(t, "a1", []int{3, 4, 5, 123, 245})
require.EqualValues(t, -1, rdb.TTL(ctx, "a1").Val())
@@ -805,8 +866,8 @@ func TestRename_SInt(t *testing.T) {
require.NoError(t, rdb.Expire(ctx, "a", 10*time.Second).Err())
require.NoError(t, rdb.Do(ctx, "SIADD", "a1", 99).Err())
require.NoError(t, rdb.Expire(ctx, "a1",
1000*time.Second).Err())
- require.NoError(t, rdb.Rename(ctx, "a", "a1").Err())
- require.EqualValues(t, "", rdb.Get(ctx, "a").Val())
+ require.NoError(t, rdb.Copy(ctx, "a", "a1", 0, true).Err())
+ EqualSIntValues(t, "a", []int{3, 4, 5, 123, 245})
EqualSIntValues(t, "a1", []int{3, 4, 5, 123, 245})
util.BetweenValues(t, rdb.TTL(ctx, "a1").Val(), time.Second,
10*time.Second)
@@ -814,57 +875,57 @@ func TestRename_SInt(t *testing.T) {
require.NoError(t, rdb.Del(ctx, "a", "a1").Err())
require.NoError(t, rdb.Do(ctx, "SIADD", "a", 3, 4, 5, 123,
245).Err())
require.NoError(t, rdb.LPush(ctx, "a1", "a").Err())
- require.NoError(t, rdb.Rename(ctx, "a", "a1").Err())
- require.EqualValues(t, "", rdb.Get(ctx, "a").Val())
+ require.NoError(t, rdb.Copy(ctx, "a", "a1", 0, true).Err())
+ EqualSIntValues(t, "a", []int{3, 4, 5, 123, 245})
EqualSIntValues(t, "a1", []int{3, 4, 5, 123, 245})
require.EqualValues(t, -1, rdb.TTL(ctx, "a1").Val())
// key == newkey
require.NoError(t, rdb.Del(ctx, "a").Err())
require.NoError(t, rdb.Do(ctx, "SIADD", "a", 3, 4, 5, 123,
245).Err())
- require.NoError(t, rdb.Rename(ctx, "a", "a").Err())
+ require.NoError(t, rdb.Copy(ctx, "a", "a", 0, true).Err())
EqualSIntValues(t, "a1", []int{3, 4, 5, 123, 245})
- // rename*3
+ // copy * 3
require.NoError(t, rdb.Del(ctx, "a", "a1", "a2", "a3").Err())
require.NoError(t, rdb.Do(ctx, "SIADD", "a", 3, 4, 5, 123,
245).Err())
require.NoError(t, rdb.Do(ctx, "SIADD", "a1", 85).Err())
require.NoError(t, rdb.Do(ctx, "SIADD", "a2", 77, 0).Err())
require.NoError(t, rdb.Do(ctx, "SIADD", "a3", 111, 222,
333).Err())
- require.NoError(t, rdb.Rename(ctx, "a", "a1").Err())
- require.NoError(t, rdb.Rename(ctx, "a1", "a2").Err())
- require.NoError(t, rdb.Rename(ctx, "a2", "a3").Err())
- require.EqualValues(t, "", rdb.Get(ctx, "a").Val())
- require.EqualValues(t, "", rdb.Get(ctx, "a1").Val())
- require.EqualValues(t, "", rdb.Get(ctx, "a2").Val())
+ require.NoError(t, rdb.Copy(ctx, "a", "a1", 0, true).Err())
+ require.NoError(t, rdb.Copy(ctx, "a1", "a2", 0, true).Err())
+ require.NoError(t, rdb.Copy(ctx, "a2", "a3", 0, true).Err())
+ EqualSIntValues(t, "a", []int{3, 4, 5, 123, 245})
+ EqualSIntValues(t, "a1", []int{3, 4, 5, 123, 245})
+ EqualSIntValues(t, "a2", []int{3, 4, 5, 123, 245})
EqualSIntValues(t, "a3", []int{3, 4, 5, 123, 245})
})
- t.Run("RenameNX SInt", func(t *testing.T) {
+ t.Run("Copy sint not replace", func(t *testing.T) {
require.NoError(t, rdb.Del(ctx, "a", "a1").Err())
require.NoError(t, rdb.Do(ctx, "SIADD", "a", 3, 4, 5, 123,
245).Err())
require.NoError(t, rdb.Do(ctx, "SIADD", "a1", 99).Err())
- require.EqualValues(t, false, rdb.RenameNX(ctx, "a",
"a1").Val())
+ require.EqualValues(t, int64(0), rdb.Copy(ctx, "a", "a1", 0,
false).Val())
EqualSIntValues(t, "a", []int{3, 4, 5, 123, 245})
EqualSIntValues(t, "a1", []int{99})
require.NoError(t, rdb.Del(ctx, "a", "a1").Err())
require.NoError(t, rdb.Do(ctx, "SIADD", "a", 3, 4, 5, 123,
245).Err())
- require.EqualValues(t, true, rdb.RenameNX(ctx, "a", "a1").Val())
+ require.EqualValues(t, int64(1), rdb.Copy(ctx, "a", "a1", 0,
false).Val())
+ EqualSIntValues(t, "a", []int{3, 4, 5, 123, 245})
EqualSIntValues(t, "a1", []int{3, 4, 5, 123, 245})
- require.EqualValues(t, "", rdb.Get(ctx, "a").Val())
// key == newkey
require.NoError(t, rdb.Del(ctx, "a", "a1").Err())
require.NoError(t, rdb.Do(ctx, "SIADD", "a", 3, 4, 5, 123,
245).Err())
- require.EqualValues(t, false, rdb.RenameNX(ctx, "a", "a").Val())
+ require.EqualValues(t, int64(0), rdb.Copy(ctx, "a", "a", 0,
false).Val())
EqualSIntValues(t, "a", []int{3, 4, 5, 123, 245})
})
}
-func TestRename_Bloom(t *testing.T) {
+func TestCopyBloom(t *testing.T) {
srv := util.StartServer(t, map[string]string{})
defer srv.Close()
@@ -875,11 +936,11 @@ func TestRename_Bloom(t *testing.T) {
bfAdd := "BF.ADD"
bfExists := "BF.EXISTS"
- t.Run("Rename Bloom", func(t *testing.T) {
+ t.Run("Copy bloom replace", func(t *testing.T) {
require.NoError(t, rdb.Del(ctx, "a", "a1").Err())
require.NoError(t, rdb.Do(ctx, bfAdd, "a", "hello").Err())
- require.NoError(t, rdb.Rename(ctx, "a", "a1").Err())
- require.EqualValues(t, "", rdb.Get(ctx, "a").Val())
+ require.NoError(t, rdb.Copy(ctx, "a", "a1", 0, true).Err())
+ require.EqualValues(t, 1, rdb.Do(ctx, bfExists, "a",
"hello").Val())
require.EqualValues(t, 1, rdb.Do(ctx, bfExists, "a1",
"hello").Val())
require.EqualValues(t, -1, rdb.TTL(ctx, "a1").Val())
@@ -889,8 +950,8 @@ func TestRename_Bloom(t *testing.T) {
require.NoError(t, rdb.Expire(ctx, "a", 10*time.Second).Err())
require.NoError(t, rdb.Do(ctx, bfAdd, "a1", "world").Err())
require.NoError(t, rdb.Expire(ctx, "a1",
1000*time.Second).Err())
- require.NoError(t, rdb.Rename(ctx, "a", "a1").Err())
- require.EqualValues(t, "", rdb.Get(ctx, "a").Val())
+ require.NoError(t, rdb.Copy(ctx, "a", "a1", 0, true).Err())
+ require.EqualValues(t, 1, rdb.Do(ctx, bfExists, "a",
"hello").Val())
require.EqualValues(t, 1, rdb.Do(ctx, bfExists, "a1",
"hello").Val())
require.EqualValues(t, 0, rdb.Do(ctx, bfExists, "a1",
"world").Val())
util.BetweenValues(t, rdb.TTL(ctx, "a1").Val(), time.Second,
10*time.Second)
@@ -899,55 +960,56 @@ func TestRename_Bloom(t *testing.T) {
require.NoError(t, rdb.Del(ctx, "a", "a1").Err())
require.NoError(t, rdb.Do(ctx, bfAdd, "a", "hello").Err())
require.NoError(t, rdb.LPush(ctx, "a1", "a").Err())
- require.NoError(t, rdb.Rename(ctx, "a", "a1").Err())
- require.EqualValues(t, "", rdb.Get(ctx, "a").Val())
+ require.NoError(t, rdb.Copy(ctx, "a", "a1", 0, true).Err())
+ require.EqualValues(t, 1, rdb.Do(ctx, bfExists, "a",
"hello").Val())
require.EqualValues(t, 1, rdb.Do(ctx, bfExists, "a1",
"hello").Val())
require.EqualValues(t, -1, rdb.TTL(ctx, "a1").Val())
// key == newkey
require.NoError(t, rdb.Del(ctx, "a").Err())
require.NoError(t, rdb.Do(ctx, bfAdd, "a", "hello").Err())
- require.NoError(t, rdb.Rename(ctx, "a", "a").Err())
+ require.NoError(t, rdb.Copy(ctx, "a", "a", 0, true).Err())
require.EqualValues(t, 1, rdb.Do(ctx, bfExists, "a",
"hello").Val())
- // rename*3
+ // copy * 3
require.NoError(t, rdb.Del(ctx, "a", "a1", "a2", "a3").Err())
require.NoError(t, rdb.Do(ctx, bfAdd, "a", "hello").Err())
require.NoError(t, rdb.Do(ctx, bfAdd, "a1", "world1").Err())
require.NoError(t, rdb.Do(ctx, bfAdd, "a2", "world2").Err())
require.NoError(t, rdb.Do(ctx, bfAdd, "a3", "world3").Err())
- require.NoError(t, rdb.Rename(ctx, "a", "a1").Err())
- require.NoError(t, rdb.Rename(ctx, "a1", "a2").Err())
- require.NoError(t, rdb.Rename(ctx, "a2", "a3").Err())
- require.EqualValues(t, "", rdb.Get(ctx, "a").Val())
- require.EqualValues(t, "", rdb.Get(ctx, "a1").Val())
- require.EqualValues(t, "", rdb.Get(ctx, "a2").Val())
+ require.NoError(t, rdb.Copy(ctx, "a", "a1", 0, true).Err())
+ require.NoError(t, rdb.Copy(ctx, "a1", "a2", 0, true).Err())
+ require.NoError(t, rdb.Copy(ctx, "a2", "a3", 0, true).Err())
+ require.EqualValues(t, 1, rdb.Do(ctx, bfExists, "a",
"hello").Val())
+ require.EqualValues(t, 1, rdb.Do(ctx, bfExists, "a1",
"hello").Val())
+ require.EqualValues(t, 1, rdb.Do(ctx, bfExists, "a2",
"hello").Val())
require.EqualValues(t, 1, rdb.Do(ctx, bfExists, "a3",
"hello").Val())
})
- t.Run("RenameNX Bloom", func(t *testing.T) {
+ t.Run("Copy bloom not replace", func(t *testing.T) {
require.NoError(t, rdb.Del(ctx, "a", "a1").Err())
require.NoError(t, rdb.Do(ctx, bfAdd, "a", "hello").Err())
require.NoError(t, rdb.Do(ctx, bfAdd, "a1", "world").Err())
- require.EqualValues(t, false, rdb.RenameNX(ctx, "a",
"a1").Val())
+ require.EqualValues(t, int64(0), rdb.Copy(ctx, "a", "a1", 0,
false).Val())
require.EqualValues(t, 1, rdb.Do(ctx, bfExists, "a",
"hello").Val())
require.EqualValues(t, 1, rdb.Do(ctx, bfExists, "a1",
"world").Val())
require.NoError(t, rdb.Del(ctx, "a", "a1").Err())
require.NoError(t, rdb.Do(ctx, bfAdd, "a", "hello").Err())
- require.EqualValues(t, true, rdb.RenameNX(ctx, "a", "a1").Val())
+ require.EqualValues(t, int64(1), rdb.Copy(ctx, "a", "a1", 0,
false).Val())
+ require.EqualValues(t, 1, rdb.Do(ctx, bfExists, "a",
"hello").Val())
require.EqualValues(t, 1, rdb.Do(ctx, bfExists, "a1",
"hello").Val())
- require.EqualValues(t, "", rdb.Get(ctx, "a").Val())
// key == newkey
require.NoError(t, rdb.Del(ctx, "a", "a1").Err())
require.NoError(t, rdb.Do(ctx, bfAdd, "a", "hello").Err())
- require.EqualValues(t, false, rdb.RenameNX(ctx, "a", "a").Val())
+ require.EqualValues(t, int64(0), rdb.Copy(ctx, "a", "a", 0,
false).Val())
require.EqualValues(t, 1, rdb.Do(ctx, bfExists, "a",
"hello").Val())
})
+
}
-func TestRename_Stream(t *testing.T) {
+func TestCopyStream(t *testing.T) {
srv := util.StartServer(t, map[string]string{})
defer srv.Close()
@@ -957,11 +1019,11 @@ func TestRename_Stream(t *testing.T) {
XADD := "XADD"
XREAD := "XREAD"
- t.Run("Rename Stream", func(t *testing.T) {
+ t.Run("Copy stream replace", func(t *testing.T) {
require.NoError(t, rdb.Del(ctx, "a", "a1").Err())
require.NoError(t, rdb.Do(ctx, XADD, "a", "*", "a",
"hello").Err())
- require.NoError(t, rdb.Rename(ctx, "a", "a1").Err())
- require.EqualValues(t, "", rdb.Get(ctx, "a").Val())
+ require.NoError(t, rdb.Copy(ctx, "a", "a1", 0, true).Err())
+ require.Contains(t, rdb.Do(ctx, XREAD, "STREAMS", "a",
"0").String(), "hello")
require.Contains(t, rdb.Do(ctx, XREAD, "STREAMS", "a1",
"0").String(), "hello")
require.EqualValues(t, -1, rdb.TTL(ctx, "a1").Val())
@@ -971,8 +1033,8 @@ func TestRename_Stream(t *testing.T) {
require.NoError(t, rdb.Expire(ctx, "a", 10*time.Second).Err())
require.NoError(t, rdb.Do(ctx, XADD, "a1", "*", "a",
"world").Err())
require.NoError(t, rdb.Expire(ctx, "a1",
1000*time.Second).Err())
- require.NoError(t, rdb.Rename(ctx, "a", "a1").Err())
- require.EqualValues(t, "", rdb.Get(ctx, "a").Val())
+ require.NoError(t, rdb.Copy(ctx, "a", "a1", 0, true).Err())
+ require.Contains(t, rdb.Do(ctx, XREAD, "STREAMS", "a",
"0").String(), "hello")
require.Contains(t, rdb.Do(ctx, XREAD, "STREAMS", "a1",
"0").String(), "hello")
util.BetweenValues(t, rdb.TTL(ctx, "a1").Val(), time.Second,
10*time.Second)
@@ -980,55 +1042,56 @@ func TestRename_Stream(t *testing.T) {
require.NoError(t, rdb.Del(ctx, "a", "a1").Err())
require.NoError(t, rdb.Do(ctx, XADD, "a", "*", "a",
"hello").Err())
require.NoError(t, rdb.LPush(ctx, "a1", "a").Err())
- require.NoError(t, rdb.Rename(ctx, "a", "a1").Err())
- require.EqualValues(t, "", rdb.Get(ctx, "a").Val())
+ require.NoError(t, rdb.Copy(ctx, "a", "a1", 0, true).Err())
+ require.Contains(t, rdb.Do(ctx, XREAD, "STREAMS", "a",
"0").String(), "hello")
require.Contains(t, rdb.Do(ctx, XREAD, "STREAMS", "a1",
"0").String(), "hello")
require.EqualValues(t, -1, rdb.TTL(ctx, "a1").Val())
// key == newkey
require.NoError(t, rdb.Del(ctx, "a").Err())
require.NoError(t, rdb.Do(ctx, XADD, "a", "*", "a",
"hello").Err())
- require.NoError(t, rdb.Rename(ctx, "a", "a").Err())
+ require.NoError(t, rdb.Copy(ctx, "a", "a", 0, true).Err())
require.Contains(t, rdb.Do(ctx, XREAD, "STREAMS", "a",
"0").String(), "hello")
- // rename*3
+ // copy * 3
require.NoError(t, rdb.Del(ctx, "a", "a1", "a2", "a3").Err())
require.NoError(t, rdb.Do(ctx, XADD, "a", "*", "a",
"hello").Err())
require.NoError(t, rdb.Do(ctx, XADD, "a1", "*", "a",
"world1").Err())
require.NoError(t, rdb.Do(ctx, XADD, "a2", "*", "a",
"world2").Err())
require.NoError(t, rdb.Do(ctx, XADD, "a3", "*", "a",
"world3").Err())
- require.NoError(t, rdb.Rename(ctx, "a", "a1").Err())
- require.NoError(t, rdb.Rename(ctx, "a1", "a2").Err())
- require.NoError(t, rdb.Rename(ctx, "a2", "a3").Err())
- require.EqualValues(t, "", rdb.Get(ctx, "a").Val())
- require.EqualValues(t, "", rdb.Get(ctx, "a1").Val())
- require.EqualValues(t, "", rdb.Get(ctx, "a2").Val())
+ require.NoError(t, rdb.Copy(ctx, "a", "a1", 0, true).Err())
+ require.NoError(t, rdb.Copy(ctx, "a1", "a2", 0, true).Err())
+ require.NoError(t, rdb.Copy(ctx, "a2", "a3", 0, true).Err())
+ require.Contains(t, rdb.Do(ctx, XREAD, "STREAMS", "a",
"0").String(), "hello")
+ require.Contains(t, rdb.Do(ctx, XREAD, "STREAMS", "a1",
"0").String(), "hello")
+ require.Contains(t, rdb.Do(ctx, XREAD, "STREAMS", "a2",
"0").String(), "hello")
require.Contains(t, rdb.Do(ctx, XREAD, "STREAMS", "a3",
"0").String(), "hello")
})
- t.Run("RenameNX Stream", func(t *testing.T) {
+ t.Run("Copy stream not replace", func(t *testing.T) {
require.NoError(t, rdb.Del(ctx, "a", "a1").Err())
require.NoError(t, rdb.Do(ctx, XADD, "a", "*", "a",
"hello").Err())
require.NoError(t, rdb.Do(ctx, XADD, "a1", "*", "a",
"world").Err())
- require.EqualValues(t, false, rdb.RenameNX(ctx, "a",
"a1").Val())
+ require.EqualValues(t, int64(0), rdb.Copy(ctx, "a", "a1", 0,
false).Val())
require.Contains(t, rdb.Do(ctx, XREAD, "STREAMS", "a",
"0").String(), "hello")
require.Contains(t, rdb.Do(ctx, XREAD, "STREAMS", "a1",
"0").String(), "world")
require.NoError(t, rdb.Del(ctx, "a", "a1").Err())
require.NoError(t, rdb.Do(ctx, XADD, "a", "*", "a",
"hello").Err())
- require.EqualValues(t, true, rdb.RenameNX(ctx, "a", "a1").Val())
+ require.EqualValues(t, int64(1), rdb.Copy(ctx, "a", "a1", 0,
false).Val())
+ require.Contains(t, rdb.Do(ctx, XREAD, "STREAMS", "a",
"0").String(), "hello")
require.Contains(t, rdb.Do(ctx, XREAD, "STREAMS", "a1",
"0").String(), "hello")
- require.EqualValues(t, "", rdb.Get(ctx, "a").Val())
// key == newkey
require.NoError(t, rdb.Del(ctx, "a", "a1").Err())
require.NoError(t, rdb.Do(ctx, XADD, "a", "*", "a",
"hello").Err())
- require.EqualValues(t, false, rdb.RenameNX(ctx, "a", "a").Val())
+ require.EqualValues(t, int64(0), rdb.Copy(ctx, "a", "a", 0,
false).Val())
require.Contains(t, rdb.Do(ctx, XREAD, "STREAMS", "a",
"0").String(), "hello")
})
+
}
-func TestRename_Error(t *testing.T) {
+func TestCopyError(t *testing.T) {
srv := util.StartServer(t, map[string]string{})
defer srv.Close()
@@ -1036,9 +1099,17 @@ func TestRename_Error(t *testing.T) {
rdb := srv.NewClient()
defer func() { require.NoError(t, rdb.Close()) }()
- t.Run("Rename from empty key", func(t *testing.T) {
- require.Error(t, rdb.Rename(ctx, ".empty", "a").Err())
- require.Error(t, rdb.RenameNX(ctx, ".empty", "a").Err())
+ t.Run("Copy to not db 0", func(t *testing.T) {
+ require.NoError(t, rdb.Del(ctx, "a").Err())
+ require.NoError(t, rdb.Set(ctx, "a", "hello", 0).Err())
+ require.Error(t, rdb.Copy(ctx, "", "a", 1, true).Err())
+ require.Error(t, rdb.Copy(ctx, "", "a", 3, false).Err())
+ })
+
+ t.Run("Copy from empty key", func(t *testing.T) {
+ require.NoError(t, rdb.Del(ctx, ".empty", "a").Err())
+ require.EqualValues(t, int64(0), rdb.Copy(ctx, ".empty", "a",
0, false).Val())
+ require.EqualValues(t, int64(0), rdb.Copy(ctx, ".empty", "a",
0, true).Val())
})
}
diff --git a/tests/gocase/unit/rename/rename_test.go
b/tests/gocase/unit/rename/rename_test.go
index 7bbd4a52..7cc0248c 100644
--- a/tests/gocase/unit/rename/rename_test.go
+++ b/tests/gocase/unit/rename/rename_test.go
@@ -30,7 +30,7 @@ import (
"github.com/stretchr/testify/require"
)
-func TestRename_String(t *testing.T) {
+func TestRenameString(t *testing.T) {
srv := util.StartServer(t, map[string]string{})
defer srv.Close()
@@ -117,7 +117,7 @@ func TestRename_String(t *testing.T) {
}
-func TestRename_JSON(t *testing.T) {
+func TestRenameJSON(t *testing.T) {
srv := util.StartServer(t, map[string]string{})
defer srv.Close()
@@ -212,7 +212,7 @@ func TestRename_JSON(t *testing.T) {
}
-func TestRename_List(t *testing.T) {
+func TestRenameList(t *testing.T) {
srv := util.StartServer(t, map[string]string{})
defer srv.Close()
@@ -309,7 +309,7 @@ func TestRename_List(t *testing.T) {
}
-func TestRename_hash(t *testing.T) {
+func TestRenameHash(t *testing.T) {
srv := util.StartServer(t, map[string]string{})
defer srv.Close()
@@ -443,7 +443,7 @@ func TestRename_hash(t *testing.T) {
}
-func TestRename_set(t *testing.T) {
+func TestRenameSet(t *testing.T) {
srv := util.StartServer(t, map[string]string{})
defer srv.Close()
@@ -540,7 +540,7 @@ func TestRename_set(t *testing.T) {
}
-func TestRename_zset(t *testing.T) {
+func TestRenameZset(t *testing.T) {
srv := util.StartServer(t, map[string]string{})
defer srv.Close()
@@ -681,7 +681,7 @@ func TestRename_zset(t *testing.T) {
}
-func TestRename_Bitmap(t *testing.T) {
+func TestRenameBitmap(t *testing.T) {
srv := util.StartServer(t, map[string]string{})
defer srv.Close()
@@ -776,7 +776,7 @@ func TestRename_Bitmap(t *testing.T) {
}
-func TestRename_SInt(t *testing.T) {
+func TestRenameSint(t *testing.T) {
srv := util.StartServer(t, map[string]string{})
defer srv.Close()
@@ -864,7 +864,7 @@ func TestRename_SInt(t *testing.T) {
}
-func TestRename_Bloom(t *testing.T) {
+func TestRenameBloom(t *testing.T) {
srv := util.StartServer(t, map[string]string{})
defer srv.Close()
@@ -947,7 +947,7 @@ func TestRename_Bloom(t *testing.T) {
})
}
-func TestRename_Stream(t *testing.T) {
+func TestRenameStream(t *testing.T) {
srv := util.StartServer(t, map[string]string{})
defer srv.Close()
@@ -1028,7 +1028,7 @@ func TestRename_Stream(t *testing.T) {
})
}
-func TestRename_Error(t *testing.T) {
+func TestRenameError(t *testing.T) {
srv := util.StartServer(t, map[string]string{})
defer srv.Close()