Skip to content

Commit 95e80af

Browse files
feat: implement proper hpexpire command signatures and tests (#2006)
* feat: implement proper hpexpire command signatures and tests * feat: implement proper hpexpire command signatures and tests * chore: update @ioredis/commands to 1.3.1 --------- Co-authored-by: Pavel Pashov <pavel.pashov@redis.com>
1 parent 8a3e052 commit 95e80af

File tree

5 files changed

+98
-8
lines changed

5 files changed

+98
-8
lines changed

bin/returnTypes.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@ module.exports = {
143143
hello: "unknown[]",
144144
hexists: "number",
145145
hexpire: "number[]",
146+
hpexpire: "number[]",
146147
hget: "string | null",
147148
hgetall: "[field: string, value: string][]",
148149
hincrby: "number",

lib/utils/RedisCommander.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4028,6 +4028,23 @@ interface RedisCommander<Context extends ClientContext = { type: "default" }> {
40284028
...args: [key: RedisKey, ...fieldValues: (string | Buffer | number)[]]
40294029
): Result<"OK", Context>;
40304030

4031+
/**
4032+
* Set expiry for hash field using relative time to expire (milliseconds)
4033+
* - _group_: hash
4034+
* - _complexity_: O(N) where N is the number of specified fields
4035+
* - _since_: 7.4.0
4036+
*/
4037+
hpexpire(...args: [key: RedisKey, milliseconds: number | string, fieldsToken: 'FIELDS', numfields: number | string, ...fields: (string | Buffer)[], callback: Callback<number[]>]): Result<number[], Context>;
4038+
hpexpire(...args: [key: RedisKey, milliseconds: number | string, fieldsToken: 'FIELDS', numfields: number | string, ...fields: (string | Buffer)[]]): Result<number[], Context>;
4039+
hpexpire(...args: [key: RedisKey, milliseconds: number | string, nx: 'NX', fieldsToken: 'FIELDS', numfields: number | string, ...fields: (string | Buffer)[], callback: Callback<number[]>]): Result<number[], Context>;
4040+
hpexpire(...args: [key: RedisKey, milliseconds: number | string, nx: 'NX', fieldsToken: 'FIELDS', numfields: number | string, ...fields: (string | Buffer)[]]): Result<number[], Context>;
4041+
hpexpire(...args: [key: RedisKey, milliseconds: number | string, xx: 'XX', fieldsToken: 'FIELDS', numfields: number | string, ...fields: (string | Buffer)[], callback: Callback<number[]>]): Result<number[], Context>;
4042+
hpexpire(...args: [key: RedisKey, milliseconds: number | string, xx: 'XX', fieldsToken: 'FIELDS', numfields: number | string, ...fields: (string | Buffer)[]]): Result<number[], Context>;
4043+
hpexpire(...args: [key: RedisKey, milliseconds: number | string, gt: 'GT', fieldsToken: 'FIELDS', numfields: number | string, ...fields: (string | Buffer)[], callback: Callback<number[]>]): Result<number[], Context>;
4044+
hpexpire(...args: [key: RedisKey, milliseconds: number | string, gt: 'GT', fieldsToken: 'FIELDS', numfields: number | string, ...fields: (string | Buffer)[]]): Result<number[], Context>;
4045+
hpexpire(...args: [key: RedisKey, milliseconds: number | string, lt: 'LT', fieldsToken: 'FIELDS', numfields: number | string, ...fields: (string | Buffer)[], callback: Callback<number[]>]): Result<number[], Context>;
4046+
hpexpire(...args: [key: RedisKey, milliseconds: number | string, lt: 'LT', fieldsToken: 'FIELDS', numfields: number | string, ...fields: (string | Buffer)[]]): Result<number[], Context>;
4047+
40314048
/**
40324049
* Get one or multiple random fields from a hash
40334050
* - _group_: hash

package-lock.json

Lines changed: 7 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@
4343
"url": "https://opencollective.com/ioredis"
4444
},
4545
"dependencies": {
46-
"@ioredis/commands": "^1.3.0",
46+
"@ioredis/commands": "^1.3.1",
4747
"cluster-key-slot": "^1.1.0",
4848
"debug": "^4.3.4",
4949
"denque": "^2.1.0",

test/functional/hpexpire.ts

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
import Redis from "../../lib/Redis";
2+
import { expect } from "chai";
3+
4+
describe("hpexpire", () => {
5+
const hashKey = "test_hash_key";
6+
const field = "test_field";
7+
8+
it("should handle non-existing field", async () => {
9+
const redis = new Redis();
10+
11+
const result = await redis.hpexpire(
12+
"non_existing_hash_key",
13+
60,
14+
"NX",
15+
"FIELDS",
16+
1,
17+
"non_existing_field"
18+
);
19+
20+
expect(result).to.deep.equal([-2]);
21+
});
22+
23+
it("should handle existing field", async () => {
24+
const redis = new Redis();
25+
26+
await redis.hset(hashKey, field, "value");
27+
28+
const result = await redis.hpexpire(hashKey, 60, "FIELDS", 1, field);
29+
30+
expect(result).to.deep.equal([1]);
31+
});
32+
33+
it("should return 0 when condition is not met", async () => {
34+
const redis = new Redis();
35+
36+
await redis.hset(hashKey, field, "value");
37+
await redis.hpexpire(hashKey, 60, "FIELDS", 1, field); // Set initial expiry
38+
39+
// Try to set expiry with NX when field already has expiry
40+
const result = await redis.hpexpire(hashKey, 120, "NX", "FIELDS", 1, field);
41+
42+
expect(result).to.deep.equal([0]);
43+
});
44+
45+
it("should return 2 when expiring field with 0 seconds", async () => {
46+
const redis = new Redis();
47+
48+
await redis.hset(hashKey, field, "value");
49+
50+
const result = await redis.hpexpire(hashKey, 0, "FIELDS", 1, field);
51+
52+
expect(result).to.deep.equal([2]);
53+
});
54+
55+
it("should expire multiple fields", async () => {
56+
const redis = new Redis();
57+
58+
await redis.hset(hashKey, field, "value", "field2", "value2");
59+
60+
const result = await redis.hpexpire(
61+
hashKey,
62+
60,
63+
"FIELDS",
64+
3,
65+
field,
66+
"field2",
67+
"non_existing_field"
68+
);
69+
70+
expect(result).to.deep.equal([1, 1, -2]);
71+
});
72+
});

0 commit comments

Comments
 (0)