diff --git a/CHANGELOG.md b/CHANGELOG.md index 0881bb1013..17e8e382bc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,10 +1,10 @@ ## 0.2.0 (2024-02-11) #### Changes -* Python, Node: Added ZCARD command ([#877](https://github.com/aws/glide-for-redis/pull/885), [#885](https://github.com/aws/glide-for-redis/pull/885)) +* Python, Node: Added ZCARD command ([#871](https://github.com/aws/glide-for-redis/pull/871), [#885](https://github.com/aws/glide-for-redis/pull/885)) * Python, Node: Added ZADD and ZADDINCR commands ([#814](https://github.com/aws/glide-for-redis/pull/814), [#830](https://github.com/aws/glide-for-redis/pull/830)) * Python, Node: Added ZREM command ([#834](https://github.com/aws/glide-for-redis/pull/834), [#831](https://github.com/aws/glide-for-redis/pull/831)) -* Python, Node: Added ZSCORE command ([#885](https://github.com/aws/glide-for-redis/pull/885), [#871](https://github.com/aws/glide-for-redis/pull/871)) +* Python, Node: Added ZSCORE command ([#877](https://github.com/aws/glide-for-redis/pull/877), [#889](https://github.com/aws/glide-for-redis/pull/889)) * Use jemalloc as default allocator. ([#847](https://github.com/aws/glide-for-redis/pull/847)) * Python, Node: Added RPOPCOUNT and LPOPCOUNT to transaction ([#874](https://github.com/aws/glide-for-redis/pull/874)) * Standalone client: Improve connection errors. ([#854](https://github.com/aws/glide-for-redis/pull/854)) diff --git a/node/src/BaseClient.ts b/node/src/BaseClient.ts index 0f7276a3b3..e6cc107983 100644 --- a/node/src/BaseClient.ts +++ b/node/src/BaseClient.ts @@ -54,6 +54,7 @@ import { createZadd, createZcard, createZrem, + createZscore, } from "./Commands"; import { ClosingError, @@ -1062,6 +1063,20 @@ export class BaseClient { return this.createWritePromise(createZcard(key)); } + /** Returns the score of `member` in the sorted set stored at `key`. + * See https://redis.io/commands/zscore/ for more details. + * + * @param key - The key of the sorted set. + * @param member - The member whose score is to be retrieved. + * @returns The score of the member. + * If `member` does not exist in the sorted set, null is returned. + * If `key` does not exist, null is returned. + * If `key` holds a value that is not a sorted set, an error is returned. + */ + public zscore(key: string, member: string): Promise { + return this.createWritePromise(createZscore(key, member)); + } + private readonly MAP_READ_FROM_STRATEGY: Record< ReadFrom, connection_request.ReadFrom diff --git a/node/src/Commands.ts b/node/src/Commands.ts index ff2a0b8ab5..3363d65d52 100644 --- a/node/src/Commands.ts +++ b/node/src/Commands.ts @@ -760,3 +760,10 @@ export function createZrem( export function createZcard(key: string): redis_request.Command { return createCommand(RequestType.Zcard, [key]); } + +/** + * @internal + */ +export function createZscore(key: string, member: string): redis_request.Command { + return createCommand(RequestType.ZScore, [key, member]); +} diff --git a/node/src/Transaction.ts b/node/src/Transaction.ts index 7a12f04670..7e5a434c5b 100644 --- a/node/src/Transaction.ts +++ b/node/src/Transaction.ts @@ -57,6 +57,7 @@ import { createZadd, createZcard, createZrem, + createZscore, } from "./Commands"; import { redis_request } from "./ProtobufMessage"; @@ -821,6 +822,21 @@ export class BaseTransaction> { return this.addAndReturn(createZcard(key)); } + /** Returns the score of `member` in the sorted set stored at `key`. + * See https://redis.io/commands/zscore/ for more details. + * + * @param key - The key of the sorted set. + * @param member - The member whose score is to be retrieved. + * + * Command Response - The score of the member. + * If `member` does not exist in the sorted set, null is returned. + * If `key` does not exist, null is returned. + * If `key` holds a value that is not a sorted set, an error is returned. + */ + public zscore(key: string, member: string) { + this.commands.push(createZscore(key, member)); + } + /** Executes a single command, without checking inputs. Every part of the command, including subcommands, * should be added as a separate value in args. * diff --git a/node/tests/SharedTests.ts b/node/tests/SharedTests.ts index 025e70ff2c..d8da1c397e 100644 --- a/node/tests/SharedTests.ts +++ b/node/tests/SharedTests.ts @@ -1389,6 +1389,30 @@ export function runBaseTests(config: { }, config.timeout ); + + + it.each([ProtocolVersion.RESP2, ProtocolVersion.RESP3])( + `zscore test_%p`, + async (protocol) => { + await runTest(async (client: BaseClient) => { + const key1 = uuidv4(); + const key2 = uuidv4(); + const membersScores = { one: 1, two: 2, three: 3 }; + expect(await client.zadd(key1, membersScores)).toEqual(3); + expect(await client.zscore(key1, "one")).toEqual(1.0); + expect(await client.zscore(key1, "nonExistingMember")).toEqual( + null + ); + expect( + await client.zscore("nonExistingKey", "nonExistingMember") + ).toEqual(null); + + expect(await client.set(key2, "foo")).toEqual("OK"); + await expect(client.zscore(key2, "foo")).rejects.toThrow(); + }, protocol); + }, + config.timeout + ); } export function runCommonTests(config: { diff --git a/node/tests/TestUtilities.ts b/node/tests/TestUtilities.ts index e25dede769..6ce9330180 100644 --- a/node/tests/TestUtilities.ts +++ b/node/tests/TestUtilities.ts @@ -95,7 +95,8 @@ export function transactionTest( .zadd(key8, { member1: 1, member2: 2 }) .zaddIncr(key8, "member2", 1) .zrem(key8, ["member1"]) - .zcard(key8); + .zcard(key8) + .zscore(key8, "member2"); return [ "OK", null, @@ -127,6 +128,7 @@ export function transactionTest( 3, 1, 1, + 3.0, ]; }