1
0
mirror of https://github.com/redis/node-redis.git synced 2025-08-07 13:22:56 +03:00
This commit is contained in:
Leibale
2023-07-06 10:38:30 -04:00
parent 2a662a367d
commit ab153a8eda
10 changed files with 97 additions and 60 deletions

View File

@@ -1,24 +1,20 @@
// import { RedisCommandArgument, RedisCommandArguments } from '.'; import { RedisArgument, ArrayReply, TuplesReply, BlobStringReply, SetReply, Command } from '../RESP/types';
// export const IS_READ_ONLY = true; export type CommandGetKeysAndFlagsRawReply = ArrayReply<TuplesReply<[
key: BlobStringReply,
flags: SetReply<BlobStringReply>
]>>;
// export function transformArguments(args: Array<RedisCommandArgument>): RedisCommandArguments { export default {
// return ['COMMAND', 'GETKEYSANDFLAGS', ...args]; FIRST_KEY_INDEX: undefined,
// } IS_READ_ONLY: true,
transformArguments(args: Array<RedisArgument>) {
// type KeysAndFlagsRawReply = Array<[ return ['COMMAND', 'GETKEYSANDFLAGS', ...args];
// RedisCommandArgument, },
// RedisCommandArguments transformReply(reply: CommandGetKeysAndFlagsRawReply) {
// ]>; return reply.map(([key, flags]) => ({
key,
// type KeysAndFlagsReply = Array<{ flags
// key: RedisCommandArgument; }));
// flags: RedisCommandArguments; }
// }>; } as const satisfies Command;
// export function transformReply(reply: KeysAndFlagsRawReply): KeysAndFlagsReply {
// return reply.map(([key, flags]) => ({
// key,
// flags
// }));
// }

View File

@@ -9,7 +9,7 @@ export const MATH_FUNCTION = {
engine: 'LUA', engine: 'LUA',
code: code:
`#!LUA name=math `#!LUA name=math
redis.register_function{ redis.register_function {
function_name = "square", function_name = "square",
callback = function(keys, args) return args[1] * args[1] end, callback = function(keys, args) return args[1] * args[1] end,
flags = { "no-writes" } flags = { "no-writes" }

View File

@@ -18,7 +18,9 @@ describe('MEMORY STATS', () => {
assert.equal(typeof memoryStats['replication.backlog'], 'number'); assert.equal(typeof memoryStats['replication.backlog'], 'number');
assert.equal(typeof memoryStats['clients.slaves'], 'number'); assert.equal(typeof memoryStats['clients.slaves'], 'number');
assert.equal(typeof memoryStats['clients.normal'], 'number'); assert.equal(typeof memoryStats['clients.normal'], 'number');
assert.equal(typeof memoryStats['cluster.links'], 'number'); if (testUtils.isVersionGreaterThan([7])) {
assert.equal(typeof memoryStats['cluster.links'], 'number');
}
assert.equal(typeof memoryStats['aof.buffer'], 'number'); assert.equal(typeof memoryStats['aof.buffer'], 'number');
assert.equal(typeof memoryStats['lua.caches'], 'number'); assert.equal(typeof memoryStats['lua.caches'], 'number');
assert.equal(typeof memoryStats['functions.caches'], 'number'); assert.equal(typeof memoryStats['functions.caches'], 'number');

View File

@@ -7,6 +7,7 @@ export type MemoryStatsReply = TuplesToMapReply<[
[BlobStringReply<'replication.backlog'>, NumberReply], [BlobStringReply<'replication.backlog'>, NumberReply],
[BlobStringReply<'clients.slaves'>, NumberReply], [BlobStringReply<'clients.slaves'>, NumberReply],
[BlobStringReply<'clients.normal'>, NumberReply], [BlobStringReply<'clients.normal'>, NumberReply],
/** added in 7.0 */
[BlobStringReply<'cluster.links'>, NumberReply], [BlobStringReply<'cluster.links'>, NumberReply],
[BlobStringReply<'aof.buffer'>, NumberReply], [BlobStringReply<'aof.buffer'>, NumberReply],
[BlobStringReply<'lua.caches'>, NumberReply], [BlobStringReply<'lua.caches'>, NumberReply],

View File

@@ -15,7 +15,11 @@ describe('XINFO CONSUMERS', () => {
client.xGroupCreate('key', 'group', '$', { client.xGroupCreate('key', 'group', '$', {
MKSTREAM: true MKSTREAM: true
}), }),
client.xGroupCreateConsumer('key', 'group', 'consumer'), // using `XREADGROUP` and not `XGROUP CREATECONSUMER` because the latter was introduced in Redis 6.2
client.xReadGroup('group', 'consumer', {
key: 'key',
id: '0-0'
}),
client.xInfoConsumers('key', 'group') client.xInfoConsumers('key', 'group')
]); ]);

View File

@@ -25,8 +25,10 @@ describe('XINFO GROUPS', () => {
consumers: 0, consumers: 0,
pending: 0, pending: 0,
'last-delivered-id': '0-0', 'last-delivered-id': '0-0',
'entries-read': null, ...testUtils.isVersionGreaterThan([7, 0]) && {
lag: 0 'entries-read': null,
lag: 0
}
}] }]
); );
}, { }, {

View File

@@ -23,9 +23,11 @@ describe('XINFO STREAM', () => {
'radix-tree-keys': 0, 'radix-tree-keys': 0,
'radix-tree-nodes': 1, 'radix-tree-nodes': 1,
'last-generated-id': '0-0', 'last-generated-id': '0-0',
'max-deleted-entry-id': '0-0', ...testUtils.isVersionGreaterThan([7, 0]) && {
'entries-added': 0, 'max-deleted-entry-id': '0-0',
'recorded-first-entry-id': '0-0', 'entries-added': 0,
'recorded-first-entry-id': '0-0',
},
groups: 1, groups: 1,
'first-entry': null, 'first-entry': null,
'last-entry': null 'last-entry': null

View File

@@ -1,26 +1,16 @@
import { TuplesToMapReply, BlobStringReply, NumberReply, NullReply, Resp2Reply, Command, RespType, RESP_TYPES, RedisArgument } from '../RESP/types'; import { TuplesToMapReply, BlobStringReply, NumberReply, NullReply, Resp2Reply, Command, RespType, RESP_TYPES, RedisArgument } from '../RESP/types';
import { StreamMessageRawReply, transformStreamMessageReply } from './generic-transformers'; import { StreamMessageRawReply, transformStreamMessageReply } from './generic-transformers';
export type XInfoStreamRawReply = TuplesToMapReply<[
[BlobStringReply<'length'>, NumberReply],
[BlobStringReply<'radix-tree-keys'>, NumberReply],
[BlobStringReply<'radix-tree-nodes'>, NumberReply],
[BlobStringReply<'last-generated-id'>, BlobStringReply],
[BlobStringReply<'max-deleted-entry-id'>, BlobStringReply],
[BlobStringReply<'entries-added'>, NumberReply],
[BlobStringReply<'recorded-first-entry-id'>, BlobStringReply],
[BlobStringReply<'groups'>, NumberReply],
[BlobStringReply<'first-entry'>, StreamMessageRawReply | NullReply],
[BlobStringReply<'last-entry'>, StreamMessageRawReply | NullReply]
]>;
export type XInfoStreamReply = TuplesToMapReply<[ export type XInfoStreamReply = TuplesToMapReply<[
[BlobStringReply<'length'>, NumberReply], [BlobStringReply<'length'>, NumberReply],
[BlobStringReply<'radix-tree-keys'>, NumberReply], [BlobStringReply<'radix-tree-keys'>, NumberReply],
[BlobStringReply<'radix-tree-nodes'>, NumberReply], [BlobStringReply<'radix-tree-nodes'>, NumberReply],
[BlobStringReply<'last-generated-id'>, BlobStringReply], [BlobStringReply<'last-generated-id'>, BlobStringReply],
/** added in 7.2 */
[BlobStringReply<'max-deleted-entry-id'>, BlobStringReply], [BlobStringReply<'max-deleted-entry-id'>, BlobStringReply],
/** added in 7.2 */
[BlobStringReply<'entries-added'>, NumberReply], [BlobStringReply<'entries-added'>, NumberReply],
/** added in 7.2 */
[BlobStringReply<'recorded-first-entry-id'>, BlobStringReply], [BlobStringReply<'recorded-first-entry-id'>, BlobStringReply],
[BlobStringReply<'groups'>, NumberReply], [BlobStringReply<'groups'>, NumberReply],
[BlobStringReply<'first-entry'>, ReturnType<typeof transformStreamMessageReply> | NullReply], [BlobStringReply<'first-entry'>, ReturnType<typeof transformStreamMessageReply> | NullReply],
@@ -34,22 +24,27 @@ export default {
return ['XINFO', 'STREAM', key]; return ['XINFO', 'STREAM', key];
}, },
transformReply: { transformReply: {
2(reply: Resp2Reply<XInfoStreamRawReply>) { // TODO: is there a "type safe" way to do it?
return { 2(reply: any) {
length: reply[1], const parsedReply: Partial<XInfoStreamReply['DEFAULT']> = {};
'radix-tree-keys': reply[3],
'radix-tree-nodes': reply[5], for (let i = 0; i < reply.length; i += 2) {
'last-generated-id': reply[7], switch (reply[i]) {
'max-deleted-entry-id': reply[9], case 'first-entry':
'entries-added': reply[11], case 'last-entry':
'recorded-first-entry-id': reply[13], parsedReply[reply[i] as ('first-entry' | 'last-entry')] = transformEntry(reply[i + 1]) as any;
groups: reply[15], break;
'first-entry': transformEntry(reply[17]),
'last-entry': transformEntry(reply[19]) default:
}; parsedReply[reply[i] as keyof typeof parsedReply] = reply[i + 1];
break;
}
}
return parsedReply as XInfoStreamReply['DEFAULT'];
}, },
3(reply: any) { // TODO: is there a "type safe" way to do it? 3(reply: any) {
if (reply instanceof Map) { if (reply instanceof Map) {
reply.set( reply.set(
'first-entry', 'first-entry',
transformEntry(reply.get('first-entry')) transformEntry(reply.get('first-entry'))

View File

@@ -41,11 +41,10 @@ describe('XPENDING RANGE', () => {
}); });
testUtils.testAll('xPendingRange', async client => { testUtils.testAll('xPendingRange', async client => {
const [, , id, , reply] = await Promise.all([ const [, , id, reply] = await Promise.all([
client.xGroupCreate('key', 'group', '$', { client.xGroupCreate('key', 'group', '$', {
MKSTREAM: true MKSTREAM: true
}), }),
client.xGroupCreateConsumer('key', 'group', 'consumer'),
client.xAdd('key', '*', { field: 'value' }), client.xAdd('key', '*', { field: 'value' }),
client.xReadGroup('group', 'consumer', { client.xReadGroup('group', 'consumer', {
key: 'key', key: 'key',

View File

@@ -66,6 +66,12 @@ import CLUSTER_SAVECONFIG from './CLUSTER_SAVECONFIG';
import CLUSTER_SET_CONFIG_EPOCH from './CLUSTER_SET-CONFIG-EPOCH'; import CLUSTER_SET_CONFIG_EPOCH from './CLUSTER_SET-CONFIG-EPOCH';
import CLUSTER_SETSLOT from './CLUSTER_SETSLOT'; import CLUSTER_SETSLOT from './CLUSTER_SETSLOT';
import CLUSTER_SLOTS from './CLUSTER_SLOTS'; import CLUSTER_SLOTS from './CLUSTER_SLOTS';
import COMMAND_COUNT from './COMMAND_COUNT';
import COMMAND_GETKEYS from './COMMAND_GETKEYS';
import COMMAND_GETKEYSANDFLAGS from './COMMAND_GETKEYSANDFLAGS';
// import COMMAND_INFO from './COMMAND_INFO';
// import COMMAND_LIST from './COMMAND_LIST';
// import COMMAND from './COMMAND';
import CONFIG_GET from './CONFIG_GET'; import CONFIG_GET from './CONFIG_GET';
import CONFIG_RESETASTAT from './CONFIG_RESETSTAT'; import CONFIG_RESETASTAT from './CONFIG_RESETSTAT';
import CONFIG_REWRITE from './CONFIG_REWRITE'; import CONFIG_REWRITE from './CONFIG_REWRITE';
@@ -388,6 +394,12 @@ type CLUSTER_SAVECONFIG = typeof import('./CLUSTER_SAVECONFIG').default;
type CLUSTER_SET_CONFIG_EPOCH = typeof import('./CLUSTER_SET-CONFIG-EPOCH').default; type CLUSTER_SET_CONFIG_EPOCH = typeof import('./CLUSTER_SET-CONFIG-EPOCH').default;
type CLUSTER_SETSLOT = typeof import('./CLUSTER_SETSLOT').default; type CLUSTER_SETSLOT = typeof import('./CLUSTER_SETSLOT').default;
type CLUSTER_SLOTS = typeof import('./CLUSTER_SLOTS').default; type CLUSTER_SLOTS = typeof import('./CLUSTER_SLOTS').default;
type COMMAND_COUNT = typeof import('./COMMAND_COUNT').default;
type COMMAND_GETKEYS = typeof import('./COMMAND_GETKEYS').default;
type COMMAND_GETKEYSANDFLAGS = typeof import('./COMMAND_GETKEYSANDFLAGS').default;
// type COMMAND_INFO = typeof import('./COMMAND_INFO').default;
// type COMMAND_LIST = typeof import('./COMMAND_LIST').default;
// type COMMAND = typeof import('./COMMAND').default;
type CONFIG_GET = typeof import('./CONFIG_GET').default; type CONFIG_GET = typeof import('./CONFIG_GET').default;
type CONFIG_RESETASTAT = typeof import('./CONFIG_RESETSTAT').default; type CONFIG_RESETASTAT = typeof import('./CONFIG_RESETSTAT').default;
type CONFIG_REWRITE = typeof import('./CONFIG_REWRITE').default; type CONFIG_REWRITE = typeof import('./CONFIG_REWRITE').default;
@@ -778,6 +790,18 @@ type Commands = {
clusterSetSlot: CLUSTER_SETSLOT; clusterSetSlot: CLUSTER_SETSLOT;
CLUSTER_SLOTS: CLUSTER_SLOTS; CLUSTER_SLOTS: CLUSTER_SLOTS;
clusterSlots: CLUSTER_SLOTS; clusterSlots: CLUSTER_SLOTS;
COMMAND_COUNT: COMMAND_COUNT;
commandCount: COMMAND_COUNT;
COMMAND_GETKEYS: COMMAND_GETKEYS;
commandGetKeys: COMMAND_GETKEYS;
COMMAND_GETKEYSANDFLAGS: COMMAND_GETKEYSANDFLAGS;
commandGetKeysAndFlags: COMMAND_GETKEYSANDFLAGS;
// COMMAND_INFO: COMMAND_INFO;
// commandInfo: COMMAND_INFO;
// COMMAND_LIST: COMMAND_LIST;
// commandList: COMMAND_LIST;
// COMMAND: COMMAND;
// command: COMMAND;
CONFIG_GET: CONFIG_GET; CONFIG_GET: CONFIG_GET;
configGet: CONFIG_GET; configGet: CONFIG_GET;
CONFIG_RESETASTAT: CONFIG_RESETASTAT; CONFIG_RESETASTAT: CONFIG_RESETASTAT;
@@ -1423,6 +1447,18 @@ export default {
clusterSetSlot: CLUSTER_SETSLOT, clusterSetSlot: CLUSTER_SETSLOT,
CLUSTER_SLOTS, CLUSTER_SLOTS,
clusterSlots: CLUSTER_SLOTS, clusterSlots: CLUSTER_SLOTS,
COMMAND_COUNT,
commandCount: COMMAND_COUNT,
COMMAND_GETKEYS,
commandGetKeys: COMMAND_GETKEYS,
COMMAND_GETKEYSANDFLAGS,
commandGetKeysAndFlags: COMMAND_GETKEYSANDFLAGS,
// COMMAND_INFO,
// commandInfo: COMMAND_INFO,
// COMMAND_LIST,
// commandList: COMMAND_LIST,
// COMMAND,
// command: COMMAND,
CONFIG_GET, CONFIG_GET,
configGet: CONFIG_GET, configGet: CONFIG_GET,
CONFIG_RESETASTAT, CONFIG_RESETASTAT,