From b3ee3e2685207e75cc9b4466287f572d5ab3d3f3 Mon Sep 17 00:00:00 2001 From: Saurav Sharma Date: Sun, 25 Feb 2024 17:44:05 +0530 Subject: [PATCH 1/3] Add option flags nx, xx, gt, lt for expire and pexpire --- changelog.d/730.feature | 1 + django_redis/client/default.py | 12 ++++++++++-- tests/test_backend.py | 12 ++++++++++++ 3 files changed, 23 insertions(+), 2 deletions(-) create mode 100644 changelog.d/730.feature diff --git a/changelog.d/730.feature b/changelog.d/730.feature new file mode 100644 index 00000000..b4ddcf9c --- /dev/null +++ b/changelog.d/730.feature @@ -0,0 +1 @@ +Add option flags nx, xx, gt, lt for expire and pexpire \ No newline at end of file diff --git a/django_redis/client/default.py b/django_redis/client/default.py index b9a5c1b0..a6622f5f 100644 --- a/django_redis/client/default.py +++ b/django_redis/client/default.py @@ -298,6 +298,10 @@ def expire( timeout: ExpiryT, version: Optional[int] = None, client: Optional[Redis] = None, + nx: bool = False, + xx: bool = False, + gt: bool = False, + lt: bool = False, ) -> bool: if timeout is DEFAULT_TIMEOUT: timeout = self._backend.default_timeout # type: ignore @@ -309,7 +313,7 @@ def expire( # for some strange reason mypy complains, # saying that timeout type is float | timedelta - return client.expire(key, timeout) # type: ignore + return client.expire(key, timeout, nx, xx, gt, lt) # type: ignore def pexpire( self, @@ -317,6 +321,10 @@ def pexpire( timeout: ExpiryT, version: Optional[int] = None, client: Optional[Redis] = None, + nx: bool = False, + xx: bool = False, + gt: bool = False, + lt: bool = False, ) -> bool: if timeout is DEFAULT_TIMEOUT: timeout = self._backend.default_timeout # type: ignore @@ -330,7 +338,7 @@ def pexpire( # is fixed. # for some strange reason mypy complains, # saying that timeout type is float | timedelta - return bool(client.pexpire(key, timeout)) # type: ignore + return bool(client.pexpire(key, timeout, nx, xx, gt, lt)) # type: ignore def pexpire_at( self, diff --git a/tests/test_backend.py b/tests/test_backend.py index 4ff60983..0041e8c8 100644 --- a/tests/test_backend.py +++ b/tests/test_backend.py @@ -606,6 +606,12 @@ def test_expire(self, cache: RedisCache): ttl = cache.ttl("foo") assert pytest.approx(ttl) == 20 assert cache.expire("not-existent-key", 20) is False + cache.set("key1", "value1", timeout=None) + assert cache.expire("key1", 20, nx=True) is True + cache.set("key2", "value2", timeout=20) + assert cache.expire("key2", 21, xx=True) is True + assert cache.expire("key2", 30, gt=True) is True + assert cache.expire("key2", 20, lt=True) is True def test_expire_with_default_timeout(self, cache: RedisCache): cache.set("foo", "bar", timeout=None) @@ -619,6 +625,12 @@ def test_pexpire(self, cache: RedisCache): # delta is set to 10 as precision error causes tests to fail assert pytest.approx(ttl, 10) == 20500 assert cache.pexpire("not-existent-key", 20500) is False + cache.set("key1", "value1", timeout=None) + assert cache.pexpire("key1", 20000, nx=True) is True + cache.set("key2", "value2", timeout=20000) + assert cache.expire("key2", 20500, xx=True) is True + assert cache.expire("key2", 30000, gt=True) is True + assert cache.expire("key2", 20000, lt=True) is True def test_pexpire_with_default_timeout(self, cache: RedisCache): cache.set("foo", "bar", timeout=None) From 965c95148bab69ffe8c81209b5952f02d54c3bb4 Mon Sep 17 00:00:00 2001 From: Saurav Sharma Date: Sun, 25 Feb 2024 19:00:11 +0530 Subject: [PATCH 2/3] ShardClient modified for expire and pexpire --- django_redis/client/sharded.py | 46 +++++++++++++++++++++++++++++++--- 1 file changed, 42 insertions(+), 4 deletions(-) diff --git a/django_redis/client/sharded.py b/django_redis/client/sharded.py index dbb1d200..74ce471c 100644 --- a/django_redis/client/sharded.py +++ b/django_redis/client/sharded.py @@ -169,19 +169,57 @@ def persist(self, key, version=None, client=None): return super().persist(key=key, version=version, client=client) - def expire(self, key, timeout, version=None, client=None): + def expire( + self, + key, + timeout, + version=None, + client=None, + nx=False, + xx=False, + gt=False, + lt=False, + ): if client is None: key = self.make_key(key, version=version) client = self.get_server(key) - return super().expire(key=key, timeout=timeout, version=version, client=client) + return super().expire( + key=key, + timeout=timeout, + version=version, + client=client, + nx=nx, + xx=xx, + gt=gt, + lt=lt, + ) - def pexpire(self, key, timeout, version=None, client=None): + def pexpire( + self, + key, + timeout, + version=None, + client=None, + nx=False, + xx=False, + gt=False, + lt=False, + ): if client is None: key = self.make_key(key, version=version) client = self.get_server(key) - return super().pexpire(key=key, timeout=timeout, version=version, client=client) + return super().pexpire( + key=key, + timeout=timeout, + version=version, + client=client, + nx=nx, + xx=xx, + gt=gt, + lt=lt, + ) def pexpire_at(self, key, when: Union[datetime, int], version=None, client=None): """ From c0cc303e5e63f99018a7b7acec3d3454137799e3 Mon Sep 17 00:00:00 2001 From: Saurav Sharma Date: Thu, 4 Jul 2024 23:35:33 +0530 Subject: [PATCH 3/3] Add chnagelog --- changelog.d/731.feature | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/731.feature diff --git a/changelog.d/731.feature b/changelog.d/731.feature new file mode 100644 index 00000000..b4ddcf9c --- /dev/null +++ b/changelog.d/731.feature @@ -0,0 +1 @@ +Add option flags nx, xx, gt, lt for expire and pexpire \ No newline at end of file