Skip to content

Commit

Permalink
Node: Add command ZRevRank (valkey-io#1977)
Browse files Browse the repository at this point in the history
* Node: Add command ZRevRank

Signed-off-by: TJ Zhang <[email protected]>
Co-authored-by: TJ Zhang <[email protected]>
  • Loading branch information
tjzhang-BQ and TJ Zhang authored Jul 19, 2024
1 parent 37899df commit 2ecad75
Show file tree
Hide file tree
Showing 6 changed files with 162 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@
* Node: Added FlushAll command ([#1958](https://github.com/valkey-io/valkey-glide/pull/1958))
* Node: Added DBSize command ([#1932](https://github.com/valkey-io/valkey-glide/pull/1932))
* Node: Added GeoAdd command ([#1980](https://github.com/valkey-io/valkey-glide/pull/1980))
* Node: Added ZRevRank command ([#1977](https://github.com/valkey-io/valkey-glide/pull/1977))

#### Breaking Changes
* Node: Update XREAD to return a Map of Map ([#1494](https://github.com/valkey-io/valkey-glide/pull/1494))
Expand Down
51 changes: 51 additions & 0 deletions node/src/BaseClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,8 @@ import {
createZRem,
createZRemRangeByRank,
createZRemRangeByScore,
createZRevRank,
createZRevRankWithScore,
createZScore,
} from "./Commands";
import {
Expand Down Expand Up @@ -2862,6 +2864,55 @@ export class BaseClient {
return this.createWritePromise(createZRank(key, member, true));
}

/**
* Returns the rank of `member` in the sorted set stored at `key`, where
* scores are ordered from the highest to lowest, starting from 0.
* To get the rank of `member` with its score, see {@link zrevrankWithScore}.
*
* See https://valkey.io/commands/zrevrank/ for more details.
*
* @param key - The key of the sorted set.
* @param member - The member whose rank is to be retrieved.
* @returns The rank of `member` in the sorted set, where ranks are ordered from high to low based on scores.
* If `key` doesn't exist, or if `member` is not present in the set, `null` will be returned.
*
* @example
* ```typescript
* const result = await client.zrevrank("my_sorted_set", "member2");
* console.log(result); // Output: 1 - Indicates that "member2" has the second-highest score in the sorted set "my_sorted_set".
* ```
*/
public zrevrank(key: string, member: string): Promise<number | null> {
return this.createWritePromise(createZRevRank(key, member));
}

/**
* Returns the rank of `member` in the sorted set stored at `key` with its
* score, where scores are ordered from the highest to lowest, starting from 0.
*
* See https://valkey.io/commands/zrevrank/ for more details.
*
* @param key - The key of the sorted set.
* @param member - The member whose rank is to be retrieved.
* @returns A list containing the rank and score of `member` in the sorted set, where ranks
* are ordered from high to low based on scores.
* If `key` doesn't exist, or if `member` is not present in the set, `null` will be returned.
*
* since - Valkey version 7.2.0.
*
* @example
* ```typescript
* const result = await client.zrevankWithScore("my_sorted_set", "member2");
* console.log(result); // Output: [1, 6.0] - Indicates that "member2" with score 6.0 has the second-highest score in the sorted set "my_sorted_set".
* ```
*/
public zrevrankWithScore(
key: string,
member: string,
): Promise<(number[] | null)[]> {
return this.createWritePromise(createZRevRankWithScore(key, member));
}

/**
* Adds an entry to the specified stream stored at `key`. If the `key` doesn't exist, the stream is created.
* See https://valkey.io/commands/xadd/ for more details.
Expand Down
20 changes: 20 additions & 0 deletions node/src/Commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1802,3 +1802,23 @@ export function createGeoAdd(

return createCommand(RequestType.GeoAdd, args);
}

/**
* @internal
*/
export function createZRevRank(
key: string,
member: string,
): command_request.Command {
return createCommand(RequestType.ZRevRank, [key, member]);
}

/**
* @internal
*/
export function createZRevRankWithScore(
key: string,
member: string,
): command_request.Command {
return createCommand(RequestType.ZRevRank, [key, member, "WITHSCORE"]);
}
38 changes: 38 additions & 0 deletions node/src/Transaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,8 @@ import {
createZRemRangeByScore,
createZScore,
createGeoAdd,
createZRevRank,
createZRevRankWithScore,
createFunctionLoad,
} from "./Commands";
import { command_request } from "./ProtobufMessage";
Expand Down Expand Up @@ -1493,6 +1495,42 @@ export class BaseTransaction<T extends BaseTransaction<T>> {
return this.addAndReturn(createZRank(key, member, true));
}

/**
* Returns the rank of `member` in the sorted set stored at `key`, where
* scores are ordered from the highest to lowest, starting from 0.
* To get the rank of `member` with its score, see {@link zrevrankWithScore}.
*
* See https://valkey.io/commands/zrevrank/ for more details.
*
* @param key - The key of the sorted set.
* @param member - The member whose rank is to be retrieved.
*
* Command Response - The rank of `member` in the sorted set, where ranks are ordered from high to low based on scores.
* If `key` doesn't exist, or if `member` is not present in the set, `null` will be returned.
*/
public zrevrank(key: string, member: string): T {
return this.addAndReturn(createZRevRank(key, member));
}

/**
* Returns the rank of `member` in the sorted set stored at `key` with its
* score, where scores are ordered from the highest to lowest, starting from 0.
*
* See https://valkey.io/commands/zrevrank/ for more details.
*
* @param key - The key of the sorted set.
* @param member - The member whose rank is to be retrieved.
*
* Command Response - A list containing the rank and score of `member` in the sorted set, where ranks
* are ordered from high to low based on scores.
* If `key` doesn't exist, or if `member` is not present in the set, `null` will be returned.
*
* since - Valkey version 7.2.0.
*/
public zrevrankWithScore(key: string, member: string): T {
return this.addAndReturn(createZRevRankWithScore(key, member));
}

/** Remove the existing timeout on `key`, turning the key from volatile (a key with an expire set) to
* persistent (a key that will never expire as no timeout is associated).
* See https://valkey.io/commands/persist/ for more details.
Expand Down
44 changes: 44 additions & 0 deletions node/tests/SharedTests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3120,6 +3120,50 @@ export function runBaseTests<Context>(config: {
},
);

it.each([ProtocolVersion.RESP2, ProtocolVersion.RESP3])(
`zrevrank test_%p`,
async (protocol) => {
await runTest(async (client: BaseClient) => {
const key = uuidv4();
const nonSetKey = uuidv4();
const membersScores = { one: 1.5, two: 2, three: 3 };
expect(await client.zadd(key, membersScores)).toEqual(3);
expect(await client.zrevrank(key, "three")).toEqual(0);

if (!(await checkIfServerVersionLessThan("7.2.0"))) {
expect(await client.zrevrankWithScore(key, "one")).toEqual([
2, 1.5,
]);
expect(
await client.zrevrankWithScore(
key,
"nonExistingMember",
),
).toBeNull();
expect(
await client.zrevrankWithScore(
"nonExistingKey",
"member",
),
).toBeNull();
}

expect(
await client.zrevrank(key, "nonExistingMember"),
).toBeNull();
expect(
await client.zrevrank("nonExistingKey", "member"),
).toBeNull();

// Key exists, but is not a sorted set
checkSimple(await client.set(nonSetKey, "value")).toEqual("OK");
await expect(
client.zrevrank(nonSetKey, "member"),
).rejects.toThrow();
}, protocol);
},
);

it.each([ProtocolVersion.RESP2, ProtocolVersion.RESP3])(
`test brpop test_%p`,
async (protocol) => {
Expand Down
8 changes: 8 additions & 0 deletions node/tests/TestUtilities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -522,6 +522,14 @@ export async function transactionTest(
args.push([0, 1]);
}

baseTransaction.zrevrank(key8, "member5");
args.push(0);

if (!(await checkIfServerVersionLessThan("7.2.0"))) {
baseTransaction.zrevrankWithScore(key8, "member5");
args.push([0, 5]);
}

baseTransaction.zaddIncr(key8, "member2", 1);
args.push(3);
baseTransaction.zrem(key8, ["member1"]);
Expand Down

0 comments on commit 2ecad75

Please sign in to comment.