Skip to content

Commit c60a567

Browse files
author
Adan
committed
Added zcount command in node.
1 parent 7ff2e8e commit c60a567

File tree

6 files changed

+150
-3
lines changed

6 files changed

+150
-3
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
* Python, Node: When recieving LPOP/RPOP with count, convert result to Array. ([#811](https://github.com/aws/glide-for-redis/pull/811))
1212
* Python: Added TYPE command ([#945](https://github.com/aws/glide-for-redis/pull/945))
1313
* Python: Added HLEN command ([#944](https://github.com/aws/glide-for-redis/pull/944))
14+
* Node: Added ZCOUNT command ([#909](https://github.com/aws/glide-for-redis/pull/909))
1415

1516
#### Features
1617
* Python, Node: Added support in Lua Scripts ([#775](https://github.com/aws/glide-for-redis/pull/775), [#860](https://github.com/aws/glide-for-redis/pull/860))

node/src/BaseClient.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import * as net from "net";
1212
import { Buffer, BufferWriter, Reader, Writer } from "protobufjs";
1313
import {
1414
ExpireOptions,
15+
ScoreLimit,
1516
SetOptions,
1617
ZaddOptions,
1718
createDecr,
@@ -53,6 +54,7 @@ import {
5354
createUnlink,
5455
createZadd,
5556
createZcard,
57+
createZcount,
5658
createZrem,
5759
createZscore,
5860
} from "./Commands";
@@ -1077,6 +1079,25 @@ export class BaseClient {
10771079
return this.createWritePromise(createZscore(key, member));
10781080
}
10791081

1082+
/** Returns the number of members in the sorted set stored at `key` with scores between `minScore` and `maxScore`.
1083+
* See https://redis.io/commands/zcount/ for more details.
1084+
*
1085+
* @param key - The key of the sorted set.
1086+
* @param minScore - The minimum score to count from. Can be positive/negative infinity, or specific score and inclusivity.
1087+
* @param maxScore - The maximum score to count up to. Can be positive/negative infinity, or specific score and inclusivity.
1088+
* @returns The number of members in the specified score range.
1089+
* If `key` does not exist, it is treated as an empty sorted set, and the command returns 0.
1090+
* If `minScore` is greater than `maxScore`, 0 is returned.
1091+
* If `key` holds a value that is not a sorted set, an error is returned.
1092+
*/
1093+
public zcount(
1094+
key: string,
1095+
minScore: ScoreLimit,
1096+
maxScore: ScoreLimit
1097+
): Promise<number> {
1098+
return this.createWritePromise(createZcount(key, minScore, maxScore));
1099+
}
1100+
10801101
private readonly MAP_READ_FROM_STRATEGY: Record<
10811102
ReadFrom,
10821103
connection_request.ReadFrom

node/src/Commands.ts

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -767,3 +767,52 @@ export function createZcard(key: string): redis_request.Command {
767767
export function createZscore(key: string, member: string): redis_request.Command {
768768
return createCommand(RequestType.ZScore, [key, member]);
769769
}
770+
771+
export type ScoreLimit =
772+
| `positiveInfinity`
773+
| `negativeInfinity`
774+
| {
775+
bound: number;
776+
isInclusive?: boolean;
777+
};
778+
779+
const positiveInfinityArg = "+inf";
780+
const negativeInfinityArg = "-inf";
781+
const isInclusiveArg = "(";
782+
783+
/**
784+
* @internal
785+
*/
786+
export function createZcount(
787+
key: string,
788+
minScore: ScoreLimit,
789+
maxScore: ScoreLimit
790+
): redis_request.Command {
791+
const args = [key];
792+
793+
if (minScore == "positiveInfinity") {
794+
args.push(positiveInfinityArg);
795+
} else if (minScore == "negativeInfinity") {
796+
args.push(negativeInfinityArg);
797+
} else {
798+
const value =
799+
minScore.isInclusive == false
800+
? isInclusiveArg + minScore.bound.toString()
801+
: minScore.bound.toString();
802+
args.push(value);
803+
}
804+
805+
if (maxScore == "positiveInfinity") {
806+
args.push(positiveInfinityArg);
807+
} else if (maxScore == "negativeInfinity") {
808+
args.push(negativeInfinityArg);
809+
} else {
810+
const value =
811+
maxScore.isInclusive == false
812+
? isInclusiveArg + maxScore.bound.toString()
813+
: maxScore.bound.toString();
814+
args.push(value);
815+
}
816+
817+
return createCommand(RequestType.Zcount, args);
818+
}

node/src/Transaction.ts

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import {
66
ExpireOptions,
77
InfoOptions,
8+
ScoreLimit,
89
SetOptions,
910
ZaddOptions,
1011
createClientGetName,
@@ -56,6 +57,7 @@ import {
5657
createUnlink,
5758
createZadd,
5859
createZcard,
60+
createZcount,
5961
createZrem,
6062
createZscore,
6163
} from "./Commands";
@@ -833,8 +835,24 @@ export class BaseTransaction<T extends BaseTransaction<T>> {
833835
* If `key` does not exist, null is returned.
834836
* If `key` holds a value that is not a sorted set, an error is returned.
835837
*/
836-
public zscore(key: string, member: string) {
837-
this.commands.push(createZscore(key, member));
838+
public zscore(key: string, member: string): T {
839+
return this.addAndReturn(createZscore(key, member));
840+
}
841+
842+
/** Returns the number of members in the sorted set stored at `key` with scores between `minScore` and `maxScore`.
843+
* See https://redis.io/commands/zcount/ for more details.
844+
*
845+
* @param key - The key of the sorted set.
846+
* @param minScore - The minimum score to count from. Can be positive/negative infinity, or specific score and inclusivity.
847+
* @param maxScore - The maximum score to count up to. Can be positive/negative infinity, or specific score and inclusivity.
848+
*
849+
* Command Response - The number of members in the specified score range.
850+
* If `key` does not exist, it is treated as an empty sorted set, and the command returns 0.
851+
* If `minScore` is greater than `maxScore`, 0 is returned.
852+
* If `key` holds a value that is not a sorted set, an error is returned.
853+
*/
854+
public zcount(key: string, minScore: ScoreLimit, maxScore: ScoreLimit): T {
855+
return this.addAndReturn(createZcount(key, minScore, maxScore));
838856
}
839857

840858
/** Executes a single command, without checking inputs. Every part of the command, including subcommands,

node/tests/SharedTests.ts

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1413,6 +1413,62 @@ export function runBaseTests<Context>(config: {
14131413
},
14141414
config.timeout
14151415
);
1416+
1417+
it.each([ProtocolVersion.RESP2, ProtocolVersion.RESP3])(
1418+
`zcount test_%p`,
1419+
async (protocol) => {
1420+
await runTest(async (client: BaseClient) => {
1421+
const key1 = uuidv4();
1422+
const key2 = uuidv4();
1423+
const membersScores = { one: 1, two: 2, three: 3 };
1424+
expect(await client.zadd(key1, membersScores)).toEqual(3);
1425+
expect(
1426+
await client.zcount(
1427+
key1,
1428+
"negativeInfinity",
1429+
"positiveInfinity"
1430+
)
1431+
).toEqual(3);
1432+
expect(
1433+
await client.zcount(
1434+
key1,
1435+
{ bound: 1, isInclusive: false },
1436+
{ bound: 3, isInclusive: false }
1437+
)
1438+
).toEqual(1);
1439+
expect(
1440+
await client.zcount(
1441+
key1,
1442+
{ bound: 1, isInclusive: false },
1443+
{ bound: 3 }
1444+
)
1445+
).toEqual(2);
1446+
expect(
1447+
await client.zcount(key1, "negativeInfinity", {
1448+
bound: 3,
1449+
})
1450+
).toEqual(3);
1451+
expect(
1452+
await client.zcount(key1, "positiveInfinity", {
1453+
bound: 3,
1454+
})
1455+
).toEqual(0);
1456+
expect(
1457+
await client.zcount(
1458+
"nonExistingKey",
1459+
"negativeInfinity",
1460+
"positiveInfinity"
1461+
)
1462+
).toEqual(0);
1463+
1464+
expect(await client.set(key2, "foo")).toEqual("OK");
1465+
await expect(
1466+
client.zcount(key2, "negativeInfinity", "positiveInfinity")
1467+
).rejects.toThrow();
1468+
}, protocol);
1469+
},
1470+
config.timeout
1471+
);
14161472
}
14171473

14181474
export function runCommonTests<Context>(config: {

node/tests/TestUtilities.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,8 @@ export function transactionTest(
9696
.zaddIncr(key8, "member2", 1)
9797
.zrem(key8, ["member1"])
9898
.zcard(key8)
99-
.zscore(key8, "member2");
99+
.zscore(key8, "member2")
100+
.zcount(key8, { bound: 2 }, "positiveInfinity");
100101
return [
101102
"OK",
102103
null,
@@ -129,6 +130,7 @@ export function transactionTest(
129130
1,
130131
1,
131132
3.0,
133+
1,
132134
];
133135
}
134136

0 commit comments

Comments
 (0)