1
0
mirror of https://github.com/redis/node-redis.git synced 2025-08-07 13:22:56 +03:00

some commands

This commit is contained in:
Leibale
2023-05-09 14:04:26 +03:00
parent a6c0d1dbb3
commit d59254e497
21 changed files with 295 additions and 235 deletions

View File

@@ -85,7 +85,10 @@ Some command arguments/replies have changed to align more closely to data types
- `HRANDFIELD_COUNT_WITHVALUES`: `Record<BlobString, BlobString>` -> `Array<{ field: BlobString; value: BlobString; }>` (it can return duplicates). - `HRANDFIELD_COUNT_WITHVALUES`: `Record<BlobString, BlobString>` -> `Array<{ field: BlobString; value: BlobString; }>` (it can return duplicates).
- `SCAN`, `HSCAN`, `SSCAN`, and `ZSCAN`: cursor type is `string` instead of `number`? - `SCAN`, `HSCAN`, `SSCAN`, and `ZSCAN`: cursor type is `string` instead of `number`?
- `HSETNX`: `boolean` -> `number` [^boolean-to-number] - `HSETNX`: `boolean` -> `number` [^boolean-to-number]
- `ZINTER`: instead of `client.ZINTER('11, { WEIGHTS: [1] })` use `client.ZINTER({ key: '1', weight: 1 }])` - `ZINTER`: instead of `client.ZINTER('key', { WEIGHTS: [1] })` use `client.ZINTER({ key: 'key', weight: 1 }])`
- `ZINTER_WITHSCORES`: instead of `client.ZINTER_WITHSCORES('key', { WEIGHTS: [1] })` use `client.ZINTER_WITHSCORES({ key: 'key', weight: 1 }])`
- `ZUNION`: instead of `client.ZUNION('key', { WEIGHTS: [1] })` use `client.ZUNION({ key: 'key', weight: 1 }])`
- `ZUNION_WITHSCORES`: instead of `client.ZUNION_WITHSCORES('key', { WEIGHTS: [1] })` use `client.ZUNION_WITHSCORES({ key: 'key', weight: 1 }])`
- `SETNX`: `boolean` -> `number` [^boolean-to-number] - `SETNX`: `boolean` -> `number` [^boolean-to-number]
- `COPY`: `destinationDb` -> `DB`, `replace` -> `REPLACE`, `boolean` -> `number` [^boolean-to-number] - `COPY`: `destinationDb` -> `DB`, `replace` -> `REPLACE`, `boolean` -> `number` [^boolean-to-number]
- `EXPIRE`: `boolean` -> `number` [^boolean-to-number] - `EXPIRE`: `boolean` -> `number` [^boolean-to-number]
@@ -104,6 +107,7 @@ Some command arguments/replies have changed to align more closely to data types
- `GEOSEARCH_WITH`/`GEORADIUS_WITH`: `GeoReplyWith` -> `GEO_REPLY_WITH` [^enum-to-constants] - `GEOSEARCH_WITH`/`GEORADIUS_WITH`: `GeoReplyWith` -> `GEO_REPLY_WITH` [^enum-to-constants]
- `GEORADIUSSTORE` -> `GEORADIUS_STORE` - `GEORADIUSSTORE` -> `GEORADIUS_STORE`
- `GEORADIUSBYMEMBERSTORE` -> `GEORADIUSBYMEMBER_STORE` - `GEORADIUSBYMEMBERSTORE` -> `GEORADIUSBYMEMBER_STORE`
- `XACK`: `boolean` -> `number` [^boolean-to-number]
[^enum-to-constants]: TODO [^enum-to-constants]: TODO

View File

