Skip to content

Commit 53658c4

Browse files
authored
IDLETIME and FREQ support for RESTORE (#1580)
1 parent cf39732 commit 53658c4

File tree

2 files changed

+65
-1
lines changed

2 files changed

+65
-1
lines changed

redis/commands.py

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1034,7 +1034,8 @@ def renamenx(self, src, dst):
10341034
"Rename key ``src`` to ``dst`` if ``dst`` doesn't already exist"
10351035
return self.execute_command('RENAMENX', src, dst)
10361036

1037-
def restore(self, name, ttl, value, replace=False, absttl=False):
1037+
def restore(self, name, ttl, value, replace=False, absttl=False,
1038+
idletime=None, frequency=None):
10381039
"""
10391040
Create a key using the provided serialized value, previously obtained
10401041
using DUMP.
@@ -1045,12 +1046,32 @@ def restore(self, name, ttl, value, replace=False, absttl=False):
10451046
``absttl`` if True, specified ``ttl`` should represent an absolute Unix
10461047
timestamp in milliseconds in which the key will expire. (Redis 5.0 or
10471048
greater).
1049+
1050+
``idletime`` Used for eviction, this is the number of seconds the
1051+
key must be idle, prior to execution.
1052+
1053+
``frequency`` Used for eviction, this is the frequency counter of
1054+
the object stored at the key, prior to execution.
10481055
"""
10491056
params = [name, ttl, value]
10501057
if replace:
10511058
params.append('REPLACE')
10521059
if absttl:
10531060
params.append('ABSTTL')
1061+
if idletime is not None:
1062+
params.append('IDLETIME')
1063+
try:
1064+
params.append(int(idletime))
1065+
except ValueError:
1066+
raise DataError("idletimemust be an integer")
1067+
1068+
if frequency is not None:
1069+
params.append('FREQ')
1070+
try:
1071+
params.append(int(frequency))
1072+
except ValueError:
1073+
raise DataError("frequency must be an integer")
1074+
10541075
return self.execute_command('RESTORE', *params)
10551076

10561077
def set(self, name, value,
@@ -3084,6 +3105,7 @@ def _geosearchgeneric(self, command, *args, **kwargs):
30843105
def module_load(self, path, *args):
30853106
"""
30863107
Loads the module from ``path``.
3108+
Passes all ``*args`` to the module, during loading.
30873109
Raises ``ModuleError`` if a module is not found at ``path``.
30883110
"""
30893111
pieces = list(args)

tests/test_commands.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3471,6 +3471,48 @@ def test_module(self, r):
34713471
r.module_load('/some/fake/path', 'arg1', 'arg2', 'arg3', 'arg4')
34723472
assert "Error loading the extension." in str(excinfo.value)
34733473

3474+
@skip_if_server_version_lt('2.6.0')
3475+
def test_restore(self, r):
3476+
3477+
# standard restore
3478+
key = 'foo'
3479+
r.set(key, 'bar')
3480+
dumpdata = r.dump(key)
3481+
r.delete(key)
3482+
assert r.restore(key, 0, dumpdata)
3483+
assert r.get(key) == b'bar'
3484+
3485+
# overwrite restore
3486+
with pytest.raises(redis.exceptions.ResponseError):
3487+
assert r.restore(key, 0, dumpdata)
3488+
r.set(key, 'a new value!')
3489+
assert r.restore(key, 0, dumpdata, replace=True)
3490+
assert r.get(key) == b'bar'
3491+
3492+
# ttl check
3493+
key2 = 'another'
3494+
r.set(key2, 'blee!')
3495+
dumpdata = r.dump(key2)
3496+
r.delete(key2)
3497+
assert r.restore(key2, 0, dumpdata)
3498+
assert r.ttl(key2) == -1
3499+
3500+
# idletime
3501+
key = 'yayakey'
3502+
r.set(key, 'blee!')
3503+
dumpdata = r.dump(key)
3504+
r.delete(key)
3505+
assert r.restore(key, 0, dumpdata, idletime=5)
3506+
assert r.get(key) == b'blee!'
3507+
3508+
# frequency
3509+
key = 'yayakey'
3510+
r.set(key, 'blee!')
3511+
dumpdata = r.dump(key)
3512+
r.delete(key)
3513+
assert r.restore(key, 0, dumpdata, frequency=5)
3514+
assert r.get(key) == b'blee!'
3515+
34743516

34753517
class TestBinarySave:
34763518

0 commit comments

Comments
 (0)