Skip to content

Commit 3326b4f

Browse files
aaron-congocyip10
authored andcommitted
Python: add ZRANGESTORE command (valkey-io#1377)
* Python: add ZRANGESTORE command (#258) * Update with PR link
1 parent 2bc8b2d commit 3326b4f

File tree

6 files changed

+372
-0
lines changed

6 files changed

+372
-0
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
* Python: Added ZMSCORE command ([#1357](https://github.com/aws/glide-for-redis/pull/1357))
2121
* Python: Added HRANDFIELD command ([#1334](https://github.com/aws/glide-for-redis/pull/1334))
2222
* Python: Added XADD, XTRIM commands ([#1320](https://github.com/aws/glide-for-redis/pull/1320))
23+
* Python: Added ZRANGESTORE command ([#1377](https://github.com/aws/glide-for-redis/pull/1377))
2324

2425
#### Fixes
2526
* Python: Fix typing error "‘type’ object is not subscriptable" ([#1203](https://github.com/aws/glide-for-redis/pull/1203))

python/python/glide/async_commands/core.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
RangeByScore,
2525
ScoreBoundary,
2626
_create_zrange_args,
27+
_create_zrangestore_args,
2728
)
2829
from glide.constants import TOK, TResult
2930
from glide.protobuf.redis_request_pb2 import RequestType
@@ -2338,6 +2339,46 @@ async def zrange_withscores(
23382339
Mapping[str, float], await self._execute_command(RequestType.Zrange, args)
23392340
)
23402341

2342+
async def zrangestore(
2343+
self,
2344+
destination: str,
2345+
source: str,
2346+
range_query: Union[RangeByIndex, RangeByLex, RangeByScore],
2347+
reverse: bool = False,
2348+
) -> int:
2349+
"""
2350+
Stores a specified range of elements from the sorted set at `source`, into a new sorted set at `destination`. If
2351+
`destination` doesn't exist, a new sorted set is created; if it exists, it's overwritten.
2352+
2353+
When in Cluster mode, all keys must map to the same hash slot.
2354+
2355+
ZRANGESTORE can perform different types of range queries: by index (rank), by the score, or by lexicographical
2356+
order.
2357+
2358+
See https://valkey.io/commands/zrangestore for more details.
2359+
2360+
Args:
2361+
destination (str): The key for the destination sorted set.
2362+
source (str): The key of the source sorted set.
2363+
range_query (Union[RangeByIndex, RangeByLex, RangeByScore]): The range query object representing the type of range query to perform.
2364+
- For range queries by index (rank), use RangeByIndex.
2365+
- For range queries by lexicographical order, use RangeByLex.
2366+
- For range queries by score, use RangeByScore.
2367+
reverse (bool): If True, reverses the sorted set, with index 0 as the element with the highest score.
2368+
2369+
Returns:
2370+
int: The number of elements in the resulting sorted set.
2371+
2372+
Examples:
2373+
>>> await client.zrangestore("destination_key", "my_sorted_set", RangeByIndex(0, 2), True)
2374+
3 # The 3 members with the highest scores from "my_sorted_set" were stored in the sorted set at "destination_key".
2375+
>>> await client.zrangestore("destination_key", "my_sorted_set", RangeByScore(InfBound.NEG_INF, ScoreBoundary(3)))
2376+
2 # The 2 members with scores between negative infinity and 3 (inclusive) from "my_sorted_set" were stored in the sorted set at "destination_key".
2377+
"""
2378+
args = _create_zrangestore_args(destination, source, range_query, reverse)
2379+
2380+
return cast(int, await self._execute_command(RequestType.ZRangeStore, args))
2381+
23412382
async def zrank(
23422383
self,
23432384
key: str,

python/python/glide/async_commands/sorted_set.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,3 +158,29 @@ def _create_zrange_args(
158158
args.append("WITHSCORES")
159159

160160
return args
161+
162+
163+
def _create_zrangestore_args(
164+
destination: str,
165+
source: str,
166+
range_query: Union[RangeByLex, RangeByScore, RangeByIndex],
167+
reverse: bool,
168+
) -> List[str]:
169+
args = [destination, source, str(range_query.start), str(range_query.stop)]
170+
171+
if isinstance(range_query, RangeByScore):
172+
args.append("BYSCORE")
173+
elif isinstance(range_query, RangeByLex):
174+
args.append("BYLEX")
175+
if reverse:
176+
args.append("REV")
177+
if hasattr(range_query, "limit") and range_query.limit is not None:
178+
args.extend(
179+
[
180+
"LIMIT",
181+
str(range_query.limit.offset),
182+
str(range_query.limit.count),
183+
]
184+
)
185+
186+
return args

python/python/glide/async_commands/transaction.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
RangeByScore,
2424
ScoreBoundary,
2525
_create_zrange_args,
26+
_create_zrangestore_args,
2627
)
2728
from glide.protobuf.redis_request_pb2 import RequestType
2829

@@ -1664,6 +1665,38 @@ def zrange_withscores(
16641665

16651666
return self.append_command(RequestType.Zrange, args)
16661667

1668+
def zrangestore(
1669+
self: TTransaction,
1670+
destination: str,
1671+
source: str,
1672+
range_query: Union[RangeByIndex, RangeByLex, RangeByScore],
1673+
reverse: bool = False,
1674+
) -> TTransaction:
1675+
"""
1676+
Stores a specified range of elements from the sorted set at `source`, into a new sorted set at `destination`. If
1677+
`destination` doesn't exist, a new sorted set is created; if it exists, it's overwritten.
1678+
1679+
ZRANGESTORE can perform different types of range queries: by index (rank), by the score, or by lexicographical
1680+
order.
1681+
1682+
See https://valkey.io/commands/zrangestore for more details.
1683+
1684+
Args:
1685+
destination (str): The key for the destination sorted set.
1686+
source (str): The key of the source sorted set.
1687+
range_query (Union[RangeByIndex, RangeByLex, RangeByScore]): The range query object representing the type of range query to perform.
1688+
- For range queries by index (rank), use RangeByIndex.
1689+
- For range queries by lexicographical order, use RangeByLex.
1690+
- For range queries by score, use RangeByScore.
1691+
reverse (bool): If True, reverses the sorted set, with index 0 as the element with the highest score.
1692+
1693+
Command response:
1694+
int: The number of elements in the resulting sorted set.
1695+
"""
1696+
args = _create_zrangestore_args(destination, source, range_query, reverse)
1697+
1698+
return self.append_command(RequestType.ZRangeStore, args)
1699+
16671700
def zrank(
16681701
self: TTransaction,
16691702
key: str,

0 commit comments

Comments
 (0)