Skip to content

Commit d65e8d2

Browse files
author
Joshua
committed
Add hsetex and tests
Signed-off-by: Joshua <joshua.gehlen@fkie.fraunhofer.de>
1 parent c291080 commit d65e8d2

File tree

2 files changed

+79
-0
lines changed

2 files changed

+79
-0
lines changed

tests/test_commands.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3236,6 +3236,27 @@ def test_hstrlen(self, r):
32363236
assert r.hstrlen("a", "1") == 2
32373237
assert r.hstrlen("a", "2") == 3
32383238

3239+
@skip_if_server_version_lt("9.0.0")
3240+
def test_hsetex(self, r):
3241+
assert r.hsetex("a", "field1", "value1", ex=5) == 1
3242+
assert r.hget("a", "field1") == b"value1"
3243+
assert r.hsetex("a", "field1", "value2", ex=5) == 1
3244+
assert r.hget("a", "field1") == b"value2"
3245+
3246+
@skip_if_server_version_lt("9.0.0")
3247+
def test_hsetex_px(self, r):
3248+
assert r.hsetex("a", "field1", "value1", px=5000) == 1
3249+
assert r.hget("a", "field1") == b"value1"
3250+
assert r.hsetex("a", "field1", "value2", px=5000) == 1
3251+
assert r.hget("a", "field1") == b"value2"
3252+
3253+
@skip_if_server_version_lt("9.0.0")
3254+
def test_hsetex_mapping(self, r):
3255+
mapping = {"field1": "value1", "field2": "value2"}
3256+
assert r.hsetex("a", mapping=mapping, ex=5) == 1
3257+
assert r.hget("a", "field1") == b"value1"
3258+
assert r.hget("a", "field2") == b"value2"
3259+
32393260
# SORT
32403261
def test_sort_basic(self, r):
32413262
r.rpush("a", "3", "2", "1", "4")

valkey/commands/core.py

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5055,6 +5055,64 @@ def hsetnx(self, name: str, key: str, value: str) -> Union[Awaitable[bool], bool
50555055
"""
50565056
return self.execute_command("HSETNX", name, key, value)
50575057

5058+
def hsetex(
5059+
self,
5060+
name: str,
5061+
key: Optional[str] = None,
5062+
value: Optional[str] = None,
5063+
mapping: Optional[dict] = None,
5064+
items: Optional[list] = None,
5065+
ex: Union[ExpiryT, None] = None,
5066+
px: Union[ExpiryT, None] = None,
5067+
exat: Union[AbsExpiryT, None] = None,
5068+
pxat: Union[AbsExpiryT, None] = None,
5069+
nx: bool = False,
5070+
xx: bool = False,
5071+
fnx: bool = False,
5072+
fxx: bool = False,
5073+
) -> Union[Awaitable[bool], bool]:
5074+
"""
5075+
Set key to value within hash ``name``,
5076+
``mapping`` accepts a dict of key/value pairs to be added to hash ``name``.
5077+
``items`` accepts a list of key/value pairs to be added to hash ``name``.
5078+
Set expiration options for the hash fields.
5079+
"""
5080+
5081+
if key is None and not mapping and not items:
5082+
raise DataError("'hsetex' with no key value pairs")
5083+
pieces = []
5084+
if ex is not None:
5085+
pieces.extend(["EX", ex])
5086+
if px is not None:
5087+
pieces.extend(["PX", px])
5088+
if exat is not None:
5089+
pieces.extend(["EXAT", exat])
5090+
if pxat is not None:
5091+
pieces.extend(["PXAT", pxat])
5092+
if nx:
5093+
pieces.append("NX")
5094+
if xx:
5095+
pieces.append("XX")
5096+
if fnx:
5097+
pieces.append("FNX")
5098+
if fxx:
5099+
pieces.append("FXX")
5100+
pieces.append("FIELDS")
5101+
if key is not None and value is not None:
5102+
pieces.append(1) # for one field
5103+
pieces.append(key)
5104+
pieces.append(value)
5105+
if mapping:
5106+
pieces.append(len(mapping))
5107+
for key, value in mapping.items():
5108+
pieces.append(key)
5109+
pieces.append(value)
5110+
if items:
5111+
pieces.append(len(items) // 2)
5112+
pieces.extend(items)
5113+
5114+
return self.execute_command("HSETEX", name, *pieces)
5115+
50585116
def hmset(self, name: str, mapping: dict) -> Union[Awaitable[str], str]:
50595117
"""
50605118
Set key to value within hash ``name`` for each corresponding

0 commit comments

Comments
 (0)