1
0
mirror of https://github.com/redis/node-redis.git synced 2025-08-06 02:15:48 +03:00
This commit is contained in:
Leibale
2023-06-22 18:18:23 -04:00
parent b46f08228c
commit 2b318d4100
27 changed files with 595 additions and 578 deletions

View File

@@ -1,6 +1,6 @@
import { Command } from '../RESP/types';
import { transformLMPopArguments, LMPopOptions, ListSide, RedisVariadicArgument } from './generic-transformers';
import LMPOP from './LMPOP';
import { ListSide, RedisVariadicArgument } from './generic-transformers';
import LMPOP, { LMPopOptions, transformLMPopArguments } from './LMPOP';
export default {
FIRST_KEY_INDEX: 3,

View File

@@ -1,5 +1,26 @@
import { NullReply, TuplesReply, BlobStringReply, Command } from '../RESP/types';
import { transformLMPopArguments, LMPopOptions, ListSide, RedisVariadicArgument } from './generic-transformers';
import { CommandArguments, NullReply, TuplesReply, BlobStringReply, Command } from '../RESP/types';
import { ListSide, RedisVariadicArgument, pushVariadicArgument } from './generic-transformers';
export interface LMPopOptions {
COUNT?: number;
}
export function transformLMPopArguments(
args: CommandArguments,
keys: RedisVariadicArgument,
side: ListSide,
options?: LMPopOptions
): CommandArguments {
pushVariadicArgument(args, keys);
args.push(side);
if (options?.COUNT) {
args.push('COUNT', options.COUNT.toString());
}
return args;
}
export default {
FIRST_KEY_INDEX: 2,

View File

@@ -1,5 +1,5 @@
import { RedisArgument, NumberReply, DoubleReply, Command, CommandArguments } from '../RESP/types';
import { ZMember, transformDoubleArgument, transformDoubleReply } from './generic-transformers';
import { RedisArgument, Command } from '../RESP/types';
import { SortedSetMember, transformDoubleArgument, transformDoubleReply } from './generic-transformers';
export interface ZAddOptions {
condition?: 'NX' | 'XX';
@@ -27,7 +27,7 @@ export default {
FIRST_KEY_INDEX: 1,
transformArguments(
key: RedisArgument,
members: ZMember | Array<ZMember>,
members: SortedSetMember | Array<SortedSetMember>,
options?: ZAddOptions
) {
const args = ['ZADD', key];
@@ -56,16 +56,12 @@ export default {
return args;
},
transformReply: {
2: transformDoubleReply,
3: undefined as unknown as () => NumberReply
}
transformReply: transformDoubleReply
} as const satisfies Command;
export function pushMembers(
args: CommandArguments,
members: ZMember | Array<ZMember>
) {
args: Array<RedisArgument>,
members: SortedSetMember | Array<SortedSetMember>) {
if (Array.isArray(members)) {
for (const member of members) {
pushMember(args, member);
@@ -75,7 +71,10 @@ export function pushMembers(
}
}
function pushMember(args: Array<RedisArgument>, member: ZMember) {
function pushMember(
args: Array<RedisArgument>,
member: SortedSetMember
) {
args.push(
transformDoubleArgument(member.score),
member.value

View File

@@ -1,6 +1,6 @@
import { RedisArgument, DoubleReply, NullReply, Command } from '../RESP/types';
import { RedisArgument, Command } from '../RESP/types';
import { pushMembers } from './ZADD';
import { ZMember, transformDoubleArgument, transformNullableDoubleReply } from './generic-transformers';
import { SortedSetMember, transformNullableDoubleReply } from './generic-transformers';
export interface ZAddOptions {
condition?: 'NX' | 'XX';
@@ -12,7 +12,7 @@ export default {
FIRST_KEY_INDEX: 1,
transformArguments(
key: RedisArgument,
members: ZMember | Array<ZMember>,
members: SortedSetMember | Array<SortedSetMember>,
options?: ZAddOptions
) {
const args = ['ZADD', key];
@@ -35,8 +35,5 @@ export default {
return args;
},
transformReply: {
2: transformNullableDoubleReply,
3: undefined as unknown as () => DoubleReply | NullReply
}
transformReply: transformNullableDoubleReply
} as const satisfies Command;

View File

@@ -15,8 +15,5 @@ export default {
member
];
},
transformReply: {
2: transformDoubleReply,
3: undefined as unknown as () => DoubleReply
}
transformReply: transformDoubleReply
} as const satisfies Command;

View File

@@ -5,6 +5,7 @@ import { ZKeys } from './generic-transformers';
export default {
FIRST_KEY_INDEX: 1,
IS_READ_ONLY: false,
transformArguments(
destination: RedisArgument,
keys: ZKeys,

View File

@@ -1,32 +1,55 @@
// import { strict as assert } from 'assert';
// import testUtils, { GLOBAL } from '../test-utils';
// import { transformArguments } from './ZMPOP';
import { strict as assert } from 'assert';
import testUtils, { GLOBAL } from '../test-utils';
import ZMPOP from './ZMPOP';
// describe('ZMPOP', () => {
// testUtils.isVersionGreaterThanHook([7]);
describe('ZMPOP', () => {
testUtils.isVersionGreaterThanHook([7]);
// describe('transformArguments', () => {
// it('simple', () => {
// assert.deepEqual(
// transformArguments('key', 'MIN'),
// ['ZMPOP', '1', 'key', 'MIN']
// );
// });
describe('transformArguments', () => {
it('simple', () => {
assert.deepEqual(
ZMPOP.transformArguments('key', 'MIN'),
['ZMPOP', '1', 'key', 'MIN']
);
});
// it('with score and count', () => {
// assert.deepEqual(
// transformArguments('key', 'MIN', {
// COUNT: 2
// }),
// ['ZMPOP', '1', 'key', 'MIN', 'COUNT', '2']
// );
// });
// });
it('with count', () => {
assert.deepEqual(
ZMPOP.transformArguments('key', 'MIN', {
COUNT: 2
}),
['ZMPOP', '1', 'key', 'MIN', 'COUNT', '2']
);
});
});
// testUtils.testWithClient('client.zmPop', async client => {
// assert.deepEqual(
// await client.zmPop('key', 'MIN'),
// null
// );
// }, GLOBAL.SERVERS.OPEN);
// });
testUtils.testAll('zmPop - null', async client => {
assert.equal(
await client.zmPop('key', 'MIN'),
null
);
}, {
client: GLOBAL.SERVERS.OPEN,
cluster: GLOBAL.CLUSTERS.OPEN
});
testUtils.testAll('zmPop - with members', async client => {
const members = [{
value: '1',
score: 1
}];
const [, reply] = await Promise.all([
client.zAdd('key', members),
client.zmPop('key', 'MIN')
]);
assert.deepEqual(reply, {
key: 'key',
members
});
}, {
client: GLOBAL.SERVERS.OPEN,
cluster: GLOBAL.CLUSTERS.OPEN
});
});

View File

@@ -1,61 +1,51 @@
// import { NullReply, TuplesReply, BlobStringReply, DoubleReply, ArrayReply, Resp2Reply, Command, RedisArgument } from '../RESP/types';
// import { pushVariadicArgument, RedisVariadicArgument, SortedSetSide } from './generic-transformers';
import { NullReply, TuplesReply, BlobStringReply, DoubleReply, ArrayReply, Resp2Reply, Command } from '../RESP/types';
import { pushVariadicArgument, RedisVariadicArgument, SortedSetSide, transformSortedSetReply } from './generic-transformers';
// export interface ZMPopOptions {
// COUNT?: number;
// }
export interface ZMPopOptions {
COUNT?: number;
}
// export type ZMPopRawReply = NullReply | TuplesReply<[
// key: BlobStringReply,
// elements: ArrayReply<TuplesReply<[
// member: BlobStringReply,
// score: DoubleReply
// ]>>
// ]>;
export type ZMPopRawReply = NullReply | TuplesReply<[
key: BlobStringReply,
members: ArrayReply<TuplesReply<[
value: BlobStringReply,
score: DoubleReply
]>>
]>;
// export function pushZMPopArguments(
// args: Array<RedisArgument>,
// keys: RedisVariadicArgument,
// side: SortedSetSide,
// options: ZMPopOptions
// )
export default {
FIRST_KEY_INDEX: 2,
IS_READ_ONLY: false,
transformArguments(
keys: RedisVariadicArgument,
side: SortedSetSide,
options?: ZMPopOptions
) {
const args = pushVariadicArgument(['ZMPOP'], keys);
// export default {
// FIRST_KEY_INDEX: 2,
// IS_READ_ONLY: false,
// transformArguments(
// keys: RedisVariadicArgument,
// side: SortedSetSide,
// options?: ZMPopOptions
// ) {
// const args = pushVariadicArgument(['ZMPOP'], keys);
args.push(side);
// args.push(side);
if (options?.COUNT) {
args.push('COUNT', options.COUNT.toString());
}
// if (options?.COUNT) {
// args.push('COUNT', options.COUNT.toString());
// }
// return args;
// },
// transformReply: {
// 2: (reply: Resp2Reply<ZMPopRawReply>) => {
// return reply === null ? null : {
// key: reply[0],
// elements: reply[1].map(([member, score]) => ({
// member,
// score: Number(score)
// }))
// };
// },
// 3: (reply: ZMPopRawReply) => {
// return reply === null ? null : {
// key: reply[0],
// elements: reply[1].map(([member, score]) => ({
// member,
// score
// }))
// };
// },
// }
// } as const satisfies Command;
return args;
},
transformReply: {
2: (reply: Resp2Reply<ZMPopRawReply>) => {
return reply === null ? null : {
key: reply[0],
members: reply[1].map(([value, score]) => ({
value,
score: Number(score)
}))
};
},
3: (reply: ZMPopRawReply) => {
return reply === null ? null : {
key: reply[0],
members: transformSortedSetReply[3](reply[1])
};
},
}
} as const satisfies Command;

View File

@@ -1,5 +1,5 @@
import { RedisArgument, ArrayReply, NullReply, BlobStringReply, DoubleReply, Command } from '../RESP/types';
import { pushVariadicArguments, RedisVariadicArgument } from './generic-transformers';
import { pushVariadicArguments, RedisVariadicArgument, transformNullableDoubleReply } from './generic-transformers';
export default {
FIRST_KEY_INDEX: 1,
@@ -12,7 +12,7 @@ export default {
},
transformReply: {
2: (reply: ArrayReply<NullReply | BlobStringReply>) => {
return reply.map(score => score === null ? null : Number(score));
return reply.map(transformNullableDoubleReply[2]);
},
3: undefined as unknown as () => ArrayReply<NullReply | DoubleReply>
}

View File

@@ -1,41 +1,39 @@
// import { strict as assert } from 'assert';
// import testUtils, { GLOBAL } from '../test-utils';
// import { transformArguments, transformReply } from './ZPOPMAX';
import { strict as assert } from 'assert';
import testUtils, { GLOBAL } from '../test-utils';
import ZPOPMAX from './ZPOPMAX';
// describe('ZPOPMAX', () => {
// it('transformArguments', () => {
// assert.deepEqual(
// transformArguments('key'),
// ['ZPOPMAX', 'key']
// );
// });
describe('ZPOPMAX', () => {
it('transformArguments', () => {
assert.deepEqual(
ZPOPMAX.transformArguments('key'),
['ZPOPMAX', 'key']
);
});
// it('transformReply', () => {
// assert.deepEqual(
// transformReply(['value', '1']),
// {
// value: 'value',
// score: 1
// }
// );
// });
testUtils.testAll('zPopMax - null', async client => {
assert.equal(
await client.zPopMax('key'),
null
);
}, {
client: GLOBAL.SERVERS.OPEN,
cluster: GLOBAL.SERVERS.OPEN
});
// describe('client.zPopMax', () => {
// testUtils.testWithClient('null', async client => {
// assert.equal(
// await client.zPopMax('key'),
// null
// );
// }, GLOBAL.SERVERS.OPEN);
testUtils.testAll('zPopMax - with member', async client => {
const member = {
value: 'value',
score: 1
};
// testUtils.testWithClient('member', async client => {
// const member = { score: 1, value: 'value' },
// [, zPopMaxReply] = await Promise.all([
// client.zAdd('key', member),
// client.zPopMax('key')
// ]);
const [, reply] = await Promise.all([
client.zAdd('key', member),
client.zPopMax('key')
]);
// assert.deepEqual(zPopMaxReply, member);
// }, GLOBAL.SERVERS.OPEN);
// });
// });
assert.deepEqual(reply, member);
}, {
client: GLOBAL.SERVERS.OPEN,
cluster: GLOBAL.SERVERS.OPEN
});
});

View File

@@ -1,12 +1,11 @@
// import { RedisCommandArgument, RedisCommandArguments } from '.';
import { RedisArgument, NullReply, TuplesReply, BlobStringReply, DoubleReply, Command } from '../RESP/types';
import ZPOPMIN from './ZPOPMIN';
// export const FIRST_KEY_INDEX = 1;
// export function transformArguments(key: RedisCommandArgument): RedisCommandArguments {
// return [
// 'ZPOPMAX',
// key
// ];
// }
// export { transformSortedSetMemberNullReply as transformReply } from './generic-transformers';
export default {
FIRST_KEY_INDEX: 1,
IS_READ_ONLY: false,
transformArguments(key: RedisArgument) {
return ['ZPOPMAX', key];
},
transformReply: ZPOPMIN.transformReply
} as const satisfies Command;

View File

@@ -1,19 +1,29 @@
// import { strict as assert } from 'assert';
// import testUtils, { GLOBAL } from '../test-utils';
// import { transformArguments } from './ZPOPMAX_COUNT';
import { strict as assert } from 'assert';
import testUtils, { GLOBAL } from '../test-utils';
import ZPOPMAX_COUNT from './ZPOPMAX_COUNT';
// describe('ZPOPMAX COUNT', () => {
// it('transformArguments', () => {
// assert.deepEqual(
// transformArguments('key', 1),
// ['ZPOPMAX', 'key', '1']
// );
// });
describe('ZPOPMAX COUNT', () => {
it('transformArguments', () => {
assert.deepEqual(
ZPOPMAX_COUNT.transformArguments('key', 1),
['ZPOPMAX', 'key', '1']
);
});
// testUtils.testWithClient('client.zPopMaxCount', async client => {
// assert.deepEqual(
// await client.zPopMaxCount('key', 1),
// []
// );
// }, GLOBAL.SERVERS.OPEN);
// });
testUtils.testAll('zPopMaxCount', async client => {
const members = [{
value: '1',
score: 1
}];
const [ , reply] = await Promise.all([
client.zAdd('key', members),
client.zPopMaxCount('key', 1)
]);
assert.deepEqual(reply, members);
}, {
client: GLOBAL.SERVERS.OPEN,
cluster: GLOBAL.SERVERS.OPEN
});
});

View File

@@ -1,16 +1,11 @@
// import { RedisCommandArgument, RedisCommandArguments } from '.';
// import { transformArguments as transformZPopMaxArguments } from './ZPOPMAX';
import { RedisArgument, Command } from '../RESP/types';
import { transformSortedSetReply } from './generic-transformers';
// export { FIRST_KEY_INDEX } from './ZPOPMAX';
// export function transformArguments(
// key: RedisCommandArgument,
// count: number
// ): RedisCommandArguments {
// return [
// ...transformZPopMaxArguments(key),
// count.toString()
// ];
// }
// export { transformSortedSetWithScoresReply as transformReply } from './generic-transformers';
export default {
FIRST_KEY_INDEX: undefined,
IS_READ_ONLY: false,
transformArguments(key: RedisArgument, count: number) {
return ['ZPOPMAX', key, count.toString()];
},
transformReply: transformSortedSetReply
} as const satisfies Command;

View File

@@ -1,41 +1,39 @@
// import { strict as assert } from 'assert';
// import testUtils, { GLOBAL } from '../test-utils';
// import { transformArguments, transformReply } from './ZPOPMIN';
import { strict as assert } from 'assert';
import testUtils, { GLOBAL } from '../test-utils';
import ZPOPMIN from './ZPOPMIN';
// describe('ZPOPMIN', () => {
// it('transformArguments', () => {
// assert.deepEqual(
// transformArguments('key'),
// ['ZPOPMIN', 'key']
// );
// });
describe('ZPOPMIN', () => {
it('transformArguments', () => {
assert.deepEqual(
ZPOPMIN.transformArguments('key'),
['ZPOPMIN', 'key']
);
});
// it('transformReply', () => {
// assert.deepEqual(
// transformReply(['value', '1']),
// {
// value: 'value',
// score: 1
// }
// );
// });
testUtils.testAll('zPopMin - null', async client => {
assert.equal(
await client.zPopMin('key'),
null
);
}, {
client: GLOBAL.SERVERS.OPEN,
cluster: GLOBAL.SERVERS.OPEN
});
// describe('client.zPopMin', () => {
// testUtils.testWithClient('null', async client => {
// assert.equal(
// await client.zPopMin('key'),
// null
// );
// }, GLOBAL.SERVERS.OPEN);
testUtils.testAll('zPopMax - with member', async client => {
const member = {
value: 'value',
score: 1
};
// testUtils.testWithClient('member', async client => {
// const member = { score: 1, value: 'value' },
// [, zPopMinReply] = await Promise.all([
// client.zAdd('key', member),
// client.zPopMin('key')
// ]);
const [, reply] = await Promise.all([
client.zAdd('key', member),
client.zPopMin('key')
]);
// assert.deepEqual(zPopMinReply, member);
// }, GLOBAL.SERVERS.OPEN);
// });
// });
assert.deepEqual(reply, member);
}, {
client: GLOBAL.SERVERS.OPEN,
cluster: GLOBAL.SERVERS.OPEN
});
});

View File

@@ -1,12 +1,27 @@
// import { RedisCommandArgument, RedisCommandArguments } from '.';
import { RedisArgument, TuplesReply, BlobStringReply, DoubleReply, Command } from '../RESP/types';
// export const FIRST_KEY_INDEX = 1;
export default {
FIRST_KEY_INDEX: 1,
IS_READ_ONLY: false,
transformArguments(key: RedisArgument) {
return ['ZPOPMIN', key];
},
transformReply: {
2: (reply: TuplesReply<[]> | TuplesReply<[BlobStringReply, BlobStringReply]>) => {
if (reply.length === 0) return null;
// export function transformArguments(key: RedisCommandArgument): RedisCommandArguments {
// return [
// 'ZPOPMIN',
// key
// ];
// }
return {
value: reply[0],
score: Number(reply[1])
};
},
3: (reply: TuplesReply<[]> | TuplesReply<[BlobStringReply, DoubleReply]>) => {
if (reply.length === 0) return null;
// export { transformSortedSetMemberNullReply as transformReply } from './generic-transformers';
return {
value: reply[0],
score: reply[1]
};
}
}
} as const satisfies Command;

View File

@@ -1,19 +1,29 @@
// import { strict as assert } from 'assert';
// import testUtils, { GLOBAL } from '../test-utils';
// import { transformArguments } from './ZPOPMIN_COUNT';
import { strict as assert } from 'assert';
import testUtils, { GLOBAL } from '../test-utils';
import ZPOPMIN_COUNT from './ZPOPMIN_COUNT';
// describe('ZPOPMIN COUNT', () => {
// it('transformArguments', () => {
// assert.deepEqual(
// transformArguments('key', 1),
// ['ZPOPMIN', 'key', '1']
// );
// });
describe('ZPOPMIN COUNT', () => {
it('transformArguments', () => {
assert.deepEqual(
ZPOPMIN_COUNT.transformArguments('key', 1),
['ZPOPMIN', 'key', '1']
);
});
// testUtils.testWithClient('client.zPopMinCount', async client => {
// assert.deepEqual(
// await client.zPopMinCount('key', 1),
// []
// );
// }, GLOBAL.SERVERS.OPEN);
// });
testUtils.testAll('zPopMinCount', async client => {
const members = [{
value: '1',
score: 1
}];
const [ , reply] = await Promise.all([
client.zAdd('key', members),
client.zPopMinCount('key', 1)
]);
assert.deepEqual(reply, members);
}, {
client: GLOBAL.SERVERS.OPEN,
cluster: GLOBAL.SERVERS.OPEN
});
});

View File

@@ -1,16 +1,11 @@
// import { RedisCommandArgument, RedisCommandArguments } from '.';
// import { transformArguments as transformZPopMinArguments } from './ZPOPMIN';
import { RedisArgument, Command } from '../RESP/types';
import { transformSortedSetReply } from './generic-transformers';
// export { FIRST_KEY_INDEX } from './ZPOPMIN';
// export function transformArguments(
// key: RedisCommandArgument,
// count: number
// ): RedisCommandArguments {
// return [
// ...transformZPopMinArguments(key),
// count.toString()
// ];
// }
// export { transformSortedSetWithScoresReply as transformReply } from './generic-transformers';
export default {
FIRST_KEY_INDEX: undefined,
IS_READ_ONLY: false,
transformArguments(key: RedisArgument, count: number) {
return ['ZPOPMIN', key, count.toString()];
},
transformReply: transformSortedSetReply
} as const satisfies Command;

View File

@@ -1,92 +1,81 @@
// import { strict as assert } from 'assert';
// import testUtils, { GLOBAL } from '../test-utils';
// import { transformArguments, transformReply } from './ZRANGESTORE';
import { strict as assert } from 'assert';
import testUtils, { GLOBAL } from '../test-utils';
import ZRANGESTORE from './ZRANGESTORE';
// describe('ZRANGESTORE', () => {
// testUtils.isVersionGreaterThanHook([6, 2]);
describe('ZRANGESTORE', () => {
testUtils.isVersionGreaterThanHook([6, 2]);
// describe('transformArguments', () => {
// it('simple', () => {
// assert.deepEqual(
// transformArguments('dst', 'src', 0, 1),
// ['ZRANGESTORE', 'dst', 'src', '0', '1']
// );
// });
describe('transformArguments', () => {
it('simple', () => {
assert.deepEqual(
ZRANGESTORE.transformArguments('destination', 'source', 0, 1),
['ZRANGESTORE', 'destination', 'source', '0', '1']
);
});
// it('with BYSCORE', () => {
// assert.deepEqual(
// transformArguments('dst', 'src', 0, 1, {
// BY: 'SCORE'
// }),
// ['ZRANGESTORE', 'dst', 'src', '0', '1', 'BYSCORE']
// );
// });
it('with BYSCORE', () => {
assert.deepEqual(
ZRANGESTORE.transformArguments('destination', 'source', 0, 1, {
BY: 'SCORE'
}),
['ZRANGESTORE', 'destination', 'source', '0', '1', 'BYSCORE']
);
});
// it('with BYLEX', () => {
// assert.deepEqual(
// transformArguments('dst', 'src', 0, 1, {
// BY: 'LEX'
// }),
// ['ZRANGESTORE', 'dst', 'src', '0', '1', 'BYLEX']
// );
// });
it('with BYLEX', () => {
assert.deepEqual(
ZRANGESTORE.transformArguments('destination', 'source', 0, 1, {
BY: 'LEX'
}),
['ZRANGESTORE', 'destination', 'source', '0', '1', 'BYLEX']
);
});
// it('with REV', () => {
// assert.deepEqual(
// transformArguments('dst', 'src', 0, 1, {
// REV: true
// }),
// ['ZRANGESTORE', 'dst', 'src', '0', '1', 'REV']
// );
// });
it('with REV', () => {
assert.deepEqual(
ZRANGESTORE.transformArguments('destination', 'source', 0, 1, {
REV: true
}),
['ZRANGESTORE', 'destination', 'source', '0', '1', 'REV']
);
});
// it('with LIMIT', () => {
// assert.deepEqual(
// transformArguments('dst', 'src', 0, 1, {
// LIMIT: {
// offset: 0,
// count: 1
// }
// }),
// ['ZRANGESTORE', 'dst', 'src', '0', '1', 'LIMIT', '0', '1']
// );
// });
it('with LIMIT', () => {
assert.deepEqual(
ZRANGESTORE.transformArguments('destination', 'source', 0, 1, {
LIMIT: {
offset: 0,
count: 1
}
}),
['ZRANGESTORE', 'destination', 'source', '0', '1', 'LIMIT', '0', '1']
);
});
// it('with BY & REV & LIMIT', () => {
// assert.deepEqual(
// transformArguments('dst', 'src', 0, 1, {
// BY: 'SCORE',
// REV: true,
// LIMIT: {
// offset: 0,
// count: 1
// },
// WITHSCORES: true
// }),
// ['ZRANGESTORE', 'dst', 'src', '0', '1', 'BYSCORE', 'REV', 'LIMIT', '0', '1', 'WITHSCORES']
// );
// });
// });
it('with BY & REV & LIMIT', () => {
assert.deepEqual(
ZRANGESTORE.transformArguments('destination', 'source', 0, 1, {
BY: 'SCORE',
REV: true,
LIMIT: {
offset: 0,
count: 1
}
}),
['ZRANGESTORE', 'destination', 'source', '0', '1', 'BYSCORE', 'REV', 'LIMIT', '0', '1']
);
});
});
// describe('transformReply', () => {
// it('should throw TypeError when reply is not a number', () => {
// assert.throws(
// // eslint-disable-next-line @typescript-eslint/no-explicit-any
// () => (transformReply as any)([]),
// TypeError
// );
// });
// });
testUtils.testWithClient('client.zRangeStore', async client => {
const [, reply] = await Promise.all([
client.zAdd('{tag}source', {
score: 1,
value: '1'
}),
client.zRangeStore('{tag}destination', '{tag}source', 0, 1)
]);
// testUtils.testWithClient('client.zRangeStore', async client => {
// await client.zAdd('src', {
// score: 0.5,
// value: 'value'
// });
// assert.equal(
// await client.zRangeStore('dst', 'src', 0, 1),
// 1
// );
// }, GLOBAL.SERVERS.OPEN);
// });
assert.equal(reply, 1);
}, GLOBAL.SERVERS.OPEN);
});

View File

@@ -1,62 +1,52 @@
// import { RedisCommandArgument, RedisCommandArguments } from '.';
// import { transformStringDoubleArgument } from './generic-transformers';
import { RedisArgument, NumberReply, Command } from '../RESP/types';
import { transformStringDoubleArgument } from './generic-transformers';
// export const FIRST_KEY_INDEX = 1;
export interface ZRangeStoreOptions {
BY?: 'SCORE' | 'LEX';
REV?: true;
LIMIT?: {
offset: number;
count: number;
};
}
// interface ZRangeStoreOptions {
// BY?: 'SCORE' | 'LEX';
// REV?: true;
// LIMIT?: {
// offset: number;
// count: number;
// };
// WITHSCORES?: true;
// }
export default {
FIRST_KEY_INDEX: 1,
IS_READ_ONLY: false,
transformArguments(
destination: RedisArgument,
source: RedisArgument,
min: RedisArgument | number,
max: RedisArgument | number,
options?: ZRangeStoreOptions
) {
const args = [
'ZRANGESTORE',
destination,
source,
transformStringDoubleArgument(min),
transformStringDoubleArgument(max)
];
// export function transformArguments(
// dst: RedisCommandArgument,
// src: RedisCommandArgument,
// min: RedisCommandArgument | number,
// max: RedisCommandArgument | number,
// options?: ZRangeStoreOptions
// ): RedisCommandArguments {
// const args = [
// 'ZRANGESTORE',
// dst,
// src,
// transformStringDoubleArgument(min),
// transformStringDoubleArgument(max)
// ];
switch (options?.BY) {
case 'SCORE':
args.push('BYSCORE');
break;
// switch (options?.BY) {
// case 'SCORE':
// args.push('BYSCORE');
// break;
case 'LEX':
args.push('BYLEX');
break;
}
// case 'LEX':
// args.push('BYLEX');
// break;
// }
if (options?.REV) {
args.push('REV');
}
// if (options?.REV) {
// args.push('REV');
// }
if (options?.LIMIT) {
args.push('LIMIT', options.LIMIT.offset.toString(), options.LIMIT.count.toString());
}
// if (options?.LIMIT) {
// args.push('LIMIT', options.LIMIT.offset.toString(), options.LIMIT.count.toString());
// }
// if (options?.WITHSCORES) {
// args.push('WITHSCORES');
// }
// return args;
// }
// export function transformReply(reply: number): number {
// if (typeof reply !== 'number') {
// throw new TypeError(`Upgrade to Redis 6.2.5 and up (https://github.com/redis/redis/pull/9089)`);
// }
// return reply;
// }
return args;
},
transformReply: undefined as unknown as () => NumberReply
} as const satisfies Command;

View File

@@ -1,65 +1,75 @@
// import { strict as assert } from 'assert';
// import testUtils, { GLOBAL } from '../test-utils';
// import { transformArguments } from './ZRANGE_WITHSCORES';
import { strict as assert } from 'assert';
import testUtils, { GLOBAL } from '../test-utils';
import ZRANGE_WITHSCORES from './ZRANGE_WITHSCORES';
// describe('ZRANGE WITHSCORES', () => {
// describe('transformArguments', () => {
// it('simple', () => {
// assert.deepEqual(
// transformArguments('src', 0, 1),
// ['ZRANGE', 'src', '0', '1', 'WITHSCORES']
// );
// });
describe('ZRANGE WITHSCORES', () => {
describe('transformArguments', () => {
it('simple', () => {
assert.deepEqual(
ZRANGE_WITHSCORES.transformArguments('src', 0, 1),
['ZRANGE', 'src', '0', '1', 'WITHSCORES']
);
});
// it('with BY', () => {
// assert.deepEqual(
// transformArguments('src', 0, 1, {
// BY: 'SCORE'
// }),
// ['ZRANGE', 'src', '0', '1', 'BYSCORE', 'WITHSCORES']
// );
// });
it('with BY', () => {
assert.deepEqual(
ZRANGE_WITHSCORES.transformArguments('src', 0, 1, {
BY: 'SCORE'
}),
['ZRANGE', 'src', '0', '1', 'BYSCORE', 'WITHSCORES']
);
});
// it('with REV', () => {
// assert.deepEqual(
// transformArguments('src', 0, 1, {
// REV: true
// }),
// ['ZRANGE', 'src', '0', '1', 'REV', 'WITHSCORES']
// );
// });
it('with REV', () => {
assert.deepEqual(
ZRANGE_WITHSCORES.transformArguments('src', 0, 1, {
REV: true
}),
['ZRANGE', 'src', '0', '1', 'REV', 'WITHSCORES']
);
});
// it('with LIMIT', () => {
// assert.deepEqual(
// transformArguments('src', 0, 1, {
// LIMIT: {
// offset: 0,
// count: 1
// }
// }),
// ['ZRANGE', 'src', '0', '1', 'LIMIT', '0', '1', 'WITHSCORES']
// );
// });
it('with LIMIT', () => {
assert.deepEqual(
ZRANGE_WITHSCORES.transformArguments('src', 0, 1, {
LIMIT: {
offset: 0,
count: 1
}
}),
['ZRANGE', 'src', '0', '1', 'LIMIT', '0', '1', 'WITHSCORES']
);
});
// it('with BY & REV & LIMIT', () => {
// assert.deepEqual(
// transformArguments('src', 0, 1, {
// BY: 'SCORE',
// REV: true,
// LIMIT: {
// offset: 0,
// count: 1
// }
// }),
// ['ZRANGE', 'src', '0', '1', 'BYSCORE', 'REV', 'LIMIT', '0', '1', 'WITHSCORES']
// );
// });
// });
it('with BY & REV & LIMIT', () => {
assert.deepEqual(
ZRANGE_WITHSCORES.transformArguments('src', 0, 1, {
BY: 'SCORE',
REV: true,
LIMIT: {
offset: 0,
count: 1
}
}),
['ZRANGE', 'src', '0', '1', 'BYSCORE', 'REV', 'LIMIT', '0', '1', 'WITHSCORES']
);
});
});
// testUtils.testWithClient('client.zRangeWithScores', async client => {
// assert.deepEqual(
// await client.zRangeWithScores('src', 0, 1),
// []
// );
// }, GLOBAL.SERVERS.OPEN);
// });
testUtils.testAll('zRangeWithScores', async client => {
const members = [{
value: '1',
score: 1
}];
const [, reply] = await Promise.all([
client.zAdd('key', members),
client.zRangeWithScores('key', 0, 1)
]);
assert.deepEqual(reply, members);
}, {
client: GLOBAL.SERVERS.OPEN,
cluster: GLOBAL.CLUSTERS.OPEN
});
});

View File

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

View File

@@ -1,6 +1,6 @@
import { RedisArgument, BlobStringReply, Command } from '../RESP/types';
import { RedisArgument, ArrayReply, BlobStringReply, Command } from '../RESP/types';
import { ScanCommonOptions, pushScanArguments } from './SCAN';
import { ZMember, transformDoubleReply } from './generic-transformers';
import { SortedSetMember, transformDoubleReply, transformSortedSetReply } from './generic-transformers';
export interface HScanEntry {
field: BlobStringReply;
@@ -17,19 +17,10 @@ export default {
) {
return pushScanArguments(['ZSCAN', key], cursor, options);
},
transformReply([cursor, rawMembers]: [BlobStringReply, Array<BlobStringReply>]) {
const members = [];
let i = 0;
while (i < rawMembers.length) {
members.push({
value: rawMembers[i++],
score: transformDoubleReply(rawMembers[i++])
} satisfies ZMember);
}
transformReply([cursor, rawMembers]: [BlobStringReply, ArrayReply<BlobStringReply>]) {
return {
cursor: Number(cursor),
members
members: transformSortedSetReply[2](rawMembers)
};
}
} as const satisfies Command;

View File

@@ -1,5 +1,5 @@
import { DoubleReply, NullReply, Command, RedisArgument } from '../RESP/types';
import { RedisArgument, Command } from '../RESP/types';
import { transformNullableDoubleReply } from './generic-transformers';
export default {
@@ -8,8 +8,5 @@ export default {
transformArguments(key: RedisArgument, member: RedisArgument) {
return ['ZSCORE', key, member];
},
transformReply: {
2: transformNullableDoubleReply,
3: undefined as unknown as () => DoubleReply | NullReply
}
transformReply: transformNullableDoubleReply
} as const satisfies Command;

View File

@@ -1,30 +1,7 @@
import { ArrayReply, BlobStringReply, CommandArguments, DoubleReply, NullReply, RedisArgument, Resp2Reply } from '../RESP/types';
import { ArrayReply, BlobStringReply, CommandArguments, DoubleReply, NullReply, RedisArgument, Resp2Reply, TuplesReply } from '../RESP/types';
export type BitValue = 0 | 1;
export function transformDoubleReply(reply: BlobStringReply): number {
switch (reply.toString()) {
case '+inf':
return Infinity;
case '-inf':
return -Infinity;
default:
return Number(reply);
}
}
export function transformNullableDoubleReply(reply: BlobStringReply | NullReply): number | null {
if (reply === null) return null;
return transformDoubleReply(reply);
}
export function transformArrayNullableDoubleReply(reply: Array<BlobStringReply | NullReply>): Array<number | null> {
return reply.map(transformNullableDoubleReply);
}
export function transformDoubleArgument(num: number): string {
switch (num) {
case Infinity:
@@ -44,6 +21,31 @@ export function transformStringDoubleArgument(num: RedisArgument | number): Redi
return transformDoubleArgument(num);
}
export const transformDoubleReply = {
2: (reply: BlobStringReply) => {
switch (reply.toString()) {
case '+inf':
return Infinity;
case '-inf':
return -Infinity;
default:
return Number(reply);
}
},
3: undefined as unknown as () => DoubleReply
};
export const transformNullableDoubleReply = {
2: (reply: BlobStringReply | NullReply) => {
if (reply === null) return null;
return transformDoubleReply[2](reply);
},
3: undefined as unknown as () => DoubleReply | NullReply
};
export function transformTuplesReply(
reply: ArrayReply<BlobStringReply>
): Record<string, BlobStringReply> {
@@ -90,27 +92,12 @@ export function transformStreamsMessagesReply(reply: Array<any> | null): Streams
}));
}
export interface ZMember {
score: number;
export interface SortedSetMember {
value: RedisArgument;
score: number;
}
export function transformSortedSetMemberNullReply(
reply: [BlobStringReply, BlobStringReply] | []
): ZMember | null {
if (!reply.length) return null;
return transformSortedSetMemberReply(reply);
}
export function transformSortedSetMemberReply(
reply: [BlobStringReply, BlobStringReply]
): ZMember {
return {
value: reply[0],
score: transformDoubleReply(reply[1])
};
}
export type SortedSetSide = 'MIN' | 'MAX';
export const transformSortedSetReply = {
2: (reply: ArrayReply<BlobStringReply>) => {
@@ -118,13 +105,13 @@ export const transformSortedSetReply = {
for (let i = 0; i < reply.length; i += 2) {
members.push({
value: reply[i],
score: transformDoubleReply(reply[i + 1])
score: transformDoubleReply[2](reply[i + 1])
});
}
return members;
},
3: (reply: ArrayReply<[BlobStringReply, DoubleReply]>) => {
3: (reply: ArrayReply<TuplesReply<[BlobStringReply, DoubleReply]>>) => {
return reply.map(([value, score]) => ({
value,
score
@@ -132,44 +119,8 @@ export const transformSortedSetReply = {
}
}
export function transformSortedSetWithScoresReply(reply: ArrayReply<BlobStringReply>): Array<ZMember> {
const members = [];
for (let i = 0; i < reply.length; i += 2) {
members.push({
value: reply[i],
score: transformDoubleReply(reply[i + 1])
});
}
return members;
}
export type ListSide = 'LEFT' | 'RIGHT';
export type SortedSetSide = 'MIN' | 'MAX';
export interface LMPopOptions {
COUNT?: number;
}
export function transformLMPopArguments(
args: CommandArguments,
keys: RedisVariadicArgument,
side: ListSide,
options?: LMPopOptions
): CommandArguments {
pushVariadicArgument(args, keys);
args.push(side);
if (options?.COUNT) {
args.push('COUNT', options.COUNT.toString());
}
return args;
}
export function transformEXAT(EXAT: number | Date): string {
return (typeof EXAT === 'number' ? EXAT : Math.floor(EXAT.getTime() / 1000)).toString();
}

View File

@@ -270,14 +270,21 @@ import ZINTER from './ZINTER';
import ZINTERCARD from './ZINTERCARD';
import ZINTERSTORE from './ZINTERSTORE';
import ZLEXCOUNT from './ZLEXCOUNT';
import ZMPOP from './ZMPOP';
import ZMSCORE from './ZMSCORE';
import ZPOPMAX_COUNT from './ZPOPMAX_COUNT';
import ZPOPMAX from './ZPOPMAX';
import ZPOPMIN_COUNT from './ZPOPMIN_COUNT';
import ZPOPMIN from './ZPOPMIN';
import ZRANDMEMBER_COUNT_WITHSCORES from './ZRANDMEMBER_COUNT_WITHSCORES';
import ZRANDMEMBER_COUNT from './ZRANDMEMBER_COUNT';
import ZRANDMEMBER from './ZRANDMEMBER';
import ZRANGE_WITHSCORES from './ZRANGE_WITHSCORES';
import ZRANGE from './ZRANGE';
import ZRANGEBYLEX from './ZRANGEBYLEX';
import ZRANGEBYSCORE_WITHSCORES from './ZRANGEBYSCORE_WITHSCORES';
import ZRANGEBYSCORE from './ZRANGEBYSCORE';
import ZRANGESTORE from './ZRANGESTORE';
import ZREMRANGEBYSCORE from './ZREMRANGEBYSCORE';
import ZRANK from './ZRANK';
import ZREM from './ZREM';
@@ -563,14 +570,21 @@ type ZINTER = typeof import('./ZINTER').default;
type ZINTERCARD = typeof import('./ZINTERCARD').default;
type ZINTERSTORE = typeof import('./ZINTERSTORE').default;
type ZLEXCOUNT = typeof import('./ZLEXCOUNT').default;
type ZMPOP = typeof import('./ZMPOP').default;
type ZMSCORE = typeof import('./ZMSCORE').default;
type ZPOPMAX_COUNT = typeof import('./ZPOPMAX_COUNT').default;
type ZPOPMAX = typeof import('./ZPOPMAX').default;
type ZPOPMIN_COUNT = typeof import('./ZPOPMIN_COUNT').default;
type ZPOPMIN = typeof import('./ZPOPMIN').default;
type ZRANDMEMBER_COUNT_WITHSCORES = typeof import('./ZRANDMEMBER_COUNT_WITHSCORES').default;
type ZRANDMEMBER_COUNT = typeof import('./ZRANDMEMBER_COUNT').default;
type ZRANDMEMBER = typeof import('./ZRANDMEMBER').default;
type ZRANGE_WITHSCORES = typeof import('./ZRANGE_WITHSCORES').default;
type ZRANGE = typeof import('./ZRANGE').default;
type ZRANGEBYLEX = typeof import('./ZRANGEBYLEX').default;
type ZRANGEBYSCORE_WITHSCORES = typeof import('./ZRANGEBYSCORE_WITHSCORES').default;
type ZRANGEBYSCORE = typeof import('./ZRANGEBYSCORE').default;
type ZRANGESTORE = typeof import('./ZRANGESTORE').default;
type ZREMRANGEBYSCORE = typeof import('./ZREMRANGEBYSCORE').default;
type ZRANK = typeof import('./ZRANK').default;
type ZREM = typeof import('./ZREM').default;
@@ -1130,14 +1144,26 @@ type Commands = {
zInterStore: ZINTERSTORE;
ZLEXCOUNT: ZLEXCOUNT;
zLexCount: ZLEXCOUNT;
ZMPOP: ZMPOP;
zmPop: ZMPOP;
ZMSCORE: ZMSCORE;
zmScore: ZMSCORE;
ZPOPMAX_COUNT: ZPOPMAX_COUNT;
zPopMaxCount: ZPOPMAX_COUNT;
ZPOPMAX: ZPOPMAX;
zPopMax: ZPOPMAX;
ZPOPMIN_COUNT: ZPOPMIN_COUNT;
zPopMinCount: ZPOPMIN_COUNT;
ZPOPMIN: ZPOPMIN;
zPopMin: ZPOPMIN;
ZRANDMEMBER_COUNT_WITHSCORES: ZRANDMEMBER_COUNT_WITHSCORES;
zRandMemberCountWithScores: ZRANDMEMBER_COUNT_WITHSCORES;
ZRANDMEMBER_COUNT: ZRANDMEMBER_COUNT;
zRandMemberCount: ZRANDMEMBER_COUNT;
ZRANDMEMBER: ZRANDMEMBER;
zRandMember: ZRANDMEMBER;
ZRANGE_WITHSCORES: ZRANGE_WITHSCORES;
zRangeWithScores: ZRANGE_WITHSCORES;
ZRANGE: ZRANGE;
zRange: ZRANGE;
ZRANGEBYLEX: ZRANGEBYLEX;
@@ -1146,6 +1172,8 @@ type Commands = {
zRangeByScoreWithScores: ZRANGEBYSCORE_WITHSCORES;
ZRANGEBYSCORE: ZRANGEBYSCORE;
zRangeByScore: ZRANGEBYSCORE;
ZRANGESTORE: ZRANGESTORE;
zRangeStore: ZRANGESTORE;
ZRANK: ZRANK;
zRank: ZRANK;
ZREM: ZREM;
@@ -1717,14 +1745,26 @@ export default {
zInterStore: ZINTERSTORE,
ZLEXCOUNT,
zLexCount: ZLEXCOUNT,
ZMPOP,
zmPop: ZMPOP,
ZMSCORE,
zmScore: ZMSCORE,
ZPOPMAX_COUNT,
zPopMaxCount: ZPOPMAX_COUNT,
ZPOPMAX,
zPopMax: ZPOPMAX,
ZPOPMIN_COUNT,
zPopMinCount: ZPOPMIN_COUNT,
ZPOPMIN,
zPopMin: ZPOPMIN,
ZRANDMEMBER_COUNT_WITHSCORES,
zRandMemberCountWithScores: ZRANDMEMBER_COUNT_WITHSCORES,
ZRANDMEMBER_COUNT,
zRandMemberCount: ZRANDMEMBER_COUNT,
ZRANDMEMBER,
zRandMember: ZRANDMEMBER,
ZRANGE_WITHSCORES,
zRangeWithScores: ZRANGE_WITHSCORES,
ZRANGE,
zRange: ZRANGE,
ZRANGEBYLEX,
@@ -1733,6 +1773,8 @@ export default {
zRangeByScoreWithScores: ZRANGEBYSCORE_WITHSCORES,
ZRANGEBYSCORE,
zRangeByScore: ZRANGEBYSCORE,
ZRANGESTORE,
zRangeStore: ZRANGESTORE,
ZRANK,
zRank: ZRANK,
ZREM,