Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add support for all hash field expiration commands #2787

Merged
merged 1 commit into from
Jul 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions packages/client/lib/cluster/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,20 +53,29 @@ import * as GETRANGE from '../commands/GETRANGE';
import * as GETSET from '../commands/GETSET';
import * as HDEL from '../commands/HDEL';
import * as HEXISTS from '../commands/HEXISTS';
import * as HEXPIRE from '../commands/HEXPIRE';
import * as HEXPIREAT from '../commands/HEXPIREAT';
import * as HEXPIRETIME from '../commands/HEXPIRETIME';
import * as HGET from '../commands/HGET';
import * as HGETALL from '../commands/HGETALL';
import * as HINCRBY from '../commands/HINCRBY';
import * as HINCRBYFLOAT from '../commands/HINCRBYFLOAT';
import * as HKEYS from '../commands/HKEYS';
import * as HLEN from '../commands/HLEN';
import * as HMGET from '../commands/HMGET';
import * as HPERSIST from '../commands/HPERSIST';
import * as HPEXPIRE from '../commands/HPEXPIRE';
import * as HPEXPIREAT from '../commands/HPEXPIREAT';
import * as HPEXPIRETIME from '../commands/HPEXPIRETIME';
import * as HPTTL from '../commands/HPTTL';
import * as HRANDFIELD_COUNT_WITHVALUES from '../commands/HRANDFIELD_COUNT_WITHVALUES';
import * as HRANDFIELD_COUNT from '../commands/HRANDFIELD_COUNT';
import * as HRANDFIELD from '../commands/HRANDFIELD';
import * as HSCAN from '../commands/HSCAN';
import * as HSET from '../commands/HSET';
import * as HSETNX from '../commands/HSETNX';
import * as HSTRLEN from '../commands/HSTRLEN';
import * as HTTL from '../commands/HTTL';
import * as HVALS from '../commands/HVALS';
import * as INCR from '../commands/INCR';
import * as INCRBY from '../commands/INCRBY';
Expand Down Expand Up @@ -321,6 +330,12 @@ export default {
hDel: HDEL,
HEXISTS,
hExists: HEXISTS,
HEXPIRE,
hExpire: HEXPIRE,
HEXPIREAT,
hExpireAt: HEXPIREAT,
HEXPIRETIME,
hExpireTime: HEXPIRETIME,
HGET,
hGet: HGET,
HGETALL,
Expand All @@ -335,6 +350,16 @@ export default {
hLen: HLEN,
HMGET,
hmGet: HMGET,
HPERSIST,
hPersist: HPERSIST,
HPEXPIRE,
hpExpire: HPEXPIRE,
HPEXPIREAT,
hpExpireAt: HPEXPIREAT,
HPEXPIRETIME,
hpExpireTime: HPEXPIRETIME,
HPTTL,
hpTTL: HPTTL,
HRANDFIELD_COUNT_WITHVALUES,
hRandFieldCountWithValues: HRANDFIELD_COUNT_WITHVALUES,
HRANDFIELD_COUNT,
Expand All @@ -349,6 +374,8 @@ export default {
hSetNX: HSETNX,
HSTRLEN,
hStrLen: HSTRLEN,
HTTL,
hTTL: HTTL,
HVALS,
hVals: HVALS,
INCR,
Expand Down
40 changes: 40 additions & 0 deletions packages/client/lib/commands/HEXPIRE.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { strict as assert } from 'node:assert';
import testUtils, { GLOBAL } from '../test-utils';
import { transformArguments } from './HEXPIRE';
import { HASH_EXPIRATION_TIME } from './HEXPIRETIME';

describe('HEXPIRE', () => {
testUtils.isVersionGreaterThanHook([7, 4]);

describe('transformArguments', () => {
it('string', () => {
assert.deepEqual(
transformArguments('key', 'field', 1),
['HEXPIRE', 'key', '1', 'FIELDS', '1', 'field']
);
});

it('array', () => {
assert.deepEqual(
transformArguments('key', ['field1', 'field2'], 1),
['HEXPIRE', 'key', '1', 'FIELDS', '2', 'field1', 'field2']
);
});

it('with set option', () => {
assert.deepEqual(
transformArguments('key', ['field1'], 1, 'NX'),
['HEXPIRE', 'key', '1', 'NX', 'FIELDS', '1', 'field1']
);
});
});

testUtils.testWithClient('hexpire', async client => {
assert.deepEqual(
await client.hExpire('key', ['field1'], 0),
[ HASH_EXPIRATION_TIME.FieldNotExists ]
);
}, {
...GLOBAL.SERVERS.OPEN
});
});
44 changes: 44 additions & 0 deletions packages/client/lib/commands/HEXPIRE.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { RedisCommandArgument } from '.';
import { pushVerdictArgument } from './generic-transformers';

/**
* @readonly
* @enum {number}
*/
export const HASH_EXPIRATION = {
/** @property {number} */
/** The field does not exist */
FieldNotExists: -2,
/** @property {number} */
/** Specified NX | XX | GT | LT condition not met */
ConditionNotMet: 0,
/** @property {number} */
/** Expiration time was set or updated */
Updated: 1,
/** @property {number} */
/** Field deleted because the specified expiration time is in the past */
Deleted: 2
} as const;

export type HashExpiration = typeof HASH_EXPIRATION[keyof typeof HASH_EXPIRATION];

export const FIRST_KEY_INDEX = 1;

export function transformArguments(
key: RedisCommandArgument,
fields: RedisCommandArgument| Array<RedisCommandArgument>,
seconds: number,
mode?: 'NX' | 'XX' | 'GT' | 'LT',
) {
const args = ['HEXPIRE', key, seconds.toString()];

if (mode) {
args.push(mode);
}

args.push('FIELDS');

return pushVerdictArgument(args, fields);
}

export declare function transformReply(): Array<HashExpiration>;
49 changes: 49 additions & 0 deletions packages/client/lib/commands/HEXPIREAT.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { strict as assert } from 'node:assert';
import testUtils, { GLOBAL } from '../test-utils';
import { transformArguments } from './HEXPIREAT';
import { HASH_EXPIRATION_TIME } from './HEXPIRETIME';

describe('HEXPIREAT', () => {
testUtils.isVersionGreaterThanHook([7, 4]);

describe('transformArguments', () => {
it('string + number', () => {
assert.deepEqual(
transformArguments('key', 'field', 1),
['HEXPIREAT', 'key', '1', 'FIELDS', '1', 'field']
);
});

it('array + number', () => {
assert.deepEqual(
transformArguments('key', ['field1', 'field2'], 1),
['HEXPIREAT', 'key', '1', 'FIELDS', '2', 'field1', 'field2']
);
});

it('date', () => {
const d = new Date();

assert.deepEqual(
transformArguments('key', ['field1'], d),
['HEXPIREAT', 'key', Math.floor(d.getTime() / 1000).toString(), 'FIELDS', '1', 'field1']
);
});

it('with set option', () => {
assert.deepEqual(
transformArguments('key', 'field1', 1, 'GT'),
['HEXPIREAT', 'key', '1', 'GT', 'FIELDS', '1', 'field1']
);
});
});

testUtils.testWithClient('expireAt', async client => {
assert.deepEqual(
await client.hExpireAt('key', 'field1', 1),
[ HASH_EXPIRATION_TIME.FieldNotExists ]
);
}, {
...GLOBAL.SERVERS.OPEN,
});
});
28 changes: 28 additions & 0 deletions packages/client/lib/commands/HEXPIREAT.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { RedisCommandArgument } from '.';
import { pushVerdictArgument, transformEXAT } from './generic-transformers';
import { HashExpiration } from './HEXPIRE';

export const FIRST_KEY_INDEX = 1;

export function transformArguments(
key: RedisCommandArgument,
fields: RedisCommandArgument | Array<RedisCommandArgument>,
timestamp: number | Date,
mode?: 'NX' | 'XX' | 'GT' | 'LT'
) {
const args = [
'HEXPIREAT',
key,
transformEXAT(timestamp)
];

if (mode) {
args.push(mode);
}

args.push('FIELDS')

return pushVerdictArgument(args, fields);
}

export declare function transformReply(): Array<HashExpiration>;
32 changes: 32 additions & 0 deletions packages/client/lib/commands/HEXPIRETIME.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { strict as assert } from 'node:assert';
import testUtils, { GLOBAL } from '../test-utils';
import { HASH_EXPIRATION_TIME, transformArguments } from './HEXPIRETIME';

describe('HEXPIRETIME', () => {
testUtils.isVersionGreaterThanHook([7, 4]);

describe('transformArguments', () => {
it('string', () => {
assert.deepEqual(
transformArguments('key', 'field'),
['HEXPIRETIME', 'key', 'FIELDS', '1', 'field']
);
});

it('array', () => {
assert.deepEqual(
transformArguments('key', ['field1', 'field2']),
['HEXPIRETIME', 'key', 'FIELDS', '2', 'field1', 'field2']
);
});
})

testUtils.testWithClient('hExpireTime', async client => {
assert.deepEqual(
await client.hExpireTime('key', 'field1'),
[ HASH_EXPIRATION_TIME.FieldNotExists ]
);
}, {
...GLOBAL.SERVERS.OPEN,
});
});
21 changes: 21 additions & 0 deletions packages/client/lib/commands/HEXPIRETIME.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { RedisCommandArgument } from '.';
import { pushVerdictArgument } from './generic-transformers';

export const HASH_EXPIRATION_TIME = {
/** @property {number} */
/** The field does not exist */
FieldNotExists: -2,
/** @property {number} */
/** The field exists but has no associated expire */
NoExpiration: -1,
} as const;

export const FIRST_KEY_INDEX = 1

export const IS_READ_ONLY = true;

export function transformArguments(key: RedisCommandArgument, fields: RedisCommandArgument | Array<RedisCommandArgument>) {
return pushVerdictArgument(['HEXPIRETIME', key, 'FIELDS'], fields);
}

export declare function transformReply(): Array<number>;
33 changes: 33 additions & 0 deletions packages/client/lib/commands/HPERSIST.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { strict as assert } from 'node:assert';
import testUtils, { GLOBAL } from '../test-utils';
import { transformArguments } from './HPERSIST';
import { HASH_EXPIRATION_TIME } from './HEXPIRETIME';

describe('HPERSIST', () => {
testUtils.isVersionGreaterThanHook([7, 4]);

describe('transformArguments', () => {
it('string', () => {
assert.deepEqual(
transformArguments('key', 'field'),
['HPERSIST', 'key', 'FIELDS', '1', 'field']
);
});

it('array', () => {
assert.deepEqual(
transformArguments('key', ['field1', 'field2']),
['HPERSIST', 'key', 'FIELDS', '2', 'field1', 'field2']
);
});
})

testUtils.testWithClient('hPersist', async client => {
assert.deepEqual(
await client.hPersist('key', 'field1'),
[ HASH_EXPIRATION_TIME.FieldNotExists ]
);
}, {
...GLOBAL.SERVERS.OPEN,
});
});
10 changes: 10 additions & 0 deletions packages/client/lib/commands/HPERSIST.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { RedisCommandArgument } from '.';
import { pushVerdictArgument } from './generic-transformers';

export const FIRST_KEY_INDEX = 1;

export function transformArguments(key: RedisCommandArgument, fields: RedisCommandArgument | Array<RedisCommandArgument>) {
return pushVerdictArgument(['HPERSIST', key, 'FIELDS'], fields);
}

export declare function transformReply(): Array<number> | null;
40 changes: 40 additions & 0 deletions packages/client/lib/commands/HPEXPIRE.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { strict as assert } from 'node:assert';
import testUtils, { GLOBAL } from '../test-utils';
import { transformArguments } from './HPEXPIRE';
import { HASH_EXPIRATION_TIME } from './HEXPIRETIME';

describe('HEXPIRE', () => {
testUtils.isVersionGreaterThanHook([7, 4]);

describe('transformArguments', () => {
it('string', () => {
assert.deepEqual(
transformArguments('key', 'field', 1),
['HPEXPIRE', 'key', '1', 'FIELDS', '1', 'field']
);
});

it('array', () => {
assert.deepEqual(
transformArguments('key', ['field1', 'field2'], 1),
['HPEXPIRE', 'key', '1', 'FIELDS', '2', 'field1', 'field2']
);
});

it('with set option', () => {
assert.deepEqual(
transformArguments('key', ['field1'], 1, 'NX'),
['HPEXPIRE', 'key', '1', 'NX', 'FIELDS', '1', 'field1']
);
});
});

testUtils.testWithClient('hexpire', async client => {
assert.deepEqual(
await client.hpExpire('key', ['field1'], 0),
[ HASH_EXPIRATION_TIME.FieldNotExists ]
);
}, {
...GLOBAL.SERVERS.OPEN
});
});
Loading
Loading