Skip to content

Commit 9ce7bb2

Browse files
authored
Add support for COPY command new in Redis 6.2 (#1492)
1 parent cb97b9b commit 9ce7bb2

File tree

2 files changed

+42
-1
lines changed

2 files changed

+42
-1
lines changed

redis/client.py

+19-1
Original file line numberDiff line numberDiff line change
@@ -561,7 +561,7 @@ class Redis:
561561
"""
562562
RESPONSE_CALLBACKS = {
563563
**string_keys_to_dict(
564-
'AUTH EXPIRE EXPIREAT HEXISTS HMSET MOVE MSETNX PERSIST '
564+
'AUTH COPY EXPIRE EXPIREAT HEXISTS HMSET MOVE MSETNX PERSIST '
565565
'PSETEX RENAMENX SISMEMBER SMOVE SETEX SETNX',
566566
bool
567567
),
@@ -1612,6 +1612,24 @@ def bitpos(self, key, bit, start=None, end=None):
16121612
"when end is specified")
16131613
return self.execute_command('BITPOS', *params)
16141614

1615+
def copy(self, source, destination, destination_db=None, replace=False):
1616+
"""
1617+
Copy the value stored in the ``source`` key to the ``destination`` key.
1618+
1619+
``destination_db`` an alternative destination database. By default,
1620+
the ``destination`` key is created in the source Redis database.
1621+
1622+
``replace`` whether the ``destination`` key should be removed before
1623+
copying the value to it. By default, the value is not copied if
1624+
the ``destination`` key already exists.
1625+
"""
1626+
params = [source, destination]
1627+
if destination_db is not None:
1628+
params.extend(["DB", destination_db])
1629+
if replace:
1630+
params.append("REPLACE")
1631+
return self.execute_command('COPY', *params)
1632+
16151633
def decr(self, name, amount=1):
16161634
"""
16171635
Decrements the value of ``key`` by ``amount``. If no key exists,

tests/test_commands.py

+23
Original file line numberDiff line numberDiff line change
@@ -578,6 +578,29 @@ def test_bitpos_wrong_arguments(self, r):
578578
with pytest.raises(exceptions.RedisError):
579579
r.bitpos(key, 7) == 12
580580

581+
@skip_if_server_version_lt('6.2.0')
582+
def test_copy(self, r):
583+
assert r.copy("a", "b") == 0
584+
r.set("a", "foo")
585+
assert r.copy("a", "b") == 1
586+
assert r.get("a") == b"foo"
587+
assert r.get("b") == b"foo"
588+
589+
@skip_if_server_version_lt('6.2.0')
590+
def test_copy_and_replace(self, r):
591+
r.set("a", "foo1")
592+
r.set("b", "foo2")
593+
assert r.copy("a", "b") == 0
594+
assert r.copy("a", "b", replace=True) == 1
595+
596+
@skip_if_server_version_lt('6.2.0')
597+
def test_copy_to_another_database(self, request):
598+
r0 = _get_client(redis.Redis, request, db=0)
599+
r1 = _get_client(redis.Redis, request, db=1)
600+
r0.set("a", "foo")
601+
assert r0.copy("a", "b", destination_db=1) == 1
602+
assert r1.get("b") == b"foo"
603+
581604
def test_decr(self, r):
582605
assert r.decr('a') == -1
583606
assert r['a'] == b'-1'

0 commit comments

Comments
 (0)