Skip to content

Commit

Permalink
Added zremRangeByScore command in Node. (#926)
Browse files Browse the repository at this point in the history
  • Loading branch information
Adan Wattad authored Mar 13, 2024
1 parent f388dc9 commit 4a208f1
Show file tree
Hide file tree
Showing 8 changed files with 124 additions and 33 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
* Python, Node: Added PTTL command ([#1036](https://github.com/aws/glide-for-redis/pull/1036), [#1082](https://github.com/aws/glide-for-redis/pull/1082))
* Node: Added HVAL command ([#1022](https://github.com/aws/glide-for-redis/pull/1022))
* Node: Added PERSIST command ([#1023](https://github.com/aws/glide-for-redis/pull/1023))
* Node: Added ZREMRANGEBYSCORE command ([#926](https://github.com/aws/glide-for-redis/pull/926))
* Node: Added ZREMRANGEBYRANK command ([#924](https://github.com/aws/glide-for-redis/pull/924))
* Node: Added Xadd, Xtrim commands. ([#1057](https://github.com/aws/glide-for-redis/pull/1057))
* Python: Added json module and JSON.SET JSON.GET commands ([#1056](https://github.com/aws/glide-for-redis/pull/1056))

Expand Down
1 change: 1 addition & 0 deletions glide-core/src/protobuf/redis_request.proto
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ enum RequestType {
Persist = 87;
JsonSet = 88;
JsonGet = 89;
ZRemRangeByScore = 90;
}

message Command {
Expand Down
1 change: 1 addition & 0 deletions glide-core/src/socket_listener.rs
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,7 @@ fn get_command(request: &Command) -> Option<Cmd> {
RequestType::Persist => Some(cmd("PERSIST")),
RequestType::JsonSet => Some(cmd("JSON.SET")),
RequestType::JsonGet => Some(cmd("JSON.GET")),
RequestType::ZRemRangeByScore => Some(cmd("ZREMRANGEBYSCORE")),
}
}

Expand Down
21 changes: 21 additions & 0 deletions node/src/BaseClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ import {
createZpopmin,
createZrem,
createZremRangeByRank,
createZremRangeByScore,
createZscore,
} from "./Commands";
import {
Expand Down Expand Up @@ -1211,6 +1212,26 @@ export class BaseClient {
return this.createWritePromise(createZremRangeByRank(key, start, end));
}

/** Removes all elements in the sorted set stored at `key` with a score between `minScore` and `maxScore`.
* See https://redis.io/commands/zremrangebyscore/ for more details.
*
* @param key - The key of the sorted set.
* @param minScore - The minimum score to remove from. Can be positive/negative infinity, or specific score and inclusivity.
* @param maxScore - The maximum score to remove to. Can be positive/negative infinity, or specific score and inclusivity.
* @returns the number of members removed.
* If `key` does not exist, it is treated as an empty sorted set, and the command returns 0.
* If `minScore` is greater than `maxScore`, 0 is returned.
*/
public zremRangeByScore(
key: string,
minScore: ScoreLimit,
maxScore: ScoreLimit,
): Promise<number> {
return this.createWritePromise(
createZremRangeByScore(key, minScore, maxScore),
);
}

/**
* Adds an entry to the specified stream.
* See https://redis.io/commands/xadd/ for more details.
Expand Down
57 changes: 29 additions & 28 deletions node/src/Commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -800,9 +800,19 @@ export type ScoreLimit =
isInclusive?: boolean;
};

const positiveInfinityArg = "+inf";
const negativeInfinityArg = "-inf";
const isInclusiveArg = "(";
function getScoreLimitArg(score: ScoreLimit): string {
if (score == "positiveInfinity") {
return "+inf";
} else if (score == "negativeInfinity") {
return "-inf";
}

const value =
score.isInclusive == false
? "(" + score.bound.toString()
: score.bound.toString();
return value;
}

/**
* @internal
Expand All @@ -813,31 +823,8 @@ export function createZcount(
maxScore: ScoreLimit,
): redis_request.Command {
const args = [key];

if (minScore == "positiveInfinity") {
args.push(positiveInfinityArg);
} else if (minScore == "negativeInfinity") {
args.push(negativeInfinityArg);
} else {
const value =
minScore.isInclusive == false
? isInclusiveArg + minScore.bound.toString()
: minScore.bound.toString();
args.push(value);
}

if (maxScore == "positiveInfinity") {
args.push(positiveInfinityArg);
} else if (maxScore == "negativeInfinity") {
args.push(negativeInfinityArg);
} else {
const value =
maxScore.isInclusive == false
? isInclusiveArg + maxScore.bound.toString()
: maxScore.bound.toString();
args.push(value);
}

args.push(getScoreLimitArg(minScore));
args.push(getScoreLimitArg(maxScore));
return createCommand(RequestType.Zcount, args);
}

Expand Down Expand Up @@ -916,6 +903,20 @@ export function createZremRangeByRank(
]);
}

/**
* @internal
*/
export function createZremRangeByScore(
key: string,
minScore: ScoreLimit,
maxScore: ScoreLimit,
): redis_request.Command {
const args = [key];
args.push(getScoreLimitArg(minScore));
args.push(getScoreLimitArg(maxScore));
return createCommand(RequestType.ZRemRangeByScore, args);
}

export function createPersist(key: string): redis_request.Command {
return createCommand(RequestType.Persist, [key]);
}
Expand Down
22 changes: 22 additions & 0 deletions node/src/Transaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ import {
createZpopmin,
createZrem,
createZremRangeByRank,
createZremRangeByScore,
createZscore,
} from "./Commands";
import { redis_request } from "./ProtobufMessage";
Expand Down Expand Up @@ -974,6 +975,27 @@ export class BaseTransaction<T extends BaseTransaction<T>> {
return this.addAndReturn(createZremRangeByRank(key, start, end));
}

/** Removes all elements in the sorted set stored at `key` with a score between `minScore` and `maxScore`.
* See https://redis.io/commands/zremrangebyscore/ for more details.
*
* @param key - The key of the sorted set.
* @param minScore - The minimum score to remove from. Can be positive/negative infinity, or specific score and inclusivity.
* @param maxScore - The maximum score to remove to. Can be positive/negative infinity, or specific score and inclusivity.
*
* Command Response - the number of members removed.
* If `key` does not exist, it is treated as an empty sorted set, and the command returns 0.
* If `minScore` is greater than `maxScore`, 0 is returned.
*/
public zremRangeByScore(
key: string,
minScore: ScoreLimit,
maxScore: ScoreLimit,
): T {
return this.addAndReturn(
createZremRangeByScore(key, minScore, maxScore),
);
}

/** 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://redis.io/commands/persist/ for more details.
Expand Down
36 changes: 36 additions & 0 deletions node/tests/SharedTests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1829,6 +1829,42 @@ export function runBaseTests<Context>(config: {
},
config.timeout,
);

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

expect(
await client.zremRangeByScore(
key,
{ bound: 1, isInclusive: false },
{ bound: 2 },
),
).toEqual(1);

expect(
await client.zremRangeByScore(
key,
{ bound: 1 },
"negativeInfinity",
),
).toEqual(0);

expect(
await client.zremRangeByScore(
"nonExistingKey",
"negativeInfinity",
"positiveInfinity",
),
).toEqual(0);
}, protocol);
},
config.timeout,
);
}

export function runCommonTests<Context>(config: {
Expand Down
17 changes: 12 additions & 5 deletions node/tests/TestUtilities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -145,23 +145,30 @@ export function transactionTest(
member2: 2,
member3: 3.5,
member4: 4,
member5: 5,
});
args.push(4);
args.push(5);
baseTransaction.zaddIncr(key8, "member2", 1);
args.push(3);
baseTransaction.zrem(key8, ["member1"]);
args.push(1);
baseTransaction.zcard(key8);
args.push(3);
args.push(4);
baseTransaction.zscore(key8, "member2");
args.push(3.0);
baseTransaction.zcount(key8, { bound: 2 }, "positiveInfinity");
args.push(3);
args.push(4);
baseTransaction.zpopmin(key8);
args.push({ member2: 3.0 });
baseTransaction.zpopmax(key8);
args.push({ member4: 4 });
baseTransaction.zremRangeByRank(key8, 0, 1);
args.push({ member5: 5 });
baseTransaction.zremRangeByRank(key8, 1, 1);
args.push(1);
baseTransaction.zremRangeByScore(
key8,
"negativeInfinity",
"positiveInfinity",
);
args.push(1);
baseTransaction.xadd(key9, [["foo", "bar"]], { id: "0-1" });
args.push("0-1");
Expand Down

0 comments on commit 4a208f1

Please sign in to comment.