@@ -2,7 +2,7 @@ import { strict as assert } from 'assert';
import testUtils, { GLOBAL } from '../test-utils'; import testUtils, { GLOBAL } from '../test-utils';
import BITPOS from './BITPOS'; import BITPOS from './BITPOS';
describe.only('BITPOS', () => { describe('BITPOS', () => {
describe('transformArguments', () => { describe('transformArguments', () => {
it('simple', () => { it('simple', () => {
assert.deepEqual( assert.deepEqual(

View File

@@ -1,35 +1,35 @@
import { strict as assert } from 'assert'; import { strict as assert } from 'assert';
import testUtils, { GLOBAL } from '../test-utils'; import testUtils, { GLOBAL } from '../test-utils';
import { RedisFlushModes, transformArguments } from './FLUSHALL'; import FLUSHALL, { REDIS_FLUSH_MODES } from './FLUSHALL';
describe('FLUSHALL', () => { describe('FLUSHALL', () => {
describe('transformArguments', () => { describe('transformArguments', () => {
it('default', () => { it('default', () => {
assert.deepEqual( assert.deepEqual(
transformArguments(), FLUSHALL.transformArguments(),
['FLUSHALL'] ['FLUSHALL']
); );
});
it('ASYNC', () => {
assert.deepEqual(
transformArguments(RedisFlushModes.ASYNC),
['FLUSHALL', 'ASYNC']
);
});
it('SYNC', () => {
assert.deepEqual(
transformArguments(RedisFlushModes.SYNC),
['FLUSHALL', 'SYNC']
);
});
}); });
testUtils.testWithClient('client.flushAll', async client => { it('ASYNC', () => {
assert.equal( assert.deepEqual(
await client.flushAll(), FLUSHALL.transformArguments(REDIS_FLUSH_MODES.ASYNC),
'OK' ['FLUSHALL', 'ASYNC']
); );
}, GLOBAL.SERVERS.OPEN); });
it('SYNC', () => {
assert.deepEqual(
FLUSHALL.transformArguments(REDIS_FLUSH_MODES.SYNC),
['FLUSHALL', 'SYNC']
);
});
});
testUtils.testWithClient('client.flushAll', async client => {
assert.equal(
await client.flushAll(),
'OK'
);
}, GLOBAL.SERVERS.OPEN);
}); });

View File

@@ -8,6 +8,8 @@ export const REDIS_FLUSH_MODES = {
export type RedisFlushModes = typeof REDIS_FLUSH_MODES[keyof typeof REDIS_FLUSH_MODES]; export type RedisFlushModes = typeof REDIS_FLUSH_MODES[keyof typeof REDIS_FLUSH_MODES];
export default { export default {
FIRST_KEY_INDEX: undefined,
IS_READ_ONLY: false,
transformArguments(mode?: RedisFlushModes) { transformArguments(mode?: RedisFlushModes) {
const args = ['FLUSHALL']; const args = ['FLUSHALL'];

View File

@@ -1,36 +1,36 @@
import { strict as assert } from 'assert'; import { strict as assert } from 'assert';
import testUtils, { GLOBAL } from '../test-utils'; import testUtils, { GLOBAL } from '../test-utils';
import { RedisFlushModes } from './FLUSHALL'; import FLUSHDB from './FLUSHDB';
import { transformArguments } from './FLUSHDB'; import { REDIS_FLUSH_MODES } from './FLUSHALL';
describe('FLUSHDB', () => { describe('FLUSHDB', () => {
describe('transformArguments', () => { describe('transformArguments', () => {
it('default', () => { it('default', () => {
assert.deepEqual( assert.deepEqual(
transformArguments(), FLUSHDB.transformArguments(),
['FLUSHDB'] ['FLUSHDB']
); );
});
it('ASYNC', () => {
assert.deepEqual(
transformArguments(RedisFlushModes.ASYNC),
['FLUSHDB', 'ASYNC']
);
});
it('SYNC', () => {
assert.deepEqual(
transformArguments(RedisFlushModes.SYNC),
['FLUSHDB', 'SYNC']
);
});
}); });
testUtils.testWithClient('client.flushDb', async client => { it('ASYNC', () => {
assert.equal( assert.deepEqual(
await client.flushDb(), FLUSHDB.transformArguments(REDIS_FLUSH_MODES.ASYNC),
'OK' ['FLUSHDB', 'ASYNC']
); );
}, GLOBAL.SERVERS.OPEN); });
it('SYNC', () => {
assert.deepEqual(
FLUSHDB.transformArguments(REDIS_FLUSH_MODES.SYNC),
['FLUSHDB', 'SYNC']
);
});
});
testUtils.testWithClient('client.flushDb', async client => {
assert.equal(
await client.flushDb(),
'OK'
);
}, GLOBAL.SERVERS.OPEN);
}); });

View File

@@ -2,6 +2,8 @@ import { SimpleStringReply, Command } from '../RESP/types';
import { RedisFlushModes } from './FLUSHALL'; import { RedisFlushModes } from './FLUSHALL';
export default { export default {
FIRST_KEY_INDEX: undefined,
IS_READ_ONLY: false,
transformArguments(mode?: RedisFlushModes) { transformArguments(mode?: RedisFlushModes) {
const args = ['FLUSHDB']; const args = ['FLUSHDB'];

View File

@@ -43,10 +43,6 @@ export function pushGeoSearchArguments(
args.push('BYBOX', by.width.toString(), by.height.toString(), by.unit); args.push('BYBOX', by.width.toString(), by.height.toString(), by.unit);
} }
if (options?.SORT) {
args.push(options.SORT);
}
pushGeoSearchOptions(args, options); pushGeoSearchOptions(args, options);
return args; return args;

View File

@@ -13,7 +13,7 @@ describe('HEXISTS', () => {
testUtils.testAll('hExists', async client => { testUtils.testAll('hExists', async client => {
assert.equal( assert.equal(
await client.hExists('key', 'field'), await client.hExists('key', 'field'),
false 0
); );
}, { }, {
client: GLOBAL.SERVERS.OPEN, client: GLOBAL.SERVERS.OPEN,

View File

@@ -13,7 +13,7 @@ describe('MOVE', () => {
testUtils.testAll('move', async client => { testUtils.testAll('move', async client => {
assert.equal( assert.equal(
await client.move('key', 1), await client.move('key', 1),
1 0
); );
}, { }, {
client: GLOBAL.SERVERS.OPEN, client: GLOBAL.SERVERS.OPEN,

View File

@@ -1,4 +1,4 @@
import { RedisArgument, BlobStringReply, Command } from '../RESP/types'; import { RedisArgument, BlobStringReply, Command, CommandArguments } from '../RESP/types';
export interface XAddOptions { export interface XAddOptions {
TRIM?: { TRIM?: {
@@ -9,6 +9,37 @@ export interface XAddOptions {
}; };
} }
export function pushXAddArguments(
args: CommandArguments,
id: RedisArgument,
message: Record<string, RedisArgument>,
options?: XAddOptions
) {
if (options?.TRIM) {
if (options.TRIM.strategy) {
args.push(options.TRIM.strategy);
}
if (options.TRIM.strategyModifier) {
args.push(options.TRIM.strategyModifier);
}
args.push(options.TRIM.threshold.toString());
if (options.TRIM.limit) {
args.push('LIMIT', options.TRIM.limit.toString());
}
}
args.push(id);
for (const [key, value] of Object.entries(message)) {
args.push(key, value);
}
return args;
}
export default { export default {
FIRST_KEY_INDEX: 1, FIRST_KEY_INDEX: 1,
IS_READ_ONLY: false, IS_READ_ONLY: false,
@@ -18,31 +49,7 @@ export default {
message: Record<string, RedisArgument>, message: Record<string, RedisArgument>,
options?: XAddOptions options?: XAddOptions
) { ) {
const args = ['XADD', key]; return pushXAddArguments(['XADD', key], id, message, options);
if (options?.TRIM) {
if (options.TRIM.strategy) {
args.push(options.TRIM.strategy);
}
if (options.TRIM.strategyModifier) {
args.push(options.TRIM.strategyModifier);
}
args.push(options.TRIM.threshold.toString());
if (options.TRIM.limit) {
args.push('LIMIT', options.TRIM.limit.toString());
}
}
args.push(id);
for (const [key, value] of Object.entries(message)) {
args.push(key, value);
}
return args;
}, },
transformReply: undefined as unknown as () => BlobStringReply transformReply: undefined as unknown as () => BlobStringReply
} as const satisfies Command; } as const satisfies Command;

View File

@@ -9,7 +9,7 @@ describe('XADD NOMKSTREAM', () => {
XADD_NOMKSTREAM.transformArguments('key', '*', { XADD_NOMKSTREAM.transformArguments('key', '*', {
field: 'value' field: 'value'
}), }),
['XADD', 'key', '*', 'field', 'value', 'NOMKSTREAM'] ['XADD', 'key', 'NOMKSTREAM', '*', 'field', 'value']
); );
}); });
@@ -19,7 +19,7 @@ describe('XADD NOMKSTREAM', () => {
'1': 'I', '1': 'I',
'2': 'II' '2': 'II'
}), }),
['XADD', 'key', '*', '1', 'I', '2', 'II', 'NOMKSTREAM'] ['XADD', 'key', 'NOMKSTREAM', '*', '1', 'I', '2', 'II']
); );
}); });
@@ -32,7 +32,7 @@ describe('XADD NOMKSTREAM', () => {
threshold: 1000 threshold: 1000
} }
}), }),
['XADD', 'key', '1000', '*', 'field', 'value', 'NOMKSTREAM'] ['XADD', 'key', 'NOMKSTREAM', '1000', '*', 'field', 'value']
); );
}); });
@@ -46,7 +46,7 @@ describe('XADD NOMKSTREAM', () => {
threshold: 1000 threshold: 1000
} }
}), }),
['XADD', 'key', 'MAXLEN', '1000', '*', 'field', 'value', 'NOMKSTREAM'] ['XADD', 'key', 'NOMKSTREAM', 'MAXLEN', '1000', '*', 'field', 'value']
); );
}); });
@@ -60,7 +60,7 @@ describe('XADD NOMKSTREAM', () => {
threshold: 1000 threshold: 1000
} }
}), }),
['XADD', 'key', '=', '1000', '*', 'field', 'value', 'NOMKSTREAM'] ['XADD', 'key', 'NOMKSTREAM', '=', '1000', '*', 'field', 'value']
); );
}); });
@@ -74,17 +74,17 @@ describe('XADD NOMKSTREAM', () => {
limit: 1 limit: 1
} }
}), }),
['XADD', 'key', '1000', 'LIMIT', '1', '*', 'field', 'value', 'NOMKSTREAM'] ['XADD', 'key', 'NOMKSTREAM', '1000', 'LIMIT', '1', '*', 'field', 'value']
); );
}); });
}); });
testUtils.testAll('xAddNoMkStream', async client => { testUtils.testAll('xAddNoMkStream', async client => {
assert.equal( assert.equal(
typeof await client.xAddNoMkStream('key', '*', { await client.xAddNoMkStream('key', '*', {
field: 'value' field: 'value'
}), }),
'string' null
); );
}, { }, {
client: GLOBAL.SERVERS.OPEN, client: GLOBAL.SERVERS.OPEN,

View File

@@ -1,13 +1,16 @@
import { BlobStringReply, NullReply, Command } from '../RESP/types'; import { RedisArgument, BlobStringReply, NullReply, Command } from '../RESP/types';
import XADD from './XADD'; import { XAddOptions, pushXAddArguments } from './XADD';
export default { export default {
FIRST_KEY_INDEX: XADD.FIRST_KEY_INDEX, FIRST_KEY_INDEX: 1,
IS_READ_ONLY: XADD.IS_READ_ONLY, IS_READ_ONLY: false,
transformArguments(...args: Parameters<typeof XADD.transformArguments>) { transformArguments(
const redisArgs = XADD.transformArguments(...args); key: RedisArgument,
redisArgs.push('NOMKSTREAM'); id: RedisArgument,
return redisArgs; message: Record<string, RedisArgument>,
options?: XAddOptions
) {
return pushXAddArguments(['XADD', key, 'NOMKSTREAM'], id, message, options);
}, },
transformReply: undefined as unknown as () => BlobStringReply | NullReply transformReply: undefined as unknown as () => BlobStringReply | NullReply
} as const satisfies Command; } as const satisfies Command;

View File

@@ -1,5 +1,5 @@
import { RedisArgument, ArrayReply, BlobStringReply, Command } from '../RESP/types'; import { RedisArgument, ArrayReply, BlobStringReply, Command } from '../RESP/types';
import { transformDoubleArgument } from './generic-transformers'; import { ZKeys, pushZKeysArguments } from './generic-transformers';
export type ZInterKeyAndWeight = { export type ZInterKeyAndWeight = {
key: RedisArgument; key: RedisArgument;
@@ -14,38 +14,10 @@ export interface ZInterOptions {
export function pushZInterArguments( export function pushZInterArguments(
args: Array<RedisArgument>, args: Array<RedisArgument>,
keys: ZInterKeys<RedisArgument> | ZInterKeys<ZInterKeyAndWeight>, keys: ZKeys,
options?: ZInterOptions options?: ZInterOptions
) { ) {
if (Array.isArray(keys)) { pushZKeysArguments(args, keys);
args.push(keys.length.toString());
if (keys.length) {
if (isPlainKeys(keys)) {
args = args.concat(keys);
} else {
const start = args.length;
args[start + keys.length] = 'WEIGHTS';
for (let i = 0; i < keys.length; i++) {
const index = start + i;
args[index] = keys[i].key;
args[index + 1 + keys.length] = transformDoubleArgument(keys[i].weight);
}
}
}
} else {
args.push('1');
if (isPlainKey(keys)) {
args.push(keys);
} else {
args.push(
keys.key,
'WEIGHTS',
transformDoubleArgument(keys.weight)
);
}
}
if (options?.AGGREGATE) { if (options?.AGGREGATE) {
args.push('AGGREGATE', options.AGGREGATE); args.push('AGGREGATE', options.AGGREGATE);
@@ -54,14 +26,6 @@ export function pushZInterArguments(
return args; return args;
} }
function isPlainKey(key: RedisArgument | ZInterKeyAndWeight): key is RedisArgument {
return typeof key === 'string' || Buffer.isBuffer(key);
}
function isPlainKeys(keys: Array<RedisArgument> | Array<ZInterKeyAndWeight>): keys is Array<RedisArgument> {
return isPlainKey(keys[0]);
}
export default { export default {
FIRST_KEY_INDEX: 2, FIRST_KEY_INDEX: 2,
IS_READ_ONLY: true, IS_READ_ONLY: true,

View File

@@ -13,22 +13,36 @@ describe('ZUNION', () => {
); );
}); });
it('keys (array)', () => { it('keys (Array<string>)', () => {
assert.deepEqual( assert.deepEqual(
ZUNION.transformArguments(['1', '2']), ZUNION.transformArguments(['1', '2']),
['ZUNION', '2', '1', '2'] ['ZUNION', '2', '1', '2']
); );
}); });
it('with WEIGHTS', () => { it('key & weight', () => {
assert.deepEqual( assert.deepEqual(
ZUNION.transformArguments('key', { ZUNION.transformArguments({
WEIGHTS: [1] key: 'key',
weight: 1
}), }),
['ZUNION', '1', 'key', 'WEIGHTS', '1'] ['ZUNION', '1', 'key', 'WEIGHTS', '1']
); );
}); });
it('keys & weights', () => {
assert.deepEqual(
ZUNION.transformArguments([{
key: 'a',
weight: 1
}, {
key: 'b',
weight: 2
}]),
['ZUNION', '2', 'a', 'b', 'WEIGHTS', '1', '2']
);
});
it('with AGGREGATE', () => { it('with AGGREGATE', () => {
assert.deepEqual( assert.deepEqual(
ZUNION.transformArguments('key', { ZUNION.transformArguments('key', {

View File

@@ -1,8 +1,7 @@
import { ArrayReply, BlobStringReply, Command } from '../RESP/types'; import { ArrayReply, BlobStringReply, Command } from '../RESP/types';
import { RedisVariadicArgument, pushVariadicArgument } from './generic-transformers'; import { ZKeys, pushZKeysArguments } from './generic-transformers';
export interface ZUnionOptions { export interface ZUnionOptions {
WEIGHTS?: Array<number>;
AGGREGATE?: 'SUM' | 'MIN' | 'MAX'; AGGREGATE?: 'SUM' | 'MIN' | 'MAX';
} }
@@ -10,14 +9,10 @@ export default {
FIRST_KEY_INDEX: 2, FIRST_KEY_INDEX: 2,
IS_READ_ONLY: true, IS_READ_ONLY: true,
transformArguments( transformArguments(
keys: RedisVariadicArgument, keys: ZKeys,
options?: ZUnionOptions options?: ZUnionOptions
) { ) {
const args = pushVariadicArgument(['ZUNION'], keys); const args = pushZKeysArguments(['ZUNION'], keys);
if (options?.WEIGHTS) {
args.push('WEIGHTS', ...options.WEIGHTS.map(weight => weight.toString()));
}
if (options?.AGGREGATE) { if (options?.AGGREGATE) {
args.push('AGGREGATE', options.AGGREGATE); args.push('AGGREGATE', options.AGGREGATE);

View File

@@ -49,7 +49,7 @@ describe('ZUNIONSTORE', () => {
testUtils.testAll('zUnionStore', async client => { testUtils.testAll('zUnionStore', async client => {
assert.equal( assert.equal(
await client.zUnionStore('destination', 'key'), await client.zUnionStore('{tag}destination', '{tag}key'),
0 0
); );
}, { }, {

View File

@@ -1,8 +1,7 @@
import { RedisArgument, NumberReply, Command, } from '../RESP/types'; import { RedisArgument, NumberReply, Command, } from '../RESP/types';
import { RedisVariadicArgument, pushVariadicArgument } from './generic-transformers'; import { ZKeys, pushZKeysArguments } from './generic-transformers';
export interface ZUnionOptions { export interface ZUnionOptions {
WEIGHTS?: Array<number>;
AGGREGATE?: 'SUM' | 'MIN' | 'MAX'; AGGREGATE?: 'SUM' | 'MIN' | 'MAX';
} }
@@ -11,14 +10,10 @@ export default {
IS_READ_ONLY: false, IS_READ_ONLY: false,
transformArguments( transformArguments(
destination: RedisArgument, destination: RedisArgument,
keys: RedisVariadicArgument, keys: ZKeys,
options?: ZUnionOptions options?: ZUnionOptions
) { ) {
const args = pushVariadicArgument(['ZUNIONSTORE', destination], keys); const args = pushZKeysArguments(['ZUNIONSTORE', destination], keys);
if (options?.WEIGHTS) {
args.push('WEIGHTS', ...options.WEIGHTS.map(weight => weight.toString()));
}
if (options?.AGGREGATE) { if (options?.AGGREGATE) {
args.push('AGGREGATE', options.AGGREGATE); args.push('AGGREGATE', options.AGGREGATE);

View File

@@ -1,48 +1,65 @@
// import { strict as assert } from 'assert'; import { strict as assert } from 'assert';
// import testUtils, { GLOBAL } from '../test-utils'; import testUtils, { GLOBAL } from '../test-utils';
// import { transformArguments } from './ZUNION_WITHSCORES'; import ZUNION_WITHSCORES from './ZUNION_WITHSCORES';
// describe('ZUNION WITHSCORES', () => { describe('ZUNION WITHSCORES', () => {
// testUtils.isVersionGreaterThanHook([6, 2]); testUtils.isVersionGreaterThanHook([6, 2]);
// describe('transformArguments', () => { describe('transformArguments', () => {
// it('key (string)', () => { it('key (string)', () => {
// assert.deepEqual( assert.deepEqual(
// transformArguments('key'), ZUNION_WITHSCORES.transformArguments('key'),
// ['ZUNION', '1', 'key', 'WITHSCORES'] ['ZUNION', '1', 'key']
// ); );
// }); });
// it('keys (array)', () => { it('keys (Array<string>)', () => {
// assert.deepEqual( assert.deepEqual(
// transformArguments(['1', '2']), ZUNION_WITHSCORES.transformArguments(['1', '2']),
// ['ZUNION', '2', '1', '2', 'WITHSCORES'] ['ZUNION', '2', '1', '2']
// ); );
// }); });
// it('with WEIGHTS', () => { it('key & weight', () => {
// assert.deepEqual( assert.deepEqual(
// transformArguments('key', { ZUNION_WITHSCORES.transformArguments({
// WEIGHTS: [1] key: 'key',
// }), weight: 1
// ['ZUNION', '1', 'key', 'WEIGHTS', '1', 'WITHSCORES'] }),
// ); ['ZUNION', '1', 'key', 'WEIGHTS', '1']
// }); );
});
// it('with AGGREGATE', () => { it('keys & weights', () => {
// assert.deepEqual( assert.deepEqual(
// transformArguments('key', { ZUNION_WITHSCORES.transformArguments([{
// AGGREGATE: 'SUM' key: 'a',
// }), weight: 1
// ['ZUNION', '1', 'key', 'AGGREGATE', 'SUM', 'WITHSCORES'] }, {
// ); key: 'b',
// }); weight: 2
// }); }]),
['ZUNION', '2', 'a', 'b', 'WEIGHTS', '1', '2']
);
});
// testUtils.testWithClient('client.zUnionWithScores', async client => { it('with AGGREGATE', () => {
// assert.deepEqual( assert.deepEqual(
// await client.zUnionWithScores('key'), ZUNION_WITHSCORES.transformArguments('key', {
// [] AGGREGATE: 'SUM'
// ); }),
// }, GLOBAL.SERVERS.OPEN); ['ZUNION', '1', 'key', 'AGGREGATE', 'SUM', 'WITHSCORES']
// }); );
});
});
testUtils.testAll('zUnionWithScores', async client => {
assert.deepEqual(
await client.zUnionWithScores('key'),
[]
);
}, {
client: GLOBAL.SERVERS.OPEN,
cluster: GLOBAL.CLUSTERS.OPEN
});
});

View File

@@ -1,13 +1,14 @@
// import { RedisCommandArguments } from '.'; import { Command } from '../RESP/types';
// import { transformArguments as transformZUnionArguments } from './ZUNION'; import ZUNION from './ZUNION';
import { transformSortedSetReply } from './generic-transformers';
// export { FIRST_KEY_INDEX, IS_READ_ONLY } from './ZUNION'; export default {
FIRST_KEY_INDEX: ZUNION.FIRST_KEY_INDEX,
// export function transformArguments(...args: Parameters<typeof transformZUnionArguments>): RedisCommandArguments { IS_READ_ONLY: ZUNION.IS_READ_ONLY,
// return [ transformArguments(...args: Parameters<typeof ZUNION['transformArguments']>) {
// ...transformZUnionArguments(...args), const redisArgs = ZUNION.transformArguments(...args);
// 'WITHSCORES' redisArgs.push('WITHSCORES');
// ]; return redisArgs;
// } },
transformReply: transformSortedSetReply
// export { transformSortedSetWithScoresReply as transformReply } from './generic-transformers'; } as const satisfies Command;

View File

@@ -432,3 +432,57 @@ export function transformRangeReply([start, end]: RawRangeReply): RangeReply {
end end
}; };
} }
export type ZKeyAndWeight = {
key: RedisArgument;
weight: number;
};
export type ZVariadicKeys<T> = T | [T, ...Array<T>];
export type ZKeys = ZVariadicKeys<RedisArgument> | ZVariadicKeys<ZKeyAndWeight>;
export function pushZKeysArguments(
args: CommandArguments,
keys: ZKeys
) {
if (Array.isArray(keys)) {
args.push(keys.length.toString());
if (keys.length) {
if (isPlainKeys(keys)) {
args = args.concat(keys);
} else {
const start = args.length;
args[start + keys.length] = 'WEIGHTS';
for (let i = 0; i < keys.length; i++) {
const index = start + i;
args[index] = keys[i].key;
args[index + 1 + keys.length] = transformDoubleArgument(keys[i].weight);
}
}
}
} else {
args.push('1');
if (isPlainKey(keys)) {
args.push(keys);
} else {
args.push(
keys.key,
'WEIGHTS',
transformDoubleArgument(keys.weight)
);
}
}
return args;
}
function isPlainKey(key: RedisArgument | ZKeyAndWeight): key is RedisArgument {
return typeof key === 'string' || Buffer.isBuffer(key);
}
function isPlainKeys(keys: Array<RedisArgument> | Array<ZKeyAndWeight>): keys is Array<RedisArgument> {
return isPlainKey(keys[0]);
}

View File

@@ -68,7 +68,12 @@ import GETDEL from './GETDEL';
import GETEX from './GETEX'; import GETEX from './GETEX';
import GETRANGE from './GETRANGE'; import GETRANGE from './GETRANGE';
import GETSET from './GETSET'; import GETSET from './GETSET';
import EXISTS from './EXISTS';
import EXPIRE from './EXPIRE';
import EXPIREAT from './EXPIREAT';
import EXPIRETIME from './EXPIRETIME';
import FLUSHALL from './FLUSHALL'; import FLUSHALL from './FLUSHALL';
import FLUSHDB from './FLUSHDB';
import HDEL from './HDEL'; import HDEL from './HDEL';
import HEXISTS from './HEXISTS'; import HEXISTS from './HEXISTS';
import HGET from './HGET'; import HGET from './HGET';
@@ -119,10 +124,6 @@ import OBJECT_FREQ from './OBJECT_FREQ';
import OBJECT_IDLETIME from './OBJECT_IDLETIME'; import OBJECT_IDLETIME from './OBJECT_IDLETIME';
import OBJECT_REFCOUNT from './OBJECT_REFCOUNT'; import OBJECT_REFCOUNT from './OBJECT_REFCOUNT';
import PERSIST from './PERSIST'; import PERSIST from './PERSIST';
import EXISTS from './EXISTS';
import EXPIRE from './EXPIRE';
import EXPIREAT from './EXPIREAT';
import EXPIRETIME from './EXPIRETIME';
import PEXPIRE from './PEXPIRE'; import PEXPIRE from './PEXPIRE';
import PEXPIREAT from './PEXPIREAT'; import PEXPIREAT from './PEXPIREAT';
import PEXPIRETIME from './PEXPIRETIME'; import PEXPIRETIME from './PEXPIRETIME';
@@ -212,6 +213,7 @@ import ZREMRANGEBYRANK from './ZREMRANGEBYRANK';
import ZREVRANK from './ZREVRANK'; import ZREVRANK from './ZREVRANK';
import ZSCAN from './ZSCAN'; import ZSCAN from './ZSCAN';
import ZSCORE from './ZSCORE'; import ZSCORE from './ZSCORE';
import ZUNION_WITHSCORES from './ZUNION_WITHSCORES';
import ZUNION from './ZUNION'; import ZUNION from './ZUNION';
import ZUNIONSTORE from './ZUNIONSTORE'; import ZUNIONSTORE from './ZUNIONSTORE';
import { Command } from '../RESP/types'; import { Command } from '../RESP/types';
@@ -311,6 +313,18 @@ export default {
del: DEL, del: DEL,
DUMP, DUMP,
dump: DUMP, dump: DUMP,
EXISTS,
exists: EXISTS,
EXPIRE,
expire: EXPIRE,
EXPIREAT,
expireAt: EXPIREAT,
EXPIRETIME,
expireTime: EXPIRETIME,
FLUSHALL,
flushAll: FLUSHALL,
FLUSHDB,
flushDb: FLUSHDB,
GEOADD, GEOADD,
geoAdd: GEOADD, geoAdd: GEOADD,
GEODIST, GEODIST,
@@ -357,8 +371,6 @@ export default {
getRange: GETRANGE, getRange: GETRANGE,
GETSET, GETSET,
getSet: GETSET, getSet: GETSET,
FLUSHALL,
flushAll: FLUSHALL,
HDEL, HDEL,
hDel: HDEL, hDel: HDEL,
HEXISTS, HEXISTS,
@@ -457,14 +469,6 @@ export default {
objectRefCount: OBJECT_REFCOUNT, objectRefCount: OBJECT_REFCOUNT,
PERSIST, PERSIST,
persist: PERSIST, persist: PERSIST,
EXISTS,
exists: EXISTS,
EXPIRE,
expire: EXPIRE,
EXPIREAT,
expireAt: EXPIREAT,
EXPIRETIME,
expireTime: EXPIRETIME,
PEXPIRE, PEXPIRE,
pExpire: PEXPIRE, pExpire: PEXPIRE,
PEXPIREAT, PEXPIREAT,
@@ -646,6 +650,8 @@ export default {
zScan: ZSCAN, zScan: ZSCAN,
ZSCORE, ZSCORE,
zScore: ZSCORE, zScore: ZSCORE,
ZUNION_WITHSCORES,
zUnionWithScores: ZUNION_WITHSCORES,
ZUNION, ZUNION,
zUnion: ZUNION, zUnion: ZUNION,
ZUNIONSTORE, ZUNIONSTORE,