You've already forked node-redis
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:
@@ -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
|
||||||
|
|
||||||
|
@@ -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(
|
||||||
|
@@ -1,26 +1,26 @@
|
|||||||
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', () => {
|
it('ASYNC', () => {
|
||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
transformArguments(RedisFlushModes.ASYNC),
|
FLUSHALL.transformArguments(REDIS_FLUSH_MODES.ASYNC),
|
||||||
['FLUSHALL', 'ASYNC']
|
['FLUSHALL', 'ASYNC']
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('SYNC', () => {
|
it('SYNC', () => {
|
||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
transformArguments(RedisFlushModes.SYNC),
|
FLUSHALL.transformArguments(REDIS_FLUSH_MODES.SYNC),
|
||||||
['FLUSHALL', 'SYNC']
|
['FLUSHALL', 'SYNC']
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
@@ -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'];
|
||||||
|
|
||||||
|
@@ -1,27 +1,27 @@
|
|||||||
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', () => {
|
it('ASYNC', () => {
|
||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
transformArguments(RedisFlushModes.ASYNC),
|
FLUSHDB.transformArguments(REDIS_FLUSH_MODES.ASYNC),
|
||||||
['FLUSHDB', 'ASYNC']
|
['FLUSHDB', 'ASYNC']
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('SYNC', () => {
|
it('SYNC', () => {
|
||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
transformArguments(RedisFlushModes.SYNC),
|
FLUSHDB.transformArguments(REDIS_FLUSH_MODES.SYNC),
|
||||||
['FLUSHDB', 'SYNC']
|
['FLUSHDB', 'SYNC']
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
@@ -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'];
|
||||||
|
|
||||||
|
@@ -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;
|
||||||
|
@@ -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,
|
||||||
|
@@ -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,
|
||||||
|
@@ -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,17 +9,12 @@ export interface XAddOptions {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export default {
|
export function pushXAddArguments(
|
||||||
FIRST_KEY_INDEX: 1,
|
args: CommandArguments,
|
||||||
IS_READ_ONLY: false,
|
|
||||||
transformArguments(
|
|
||||||
key: RedisArgument,
|
|
||||||
id: RedisArgument,
|
id: RedisArgument,
|
||||||
message: Record<string, RedisArgument>,
|
message: Record<string, RedisArgument>,
|
||||||
options?: XAddOptions
|
options?: XAddOptions
|
||||||
) {
|
) {
|
||||||
const args = ['XADD', key];
|
|
||||||
|
|
||||||
if (options?.TRIM) {
|
if (options?.TRIM) {
|
||||||
if (options.TRIM.strategy) {
|
if (options.TRIM.strategy) {
|
||||||
args.push(options.TRIM.strategy);
|
args.push(options.TRIM.strategy);
|
||||||
@@ -43,6 +38,18 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return args;
|
return args;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
FIRST_KEY_INDEX: 1,
|
||||||
|
IS_READ_ONLY: false,
|
||||||
|
transformArguments(
|
||||||
|
key: RedisArgument,
|
||||||
|
id: RedisArgument,
|
||||||
|
message: Record<string, RedisArgument>,
|
||||||
|
options?: XAddOptions
|
||||||
|
) {
|
||||||
|
return pushXAddArguments(['XADD', key], id, message, options);
|
||||||
},
|
},
|
||||||
transformReply: undefined as unknown as () => BlobStringReply
|
transformReply: undefined as unknown as () => BlobStringReply
|
||||||
} as const satisfies Command;
|
} as const satisfies Command;
|
||||||
|
@@ -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,
|
||||||
|
@@ -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;
|
||||||
|
@@ -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,
|
||||||
|
@@ -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', {
|
||||||
|
@@ -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);
|
||||||
|
@@ -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
|
||||||
);
|
);
|
||||||
}, {
|
}, {
|
||||||
|
@@ -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);
|
||||||
|
@@ -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
|
||||||
|
});
|
||||||
|
});
|
||||||
|
@@ -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;
|
||||||
|
@@ -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]);
|
||||||
|
}
|
||||||
|
@@ -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,
|
||||||
|
Reference in New Issue
Block a user