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

fix GEO* commands

This commit is contained in:
Leibale
2023-05-08 11:04:22 +03:00
parent d2e244a77d
commit 6a0b4db4f7
37 changed files with 1115 additions and 990 deletions

View File

@@ -1,12 +1,12 @@
import { strict as assert } from 'assert';
import testUtils, { GLOBAL } from '../test-utils';
import { transformArguments } from './GEOADD';
import GEOADD from './GEOADD';
describe('GEOADD', () => {
describe('transformArguments', () => {
it('one member', () => {
assert.deepEqual(
transformArguments('key', {
GEOADD.transformArguments('key', {
member: 'member',
longitude: 1,
latitude: 2
@@ -17,7 +17,7 @@ describe('GEOADD', () => {
it('multiple members', () => {
assert.deepEqual(
transformArguments('key', [{
GEOADD.transformArguments('key', [{
longitude: 1,
latitude: 2,
member: '3',
@@ -30,9 +30,22 @@ describe('GEOADD', () => {
);
});
it('with NX', () => {
it('with condition', () => {
assert.deepEqual(
transformArguments('key', {
GEOADD.transformArguments('key', {
longitude: 1,
latitude: 2,
member: 'member'
}, {
condition: 'NX'
}),
['GEOADD', 'key', 'NX', '1', '2', 'member']
);
});
it('with NX (backwards compatibility)', () => {
assert.deepEqual(
GEOADD.transformArguments('key', {
longitude: 1,
latitude: 2,
member: 'member'
@@ -45,7 +58,7 @@ describe('GEOADD', () => {
it('with CH', () => {
assert.deepEqual(
transformArguments('key', {
GEOADD.transformArguments('key', {
longitude: 1,
latitude: 2,
member: 'member'
@@ -56,14 +69,14 @@ describe('GEOADD', () => {
);
});
it('with XX, CH', () => {
it('with condition, CH', () => {
assert.deepEqual(
transformArguments('key', {
GEOADD.transformArguments('key', {
longitude: 1,
latitude: 2,
member: 'member'
}, {
XX: true,
condition: 'XX',
CH: true
}),
['GEOADD', 'key', 'XX', 'CH', '1', '2', 'member']
@@ -71,7 +84,7 @@ describe('GEOADD', () => {
});
});
testUtils.testWithClient('client.geoAdd', async client => {
testUtils.testAll('geoAdd', async client => {
assert.equal(
await client.geoAdd('key', {
member: 'member',
@@ -80,16 +93,8 @@ describe('GEOADD', () => {
}),
1
);
}, GLOBAL.SERVERS.OPEN);
testUtils.testWithCluster('cluster.geoAdd', async cluster => {
assert.equal(
await cluster.geoAdd('key', {
member: 'member',
longitude: 1,
latitude: 2
}),
1
);
}, GLOBAL.CLUSTERS.OPEN);
}, {
client: GLOBAL.SERVERS.OPEN,
cluster: GLOBAL.CLUSTERS.OPEN
});
});

View File

@@ -1,12 +1,12 @@
import { CommandArguments, RedisArgument, NumberReply, Command } from '../RESP/types';
import { GeoCoordinates } from './generic-transformers';
import { RedisArgument, CommandArguments, NumberReply, Command } from '../RESP/types';
import { GeoCoordinates } from './GEOSEARCH';
interface GeoMember extends GeoCoordinates {
export interface GeoMember extends GeoCoordinates {
member: RedisArgument;
}
interface GeoAddOptions {
condition: 'NX' | 'XX';
export interface GeoAddOptions {
condition?: 'NX' | 'XX';
/**
* @deprecated Use `{ condition: 'NX' }` instead.
*/

View File

@@ -1,33 +1,35 @@
import { strict as assert } from 'assert';
import testUtils, { GLOBAL } from '../test-utils';
import { transformArguments } from './GEODIST';
import GEODIST from './GEODIST';
describe('GEODIST', () => {
describe('transformArguments', () => {
it('simple', () => {
assert.deepEqual(
transformArguments('key', '1', '2'),
GEODIST.transformArguments('key', '1', '2'),
['GEODIST', 'key', '1', '2']
);
});
it('with unit', () => {
assert.deepEqual(
transformArguments('key', '1', '2', 'm'),
GEODIST.transformArguments('key', '1', '2', 'm'),
['GEODIST', 'key', '1', '2', 'm']
);
});
});
describe('client.geoDist', () => {
testUtils.testWithClient('null', async client => {
testUtils.testAll('geoDist null', async client => {
assert.equal(
await client.geoDist('key', '1', '2'),
null
);
}, GLOBAL.SERVERS.OPEN);
}, {
client: GLOBAL.SERVERS.OPEN,
cluster: GLOBAL.CLUSTERS.OPEN
});
testUtils.testWithClient('with value', async client => {
testUtils.testAll('geoDist with member', async client => {
const [, dist] = await Promise.all([
client.geoAdd('key', [{
member: '1',
@@ -45,13 +47,8 @@ describe('GEODIST', () => {
dist,
157270.0561
);
}, GLOBAL.SERVERS.OPEN);
}, {
client: GLOBAL.SERVERS.OPEN,
cluster: GLOBAL.CLUSTERS.OPEN
});
testUtils.testWithCluster('cluster.geoDist', async cluster => {
assert.equal(
await cluster.geoDist('key', '1', '2'),
null
);
}, GLOBAL.CLUSTERS.OPEN);
});

View File

@@ -1,35 +1,31 @@
import { strict as assert } from 'assert';
import testUtils, { GLOBAL } from '../test-utils';
import { transformArguments } from './GEOHASH';
import GEOHASH from './GEOHASH';
describe('GEOHASH', () => {
describe('transformArguments', () => {
it('single member', () => {
assert.deepEqual(
transformArguments('key', 'member'),
GEOHASH.transformArguments('key', 'member'),
['GEOHASH', 'key', 'member']
);
});
it('multiple members', () => {
assert.deepEqual(
transformArguments('key', ['1', '2']),
GEOHASH.transformArguments('key', ['1', '2']),
['GEOHASH', 'key', '1', '2']
);
});
});
testUtils.testWithClient('client.geoHash', async client => {
testUtils.testAll('geoHash', async client => {
assert.deepEqual(
await client.geoHash('key', 'member'),
[null]
);
}, GLOBAL.SERVERS.OPEN);
testUtils.testWithCluster('cluster.geoHash', async cluster => {
assert.deepEqual(
await cluster.geoHash('key', 'member'),
[null]
);
}, GLOBAL.CLUSTERS.OPEN);
}, {
client: GLOBAL.SERVERS.OPEN,
cluster: GLOBAL.CLUSTERS.OPEN
});
});

View File

@@ -1,52 +1,35 @@
import { strict as assert } from 'assert';
import testUtils, { GLOBAL } from '../test-utils';
import { transformArguments, transformReply } from './GEOPOS';
import GEOPOS from './GEOPOS';
describe('GEOPOS', () => {
describe('transformArguments', () => {
it('single member', () => {
assert.deepEqual(
transformArguments('key', 'member'),
GEOPOS.transformArguments('key', 'member'),
['GEOPOS', 'key', 'member']
);
});
it('multiple members', () => {
assert.deepEqual(
transformArguments('key', ['1', '2']),
GEOPOS.transformArguments('key', ['1', '2']),
['GEOPOS', 'key', '1', '2']
);
});
});
describe('transformReply', () => {
it('null', () => {
assert.deepEqual(
transformReply([null]),
[null]
);
});
it('with member', () => {
assert.deepEqual(
transformReply([['1', '2']]),
[{
longitude: '1',
latitude: '2'
}]
);
});
});
describe('client.geoPos', () => {
testUtils.testWithClient('null', async client => {
testUtils.testAll('geoPos null', async client => {
assert.deepEqual(
await client.geoPos('key', 'member'),
[null]
);
}, GLOBAL.SERVERS.OPEN);
}, {
client: GLOBAL.SERVERS.OPEN,
cluster: GLOBAL.CLUSTERS.OPEN
});
testUtils.testWithClient('with member', async client => {
testUtils.testAll('geoPos with member', async client => {
const coordinates = {
longitude: '-122.06429868936538696',
latitude: '37.37749628831998194'
@@ -61,13 +44,8 @@ describe('GEOPOS', () => {
await client.geoPos('key', 'member'),
[coordinates]
);
}, GLOBAL.SERVERS.OPEN);
}, {
client: GLOBAL.SERVERS.OPEN,
cluster: GLOBAL.CLUSTERS.OPEN
});
testUtils.testWithCluster('cluster.geoPos', async cluster => {
assert.deepEqual(
await cluster.geoPos('key', 'member'),
[null]
);
}, GLOBAL.CLUSTERS.OPEN);
});

View File

@@ -1,35 +1,28 @@
import { strict as assert } from 'assert';
import testUtils, { GLOBAL } from '../test-utils';
import { transformArguments } from './GEORADIUS';
import GEORADIUS from './GEORADIUS';
describe('GEORADIUS', () => {
it('transformArguments', () => {
assert.deepEqual(
transformArguments('key', {
GEORADIUS.transformArguments('key', {
longitude: 1,
latitude: 2
}, 3 , 'm'),
}, 3, 'm'),
['GEORADIUS', 'key', '1', '2', '3', 'm']
);
});
testUtils.testWithClient('client.geoRadius', async client => {
testUtils.testAll('geoRadius', async client => {
assert.deepEqual(
await client.geoRadius('key', {
longitude: 1,
latitude: 2
}, 3 , 'm'),
}, 3, 'm'),
[]
);
}, GLOBAL.SERVERS.OPEN);
testUtils.testWithCluster('cluster.geoRadius', async cluster => {
assert.deepEqual(
await cluster.geoRadius('key', {
longitude: 1,
latitude: 2
}, 3 , 'm'),
[]
);
}, GLOBAL.CLUSTERS.OPEN);
}, {
client: GLOBAL.SERVERS.OPEN,
cluster: GLOBAL.CLUSTERS.OPEN
});
});

View File

@@ -1,25 +1,32 @@
// import { RedisCommandArgument, RedisCommandArguments } from '.';
// import { GeoSearchOptions, GeoCoordinates, pushGeoRadiusArguments, GeoUnits } from './generic-transformers';
import { RedisArgument, ArrayReply, BlobStringReply, Command } from '../RESP/types';
import { GeoCoordinates, GeoUnits, GeoSearchOptions, pushGeoSearchOptions } from './GEOSEARCH';
// export const FIRST_KEY_INDEX = 1;
export function transformGeoRadiusArguments(
command: RedisArgument,
key: RedisArgument,
from: GeoCoordinates,
radius: number,
unit: GeoUnits,
options?: GeoSearchOptions
) {
const args = [
command,
key,
from.longitude.toString(),
from.latitude.toString(),
radius.toString(),
unit
];
// export const IS_READ_ONLY = true;
pushGeoSearchOptions(args, options);
// export function transformArguments(
// key: RedisCommandArgument,
// coordinates: GeoCoordinates,
// radius: number,
// unit: GeoUnits,
// options?: GeoSearchOptions
// ): RedisCommandArguments {
// return pushGeoRadiusArguments(
// ['GEORADIUS'],
// key,
// coordinates,
// radius,
// unit,
// options
// );
// }
return args;
}
export default {
FIRST_KEY_INDEX: 1,
IS_READ_ONLY: false,
transformArguments: transformGeoRadiusArguments.bind(undefined, 'GEORADIUS'),
transformReply: undefined as unknown as () => ArrayReply<BlobStringReply>
} as const satisfies Command;
// export declare function transformReply(): Array<RedisCommandArgument>;

View File

@@ -1,26 +1,22 @@
import { strict as assert } from 'assert';
import testUtils, { GLOBAL } from '../test-utils';
import { transformArguments } from './GEORADIUSBYMEMBER';
import GEORADIUSBYMEMBER from './GEORADIUSBYMEMBER';
describe('GEORADIUSBYMEMBER', () => {
it('transformArguments', () => {
assert.deepEqual(
transformArguments('key', 'member', 3 , 'm'),
GEORADIUSBYMEMBER.transformArguments('key', 'member', 3, 'm'),
['GEORADIUSBYMEMBER', 'key', 'member', '3', 'm']
);
});
testUtils.testWithClient('client.geoRadiusByMember', async client => {
testUtils.testAll('geoRadiusByMember', async client => {
assert.deepEqual(
await client.geoRadiusByMember('key', 'member', 3 , 'm'),
await client.geoRadiusByMember('key', 'member', 3, 'm'),
[]
);
}, GLOBAL.SERVERS.OPEN);
testUtils.testWithCluster('cluster.geoRadiusByMember', async cluster => {
assert.deepEqual(
await cluster.geoRadiusByMember('key', 'member', 3 , 'm'),
[]
);
}, GLOBAL.CLUSTERS.OPEN);
}, {
client: GLOBAL.SERVERS.OPEN,
cluster: GLOBAL.CLUSTERS.OPEN
});
});

View File

@@ -1,25 +1,30 @@
// import { RedisCommandArgument, RedisCommandArguments } from '.';
// import { GeoSearchOptions, pushGeoRadiusArguments, GeoUnits } from './generic-transformers';
import { RedisArgument, ArrayReply, BlobStringReply, Command } from '../RESP/types';
import { GeoUnits, GeoSearchOptions, pushGeoSearchOptions } from './GEOSEARCH';
// export const FIRST_KEY_INDEX = 1;
export function transformGeoRadiusByMemberArguments(
command: RedisArgument,
key: RedisArgument,
from: RedisArgument,
radius: number,
unit: GeoUnits,
options?: GeoSearchOptions
) {
const args = [
command,
key,
from,
radius.toString(),
unit
];
// export const IS_READ_ONLY = true;
pushGeoSearchOptions(args, options);
// export function transformArguments(
// key: RedisCommandArgument,
// member: string,
// radius: number,
// unit: GeoUnits,
// options?: GeoSearchOptions
// ): RedisCommandArguments {
// return pushGeoRadiusArguments(
// ['GEORADIUSBYMEMBER'],
// key,
// member,
// radius,
// unit,
// options
// );
// }
return args;
}
// export declare function transformReply(): Array<RedisCommandArgument>;
export default {
FIRST_KEY_INDEX: 1,
IS_READ_ONLY: false,
transformArguments: transformGeoRadiusByMemberArguments.bind(undefined, 'GEORADIUSBYMEMBER'),
transformReply: undefined as unknown as () => ArrayReply<BlobStringReply>
} as const satisfies Command;

View File

@@ -1,53 +0,0 @@
import { strict as assert } from 'assert';
import testUtils, { GLOBAL } from '../test-utils';
import { transformArguments, transformReply } from './GEORADIUSBYMEMBERSTORE';
describe('GEORADIUSBYMEMBERSTORE', () => {
describe('transformArguments', () => {
it('STORE', () => {
assert.deepEqual(
transformArguments('key', 'member', 3 , 'm', 'dest', {
SORT: 'ASC',
COUNT: {
value: 1,
ANY: true
}
}),
['GEORADIUSBYMEMBER', 'key', 'member', '3', 'm', 'ASC', 'COUNT', '1', 'ANY', 'STORE', 'dest']
);
});
it('STOREDIST', () => {
assert.deepEqual(
transformArguments('key', 'member', 3 , 'm', 'dest', { STOREDIST: true }),
['GEORADIUSBYMEMBER', 'key', 'member', '3', 'm', 'STOREDIST', 'dest']
);
});
});
testUtils.testWithClient('client.geoRadiusByMemberStore', async client => {
await client.geoAdd('source', {
longitude: 1,
latitude: 1,
member: 'member'
});
assert.equal(
await client.geoRadiusByMemberStore('source', 'member', 3 , 'm', 'dest'),
1
);
}, GLOBAL.SERVERS.OPEN);
testUtils.testWithCluster('cluster.geoRadiusByMemberStore', async cluster => {
await cluster.geoAdd('{tag}source', {
longitude: 1,
latitude: 1,
member: 'member'
});
assert.equal(
await cluster.geoRadiusByMemberStore('{tag}source', 'member', 3 , 'm','{tag}destination'),
1
);
}, GLOBAL.CLUSTERS.OPEN);
});

View File

@@ -1,25 +0,0 @@
// import { RedisCommandArgument, RedisCommandArguments } from '.';
// import { GeoUnits, GeoRadiusStoreOptions, pushGeoRadiusStoreArguments } from './generic-transformers';
// export { FIRST_KEY_INDEX, IS_READ_ONLY } from './GEORADIUSBYMEMBER';
// export function transformArguments(
// key: RedisCommandArgument,
// member: string,
// radius: number,
// unit: GeoUnits,
// destination: RedisCommandArgument,
// options?: GeoRadiusStoreOptions,
// ): RedisCommandArguments {
// return pushGeoRadiusStoreArguments(
// ['GEORADIUSBYMEMBER'],
// key,
// member,
// radius,
// unit,
// destination,
// options
// );
// }
// export declare function transformReply(): number

View File

@@ -1,26 +1,22 @@
import { strict as assert } from 'assert';
import testUtils, { GLOBAL } from '../test-utils';
import { transformArguments } from './GEORADIUSBYMEMBER_RO';
import GEORADIUSBYMEMBER_RO from './GEORADIUSBYMEMBER_RO';
describe('GEORADIUSBYMEMBER_RO', () => {
it('transformArguments', () => {
assert.deepEqual(
transformArguments('key', 'member', 3 , 'm'),
GEORADIUSBYMEMBER_RO.transformArguments('key', 'member', 3, 'm'),
['GEORADIUSBYMEMBER_RO', 'key', 'member', '3', 'm']
);
});
testUtils.testWithClient('client.geoRadiusByMemberRo', async client => {
testUtils.testAll('geoRadiusByMemberRo', async client => {
assert.deepEqual(
await client.geoRadiusByMemberRo('key', 'member', 3 , 'm'),
await client.geoRadiusByMemberRo('key', 'member', 3, 'm'),
[]
);
}, GLOBAL.SERVERS.OPEN);
testUtils.testWithCluster('cluster.geoRadiusByMemberRo', async cluster => {
assert.deepEqual(
await cluster.geoRadiusByMemberRo('key', 'member', 3 , 'm'),
[]
);
}, GLOBAL.CLUSTERS.OPEN);
}, {
client: GLOBAL.SERVERS.OPEN,
cluster: GLOBAL.CLUSTERS.OPEN
});
});

View File

@@ -1,25 +1,9 @@
// import { RedisCommandArgument, RedisCommandArguments } from '.';
// import { GeoSearchOptions, pushGeoRadiusArguments, GeoUnits } from './generic-transformers';
import { Command } from '../RESP/types';
import GEORADIUSBYMEMBER, { transformGeoRadiusByMemberArguments } from './GEORADIUSBYMEMBER';
// export const FIRST_KEY_INDEX = 1;
// export const IS_READ_ONLY = true;
// export function transformArguments(
// key: RedisCommandArgument,
// member: string,
// radius: number,
// unit: GeoUnits,
// options?: GeoSearchOptions
// ): RedisCommandArguments {
// return pushGeoRadiusArguments(
// ['GEORADIUSBYMEMBER_RO'],
// key,
// member,
// radius,
// unit,
// options
// );
// }
// export declare function transformReply(): Array<RedisCommandArgument>;
export default {
FIRST_KEY_INDEX: GEORADIUSBYMEMBER.FIRST_KEY_INDEX,
IS_READ_ONLY: true,
transformArguments: transformGeoRadiusByMemberArguments.bind(undefined, 'GEORADIUSBYMEMBER_RO'),
transformReply: GEORADIUSBYMEMBER.transformReply
} as const satisfies Command;

View File

@@ -1,31 +1,44 @@
import { strict as assert } from 'assert';
import testUtils, { GLOBAL } from '../test-utils';
import { RedisCommandArguments } from '.';
import { GeoReplyWith } from './generic-transformers';
import { transformArguments } from './GEORADIUSBYMEMBER_RO_WITH';
import GEORADIUSBYMEMBER_RO_WITH from './GEORADIUSBYMEMBER_RO_WITH';
import { CommandArguments } from '../RESP/types';
import { GEO_REPLY_WITH } from './GEOSEARCH_WITH';
describe('GEORADIUSBYMEMBER_RO WITH', () => {
it('transformArguments', () => {
const expectedReply: RedisCommandArguments = ['GEORADIUSBYMEMBER_RO', 'key', 'member', '3', 'm', 'WITHDIST'];
const expectedReply: CommandArguments = ['GEORADIUSBYMEMBER_RO', 'key', 'member', '3', 'm', 'WITHDIST'];
expectedReply.preserve = ['WITHDIST'];
assert.deepEqual(
transformArguments('key', 'member', 3 , 'm', [GeoReplyWith.DISTANCE]),
GEORADIUSBYMEMBER_RO_WITH.transformArguments('key', 'member', 3, 'm', [
GEO_REPLY_WITH.DISTANCE
]),
expectedReply
);
});
testUtils.testWithClient('client.geoRadiusByMemberRoWith', async client => {
assert.deepEqual(
await client.geoRadiusByMemberRoWith('key', 'member', 3 , 'm', [GeoReplyWith.DISTANCE]),
[]
);
}, GLOBAL.SERVERS.OPEN);
testUtils.testAll('geoRadiusByMemberRoWith', async client => {
const [, reply] = await Promise.all([
client.geoAdd('key', {
member: 'member',
longitude: 1,
latitude: 2
}),
client.geoRadiusByMemberRoWith('key', 'member', 1, 'm', [
GEO_REPLY_WITH.HASH,
GEO_REPLY_WITH.DISTANCE,
GEO_REPLY_WITH.COORDINATES
])
]);
testUtils.testWithCluster('cluster.geoRadiusByMemberRoWith', async cluster => {
assert.deepEqual(
await cluster.geoRadiusByMemberRoWith('key', 'member', 3 , 'm', [GeoReplyWith.DISTANCE]),
[]
);
}, GLOBAL.CLUSTERS.OPEN);
assert.equal(reply.length, 1);
assert.equal(reply[0].member, 'member');
assert.equal(typeof reply[0].distance, 'string');
assert.equal(typeof reply[0].hash, 'number');
assert.equal(typeof reply[0].coordinates?.longitude, 'string');
assert.equal(typeof reply[0].coordinates?.latitude, 'string');
}, {
client: GLOBAL.SERVERS.OPEN,
cluster: GLOBAL.CLUSTERS.OPEN
});
});

View File

@@ -1,30 +1,9 @@
// import { RedisCommandArgument, RedisCommandArguments } from '.';
// import { GeoReplyWith, GeoSearchOptions, GeoUnits } from './generic-transformers';
// import { transformArguments as geoRadiusTransformArguments } from './GEORADIUSBYMEMBER_RO';
import { Command } from '../RESP/types';
import GEORADIUSBYMEMBER_WITH, { transformGeoRadiusByMemberWithArguments } from './GEORADIUSBYMEMBER_WITH';
// export { FIRST_KEY_INDEX, IS_READ_ONLY } from './GEORADIUSBYMEMBER_RO';
// export function transformArguments(
// key: RedisCommandArgument,
// member: string,
// radius: number,
// unit: GeoUnits,
// replyWith: Array<GeoReplyWith>,
// options?: GeoSearchOptions
// ): RedisCommandArguments {
// const args: RedisCommandArguments = geoRadiusTransformArguments(
// key,
// member,
// radius,
// unit,
// options
// );
// args.push(...replyWith);
// args.preserve = replyWith;
// return args;
// }
// export { transformGeoMembersWithReply as transformReply } from './generic-transformers';
export default {
FIRST_KEY_INDEX: GEORADIUSBYMEMBER_WITH.FIRST_KEY_INDEX,
IS_READ_ONLY: true,
transformArguments: transformGeoRadiusByMemberWithArguments.bind(undefined, 'GEORADIUSBYMEMBER_RO'),
transformReply: GEORADIUSBYMEMBER_WITH.transformReply
} as const satisfies Command;

View File

@@ -0,0 +1,39 @@
import { strict as assert } from 'assert';
import testUtils, { GLOBAL } from '../test-utils';
import GEORADIUSBYMEMBER_STORE from './GEORADIUSBYMEMBER_STORE';
describe('GEORADIUSBYMEMBER STORE', () => {
describe('transformArguments', () => {
it('STORE', () => {
assert.deepEqual(
GEORADIUSBYMEMBER_STORE.transformArguments('key', 'member', 3, 'm', 'destination'),
['GEORADIUSBYMEMBER', 'key', 'member', '3', 'm', 'STORE', 'destination']
);
});
it('STOREDIST', () => {
assert.deepEqual(
GEORADIUSBYMEMBER_STORE.transformArguments('key', 'member', 3, 'm', 'destination', {
STOREDIST: true
}),
['GEORADIUSBYMEMBER', 'key', 'member', '3', 'm', 'STOREDIST', 'destination']
);
});
});
testUtils.testAll('geoRadiusByMemberStore', async client => {
const [, reply] = await Promise.all([
client.geoAdd('{tag}source', {
longitude: 1,
latitude: 2,
member: 'member'
}),
client.geoRadiusByMemberStore('{tag}source', 'member', 3, 'm', '{tag}destination')
]);
assert.equal(reply, 1);
}, {
client: GLOBAL.SERVERS.OPEN,
cluster: GLOBAL.CLUSTERS.OPEN
});
});

View File

@@ -0,0 +1,31 @@
import { RedisArgument, NumberReply, Command } from '../RESP/types';
import GEORADIUSBYMEMBER, { transformGeoRadiusByMemberArguments } from './GEORADIUSBYMEMBER';
import { GeoSearchOptions, GeoUnits } from './GEOSEARCH';
export interface GeoRadiusStoreOptions extends GeoSearchOptions {
STOREDIST?: boolean;
}
export default {
FIRST_KEY_INDEX: GEORADIUSBYMEMBER.FIRST_KEY_INDEX,
IS_READ_ONLY: GEORADIUSBYMEMBER.IS_READ_ONLY,
transformArguments(
key: RedisArgument,
from: RedisArgument,
radius: number,
unit: GeoUnits,
destination: RedisArgument,
options?: GeoRadiusStoreOptions
) {
const args = transformGeoRadiusByMemberArguments('GEORADIUSBYMEMBER', key, from, radius, unit, options);
if (options?.STOREDIST) {
args.push('STOREDIST', destination);
} else {
args.push('STORE', destination);
}
return args;
},
transformReply: undefined as unknown as () => NumberReply
} as const satisfies Command;

View File

@@ -1,31 +1,44 @@
import { strict as assert } from 'assert';
import testUtils, { GLOBAL } from '../test-utils';
import { RedisCommandArguments } from '.';
import { GeoReplyWith } from './generic-transformers';
import { transformArguments } from './GEORADIUSBYMEMBER_WITH';
import GEORADIUSBYMEMBER_WITH from './GEORADIUSBYMEMBER_WITH';
import { CommandArguments } from '../RESP/types';
import { GEO_REPLY_WITH } from './GEOSEARCH_WITH';
describe('GEORADIUSBYMEMBER WITH', () => {
it('transformArguments', () => {
const expectedReply: RedisCommandArguments = ['GEORADIUSBYMEMBER', 'key', 'member', '3', 'm', 'WITHDIST'];
const expectedReply: CommandArguments = ['GEORADIUSBYMEMBER', 'key', 'member', '3', 'm', 'WITHDIST'];
expectedReply.preserve = ['WITHDIST'];
assert.deepEqual(
transformArguments('key', 'member', 3 , 'm', [GeoReplyWith.DISTANCE]),
GEORADIUSBYMEMBER_WITH.transformArguments('key', 'member', 3, 'm', [
GEO_REPLY_WITH.DISTANCE
]),
expectedReply
);
});
testUtils.testWithClient('client.geoRadiusByMemberWith', async client => {
assert.deepEqual(
await client.geoRadiusByMemberWith('key', 'member', 3 , 'm', [GeoReplyWith.DISTANCE]),
[]
);
}, GLOBAL.SERVERS.OPEN);
testUtils.testAll('geoRadiusByMemberWith', async client => {
const [, reply] = await Promise.all([
client.geoAdd('key', {
member: 'member',
longitude: 1,
latitude: 2
}),
client.geoRadiusByMemberWith('key', 'member', 1, 'm', [
GEO_REPLY_WITH.HASH,
GEO_REPLY_WITH.DISTANCE,
GEO_REPLY_WITH.COORDINATES
])
]);
testUtils.testWithCluster('cluster.geoRadiusByMemberWith', async cluster => {
assert.deepEqual(
await cluster.geoRadiusByMemberWith('key', 'member', 3 , 'm', [GeoReplyWith.DISTANCE]),
[]
);
}, GLOBAL.CLUSTERS.OPEN);
assert.equal(reply.length, 1);
assert.equal(reply[0].member, 'member');
assert.equal(typeof reply[0].distance, 'string');
assert.equal(typeof reply[0].hash, 'number');
assert.equal(typeof reply[0].coordinates!.longitude, 'string');
assert.equal(typeof reply[0].coordinates!.latitude, 'string');
}, {
client: GLOBAL.SERVERS.OPEN,
cluster: GLOBAL.CLUSTERS.OPEN
});
});

View File

@@ -1,30 +1,36 @@
// import { RedisCommandArgument, RedisCommandArguments } from '.';
// import { GeoReplyWith, GeoSearchOptions, GeoUnits } from './generic-transformers';
// import { transformArguments as transformGeoRadiusArguments } from './GEORADIUSBYMEMBER';
import { RedisArgument, CommandArguments, ArrayReply, BlobStringReply, Command } from '../RESP/types';
import GEORADIUSBYMEMBER from './GEORADIUSBYMEMBER';
import { GeoSearchOptions, GeoUnits, pushGeoSearchOptions } from './GEOSEARCH';
import GEOSEARCH_WITH, { GeoReplyWith } from './GEOSEARCH_WITH';
// export { FIRST_KEY_INDEX, IS_READ_ONLY } from './GEORADIUSBYMEMBER';
export function transformGeoRadiusByMemberWithArguments(
command: RedisArgument,
key: RedisArgument,
from: RedisArgument,
radius: number,
unit: GeoUnits,
replyWith: Array<GeoReplyWith>,
options?: GeoSearchOptions
) {
const args: CommandArguments = [
command,
key,
from,
radius.toString(),
unit
];
// export function transformArguments(
// key: RedisCommandArgument,
// member: string,
// radius: number,
// unit: GeoUnits,
// replyWith: Array<GeoReplyWith>,
// options?: GeoSearchOptions
// ): RedisCommandArguments {
// const args: RedisCommandArguments = transformGeoRadiusArguments(
// key,
// member,
// radius,
// unit,
// options
// );
pushGeoSearchOptions(args, options);
// args.push(...replyWith);
args.push(...replyWith);
args.preserve = replyWith;
// args.preserve = replyWith;
return args;
}
// return args;
// }
// export { transformGeoMembersWithReply as transformReply } from './generic-transformers';
export default {
FIRST_KEY_INDEX: GEORADIUSBYMEMBER.FIRST_KEY_INDEX,
IS_READ_ONLY: GEORADIUSBYMEMBER.IS_READ_ONLY,
transformArguments: transformGeoRadiusByMemberWithArguments.bind(undefined, 'GEORADIUSBYMEMBER'),
transformReply: GEOSEARCH_WITH.transformReply
} as const satisfies Command;

View File

@@ -1,53 +0,0 @@
import { strict as assert } from 'assert';
import testUtils, { GLOBAL } from '../test-utils';
import { transformArguments, transformReply } from './GEORADIUSSTORE';
describe('GEORADIUSSTORE', () => {
describe('transformArguments', () => {
it('STORE', () => {
assert.deepEqual(
transformArguments('key', {longitude: 1, latitude: 2}, 3 , 'm', 'dest', {
SORT: 'ASC',
COUNT: {
value: 1,
ANY: true
}
}),
['GEORADIUS', 'key', '1', '2', '3', 'm', 'ASC', 'COUNT', '1', 'ANY', 'STORE', 'dest']
);
});
it('STOREDIST', () => {
assert.deepEqual(
transformArguments('key', {longitude: 1, latitude: 2}, 3 , 'm', 'dest', { STOREDIST: true }),
['GEORADIUS', 'key', '1', '2', '3', 'm', 'STOREDIST', 'dest']
);
});
});
testUtils.testWithClient('client.geoRadiusStore', async client => {
await client.geoAdd('source', {
longitude: 1,
latitude: 1,
member: 'member'
});
assert.equal(
await client.geoRadiusStore('source', {longitude: 1, latitude: 1}, 3 , 'm', 'dest'),
1
);
}, GLOBAL.SERVERS.OPEN);
testUtils.testWithCluster('cluster.geoRadiusStore', async cluster => {
await cluster.geoAdd('{tag}source', {
longitude: 1,
latitude: 1,
member: 'member'
});
assert.equal(
await cluster.geoRadiusStore('{tag}source', {longitude: 1, latitude: 1}, 3 , 'm', '{tag}destination'),
1
);
}, GLOBAL.CLUSTERS.OPEN);
});

View File

@@ -1,25 +0,0 @@
// import { RedisCommandArgument, RedisCommandArguments } from '.';
// import { GeoCoordinates, GeoUnits, GeoRadiusStoreOptions, pushGeoRadiusStoreArguments } from './generic-transformers';
// export { FIRST_KEY_INDEX, IS_READ_ONLY } from './GEORADIUS';
// export function transformArguments(
// key: RedisCommandArgument,
// coordinates: GeoCoordinates,
// radius: number,
// unit: GeoUnits,
// destination: RedisCommandArgument,
// options?: GeoRadiusStoreOptions,
// ): RedisCommandArguments {
// return pushGeoRadiusStoreArguments(
// ['GEORADIUS'],
// key,
// coordinates,
// radius,
// unit,
// destination,
// options
// );
// }
// export declare function transformReply(): number;

View File

@@ -1,35 +1,28 @@
import { strict as assert } from 'assert';
import testUtils, { GLOBAL } from '../test-utils';
import { transformArguments } from './GEORADIUS_RO';
import GEORADIUS_RO from './GEORADIUS_RO';
describe('GEORADIUS_RO', () => {
it('transformArguments', () => {
assert.deepEqual(
transformArguments('key', {
GEORADIUS_RO.transformArguments('key', {
longitude: 1,
latitude: 2
}, 3 , 'm'),
}, 3, 'm'),
['GEORADIUS_RO', 'key', '1', '2', '3', 'm']
);
});
testUtils.testWithClient('client.geoRadiusRo', async client => {
testUtils.testAll('geoRadiusRo', async client => {
assert.deepEqual(
await client.geoRadiusRo('key', {
longitude: 1,
latitude: 2
}, 3 , 'm'),
}, 3, 'm'),
[]
);
}, GLOBAL.SERVERS.OPEN);
testUtils.testWithCluster('cluster.geoRadiusRo', async cluster => {
assert.deepEqual(
await cluster.geoRadiusRo('key', {
longitude: 1,
latitude: 2
}, 3 , 'm'),
[]
);
}, GLOBAL.CLUSTERS.OPEN);
}, {
client: GLOBAL.SERVERS.OPEN,
cluster: GLOBAL.CLUSTERS.OPEN
});
});

View File

@@ -1,25 +1,9 @@
// import { RedisCommandArgument, RedisCommandArguments } from '.';
// import { GeoSearchOptions, GeoCoordinates, pushGeoRadiusArguments, GeoUnits } from './generic-transformers';
import { Command } from '../RESP/types';
import GEORADIUS, { transformGeoRadiusArguments } from './GEORADIUS';
// export const FIRST_KEY_INDEX = 1;
// export const IS_READ_ONLY = true;
// export function transformArguments(
// key: RedisCommandArgument,
// coordinates: GeoCoordinates,
// radius: number,
// unit: GeoUnits,
// options?: GeoSearchOptions
// ): RedisCommandArguments {
// return pushGeoRadiusArguments(
// ['GEORADIUS_RO'],
// key,
// coordinates,
// radius,
// unit,
// options
// );
// }
// export declare function transformReply(): Array<RedisCommandArgument>;
export default {
FIRST_KEY_INDEX: GEORADIUS.FIRST_KEY_INDEX,
IS_READ_ONLY: true,
transformArguments: transformGeoRadiusArguments.bind(undefined, 'GEORADIUS_RO'),
transformReply: GEORADIUS.transformReply
} as const satisfies Command;

View File

@@ -1,40 +1,48 @@
import { strict as assert } from 'assert';
import testUtils, { GLOBAL } from '../test-utils';
import { RedisCommandArguments } from '.';
import { GeoReplyWith } from './generic-transformers';
import { transformArguments } from './GEORADIUS_RO_WITH';
import GEORADIUS_RO_WITH from './GEORADIUS_RO_WITH';
import { GEO_REPLY_WITH } from './GEOSEARCH_WITH';
import { CommandArguments } from '../RESP/types';
describe('GEORADIUS_RO WITH', () => {
it('transformArguments', () => {
const expectedReply: RedisCommandArguments = ['GEORADIUS_RO', 'key', '1', '2', '3', 'm', 'WITHDIST'];
const expectedReply: CommandArguments = ['GEORADIUS_RO', 'key', '1', '2', '3', 'm', 'WITHDIST'];
expectedReply.preserve = ['WITHDIST'];
assert.deepEqual(
transformArguments('key', {
GEORADIUS_RO_WITH.transformArguments('key', {
longitude: 1,
latitude: 2
}, 3 , 'm', [GeoReplyWith.DISTANCE]),
}, 3, 'm', [GEO_REPLY_WITH.DISTANCE]),
expectedReply
);
});
testUtils.testWithClient('client.geoRadiusRoWith', async client => {
assert.deepEqual(
await client.geoRadiusRoWith('key', {
testUtils.testAll('geoRadiusRoWith', async client => {
const [, reply] = await Promise.all([
client.geoAdd('key', {
member: 'member',
longitude: 1,
latitude: 2
}, 3 , 'm', [GeoReplyWith.DISTANCE]),
[]
);
}, GLOBAL.SERVERS.OPEN);
}),
client.geoRadiusRoWith('key', {
longitude: 1,
latitude: 2
}, 1, 'm', [
GEO_REPLY_WITH.HASH,
GEO_REPLY_WITH.DISTANCE,
GEO_REPLY_WITH.COORDINATES
])
]);
testUtils.testWithCluster('cluster.geoRadiusReadOnlyWith', async cluster => {
assert.deepEqual(
await cluster.geoRadiusRoWith('key', {
longitude: 1,
latitude: 2
}, 3 , 'm', [GeoReplyWith.DISTANCE]),
[]
);
}, GLOBAL.CLUSTERS.OPEN);
assert.equal(reply.length, 1);
assert.equal(reply[0].member, 'member');
assert.equal(typeof reply[0].distance, 'string');
assert.equal(typeof reply[0].hash, 'number');
assert.equal(typeof reply[0].coordinates!.longitude, 'string');
assert.equal(typeof reply[0].coordinates!.latitude, 'string');
}, {
client: GLOBAL.SERVERS.OPEN,
cluster: GLOBAL.CLUSTERS.OPEN
});
});

View File

@@ -1,30 +1,9 @@
// import { RedisCommandArgument, RedisCommandArguments } from '.';
// import { GeoReplyWith, GeoSearchOptions, GeoCoordinates, GeoUnits } from './generic-transformers';
// import { transformArguments as transformGeoRadiusRoArguments } from './GEORADIUS_RO';
import { Command } from '../RESP/types';
import GEORADIUS_WITH, { transformGeoRadiusWithArguments } from './GEORADIUS_WITH';
// export { FIRST_KEY_INDEX, IS_READ_ONLY } from './GEORADIUS_RO';
// export function transformArguments(
// key: RedisCommandArgument,
// coordinates: GeoCoordinates,
// radius: number,
// unit: GeoUnits,
// replyWith: Array<GeoReplyWith>,
// options?: GeoSearchOptions
// ): RedisCommandArguments {
// const args: RedisCommandArguments = transformGeoRadiusRoArguments(
// key,
// coordinates,
// radius,
// unit,
// options
// );
// args.push(...replyWith);
// args.preserve = replyWith;
// return args;
// }
// export { transformGeoMembersWithReply as transformReply } from './generic-transformers';
export default {
FIRST_KEY_INDEX: GEORADIUS_WITH.FIRST_KEY_INDEX,
IS_READ_ONLY: true,
transformArguments: transformGeoRadiusWithArguments.bind(undefined, 'GEORADIUS_RO'),
transformReply: GEORADIUS_WITH.transformReply
} as const satisfies Command;

View File

@@ -0,0 +1,48 @@
import { strict as assert } from 'assert';
import testUtils, { GLOBAL } from '../test-utils';
import GEORADIUS_STORE from './GEORADIUS_STORE';
describe('GEORADIUS STORE', () => {
describe('transformArguments', () => {
it('STORE', () => {
assert.deepEqual(
GEORADIUS_STORE.transformArguments('key', {
longitude: 1,
latitude: 2
}, 3, 'm', 'destination'),
['GEORADIUS', 'key', '1', '2', '3', 'm', 'STORE', 'destination']
);
});
it('STOREDIST', () => {
assert.deepEqual(
GEORADIUS_STORE.transformArguments('key', {
longitude: 1,
latitude: 2
}, 3, 'm', 'destination', {
STOREDIST: true
}),
['GEORADIUS', 'key', '1', '2', '3', 'm', 'STOREDIST', 'destination']
);
});
});
testUtils.testAll('geoRadiusStore', async client => {
const [, reply] = await Promise.all([
client.geoAdd('{tag}source', {
longitude: 1,
latitude: 2,
member: 'member'
}),
client.geoRadiusStore('{tag}source', {
longitude: 1,
latitude: 2
}, 1, 'm', '{tag}destination')
]);
assert.equal(reply, 1);
}, {
client: GLOBAL.SERVERS.OPEN,
cluster: GLOBAL.CLUSTERS.OPEN
});
});

View File

@@ -0,0 +1,31 @@
import { RedisArgument, NumberReply, Command } from '../RESP/types';
import GEORADIUS, { transformGeoRadiusArguments } from './GEORADIUS';
import { GeoCoordinates, GeoSearchOptions, GeoUnits } from './GEOSEARCH';
export interface GeoRadiusStoreOptions extends GeoSearchOptions {
STOREDIST?: boolean;
}
export default {
FIRST_KEY_INDEX: GEORADIUS.FIRST_KEY_INDEX,
IS_READ_ONLY: GEORADIUS.IS_READ_ONLY,
transformArguments(
key: RedisArgument,
from: GeoCoordinates,
radius: number,
unit: GeoUnits,
destination: RedisArgument,
options?: GeoRadiusStoreOptions
) {
const args = transformGeoRadiusArguments('GEORADIUS', key, from, radius, unit, options);
if (options?.STOREDIST) {
args.push('STOREDIST', destination);
} else {
args.push('STORE', destination);
}
return args;
},
transformReply: undefined as unknown as () => NumberReply
} as const satisfies Command;

View File

@@ -1,40 +1,48 @@
import { strict as assert } from 'assert';
import testUtils, { GLOBAL } from '../test-utils';
import { RedisCommandArguments } from '.';
import { GeoReplyWith } from './generic-transformers';
import { transformArguments } from './GEORADIUS_WITH';
import GEORADIUS_WITH from './GEORADIUS_WITH';
import { GEO_REPLY_WITH } from './GEOSEARCH_WITH';
import { CommandArguments } from '../RESP/types';
describe('GEORADIUS WITH', () => {
it('transformArguments', () => {
const expectedReply: RedisCommandArguments = ['GEORADIUS', 'key', '1', '2', '3', 'm', 'WITHDIST'];
const expectedReply: CommandArguments = ['GEORADIUS', 'key', '1', '2', '3', 'm', 'WITHDIST'];
expectedReply.preserve = ['WITHDIST'];
assert.deepEqual(
transformArguments('key', {
GEORADIUS_WITH.transformArguments('key', {
longitude: 1,
latitude: 2
}, 3 , 'm', [GeoReplyWith.DISTANCE]),
}, 3, 'm', [GEO_REPLY_WITH.DISTANCE]),
expectedReply
);
});
testUtils.testWithClient('client.geoRadiusWith', async client => {
assert.deepEqual(
await client.geoRadiusWith('key', {
testUtils.testAll('geoRadiusWith', async client => {
const [, reply] = await Promise.all([
client.geoAdd('key', {
member: 'member',
longitude: 1,
latitude: 2
}, 3 , 'm', [GeoReplyWith.DISTANCE]),
[]
);
}, GLOBAL.SERVERS.OPEN);
}),
client.geoRadiusWith('key', {
longitude: 1,
latitude: 2
}, 1, 'm', [
GEO_REPLY_WITH.HASH,
GEO_REPLY_WITH.DISTANCE,
GEO_REPLY_WITH.COORDINATES
])
]);
testUtils.testWithCluster('cluster.geoRadiusWith', async cluster => {
assert.deepEqual(
await cluster.geoRadiusWith('key', {
longitude: 1,
latitude: 2
}, 3 , 'm', [GeoReplyWith.DISTANCE]),
[]
);
}, GLOBAL.CLUSTERS.OPEN);
assert.equal(reply.length, 1);
assert.equal(reply[0].member, 'member');
assert.equal(typeof reply[0].distance, 'string');
assert.equal(typeof reply[0].hash, 'number');
assert.equal(typeof reply[0].coordinates?.longitude, 'string');
assert.equal(typeof reply[0].coordinates?.latitude, 'string');
}, {
client: GLOBAL.SERVERS.OPEN,
cluster: GLOBAL.CLUSTERS.OPEN
});
});

View File

@@ -1,30 +1,33 @@
// import { RedisCommandArgument, RedisCommandArguments } from '.';
// import { GeoReplyWith, GeoSearchOptions, GeoCoordinates, GeoUnits } from './generic-transformers';
// import { transformArguments as transformGeoRadiusArguments } from './GEORADIUS';
import { CommandArguments, Command, RedisArgument } from '../RESP/types';
import GEORADIUS, { transformGeoRadiusArguments } from './GEORADIUS';
import { GeoCoordinates, GeoSearchOptions, GeoUnits } from './GEOSEARCH';
import GEOSEARCH_WITH, { GeoReplyWith } from './GEOSEARCH_WITH';
// export { FIRST_KEY_INDEX, IS_READ_ONLY } from './GEORADIUS';
export function transformGeoRadiusWithArguments(
command: RedisArgument,
key: RedisArgument,
from: GeoCoordinates,
radius: number,
unit: GeoUnits,
replyWith: Array<GeoReplyWith>,
options?: GeoSearchOptions
) {
const args: CommandArguments = transformGeoRadiusArguments(
command,
key,
from,
radius,
unit,
options
);
args.push(...replyWith);
args.preserve = replyWith;
return args;
}
// export function transformArguments(
// key: RedisCommandArgument,
// coordinates: GeoCoordinates,
// radius: number,
// unit: GeoUnits,
// replyWith: Array<GeoReplyWith>,
// options?: GeoSearchOptions
// ): RedisCommandArguments {
// const args: RedisCommandArguments = transformGeoRadiusArguments(
// key,
// coordinates,
// radius,
// unit,
// options
// );
// args.push(...replyWith);
// args.preserve = replyWith;
// return args;
// }
// export { transformGeoMembersWithReply as transformReply } from './generic-transformers';
export default {
FIRST_KEY_INDEX: GEORADIUS.FIRST_KEY_INDEX,
IS_READ_ONLY: GEORADIUS.IS_READ_ONLY,
transformArguments: transformGeoRadiusWithArguments.bind(undefined, 'GEORADIUS'),
transformReply: GEOSEARCH_WITH.transformReply
} as const satisfies Command;

View File

@@ -1,13 +1,14 @@
import { strict as assert } from 'assert';
import testUtils, { GLOBAL } from '../test-utils';
import { transformArguments } from './GEOSEARCH';
import GEOSEARCH from './GEOSEARCH';
describe('GEOSEARCH', () => {
testUtils.isVersionGreaterThanHook([6, 2]);
it('transformArguments', () => {
describe('transformArguments', () => {
it('FROMMEMBER, BYRADIUS, without options', () => {
assert.deepEqual(
transformArguments('key', 'member', {
GEOSEARCH.transformArguments('key', 'member', {
radius: 1,
unit: 'm'
}),
@@ -15,7 +16,63 @@ describe('GEOSEARCH', () => {
);
});
testUtils.testWithClient('client.geoSearch', async client => {
it('FROMLONLAT, BYBOX, without options', () => {
assert.deepEqual(
GEOSEARCH.transformArguments('key', {
longitude: 1,
latitude: 2
}, {
width: 1,
height: 2,
unit: 'm'
}),
['GEOSEARCH', 'key', 'FROMLONLAT', '1', '2', 'BYBOX', '1', '2', 'm']
);
});
it('with SORT', () => {
assert.deepEqual(
GEOSEARCH.transformArguments('key', 'member', {
radius: 1,
unit: 'm'
}, {
SORT: 'ASC'
}),
['GEOSEARCH', 'key', 'FROMMEMBER', 'member', 'BYRADIUS', '1', 'm', 'ASC']
);
});
describe('with COUNT', () => {
it('number', () => {
assert.deepEqual(
GEOSEARCH.transformArguments('key', 'member', {
radius: 1,
unit: 'm'
}, {
COUNT: 1
}),
['GEOSEARCH', 'key', 'FROMMEMBER', 'member', 'BYRADIUS', '1', 'm', 'COUNT', '1']
);
});
it('with ANY', () => {
assert.deepEqual(
GEOSEARCH.transformArguments('key', 'member', {
radius: 1,
unit: 'm'
}, {
COUNT: {
value: 1,
ANY: true
}
}),
['GEOSEARCH', 'key', 'FROMMEMBER', 'member', 'BYRADIUS', '1', 'm', 'COUNT', '1', 'ANY']
);
});
});
});
testUtils.testAll('geoSearch', async client => {
assert.deepEqual(
await client.geoSearch('key', 'member', {
radius: 1,
@@ -23,15 +80,8 @@ describe('GEOSEARCH', () => {
}),
[]
);
}, GLOBAL.SERVERS.OPEN);
testUtils.testWithCluster('cluster.geoSearch', async cluster => {
assert.deepEqual(
await cluster.geoSearch('key', 'member', {
radius: 1,
unit: 'm'
}),
[]
);
}, GLOBAL.CLUSTERS.OPEN);
}, {
client: GLOBAL.SERVERS.OPEN,
cluster: GLOBAL.CLUSTERS.OPEN
});
});

View File

@@ -1,17 +1,98 @@
// import { RedisCommandArgument, RedisCommandArguments } from '.';
// import { GeoSearchFrom, GeoSearchBy, GeoSearchOptions, pushGeoSearchArguments } from './generic-transformers';
import { RedisArgument, CommandArguments, ArrayReply, BlobStringReply, Command } from '../RESP/types';
// export const FIRST_KEY_INDEX = 1;
export type GeoUnits = 'm' | 'km' | 'mi' | 'ft';
// export const IS_READ_ONLY = true;
export interface GeoCoordinates {
longitude: RedisArgument | number;
latitude: RedisArgument | number;
}
// export function transformArguments(
// key: RedisCommandArgument,
// from: GeoSearchFrom,
// by: GeoSearchBy,
// options?: GeoSearchOptions
// ): RedisCommandArguments {
// return pushGeoSearchArguments(['GEOSEARCH'], key, from, by, options);
// }
export type GeoSearchFrom = RedisArgument | GeoCoordinates;
// export declare function transformReply(): Array<RedisCommandArgument>;
export interface GeoSearchByRadius {
radius: number;
unit: GeoUnits;
}
export interface GeoSearchByBox {
width: number;
height: number;
unit: GeoUnits;
}
export type GeoSearchBy = GeoSearchByRadius | GeoSearchByBox;
export function pushGeoSearchArguments(
args: CommandArguments,
key: RedisArgument,
from: GeoSearchFrom,
by: GeoSearchBy,
options?: GeoSearchOptions
) {
args.push(key);
if (typeof from === 'string' || from instanceof Buffer) {
args.push('FROMMEMBER', from);
} else {
args.push('FROMLONLAT', from.longitude.toString(), from.latitude.toString());
}
if ('radius' in by) {
args.push('BYRADIUS', by.radius.toString(), by.unit);
} else {
args.push('BYBOX', by.width.toString(), by.height.toString(), by.unit);
}
if (options?.SORT) {
args.push(options.SORT);
}
pushGeoSearchOptions(args, options);
return args;
}
export type GeoCountArgument = number | {
value: number;
ANY?: boolean;
};
export interface GeoSearchOptions {
SORT?: 'ASC' | 'DESC';
COUNT?: GeoCountArgument;
}
export function pushGeoSearchOptions(
args: CommandArguments,
options?: GeoSearchOptions
) {
if (options?.SORT) {
args.push(options.SORT);
}
if (options?.COUNT) {
if (typeof options.COUNT === 'number') {
args.push('COUNT', options.COUNT.toString());
} else {
args.push('COUNT', options.COUNT.value.toString());
if (options.COUNT.ANY) {
args.push('ANY');
}
}
}
}
export default {
FIRST_KEY_INDEX: 1,
IS_READ_ONLY: true,
transformArguments(
key: RedisArgument,
from: GeoSearchFrom,
by: GeoSearchBy,
options?: GeoSearchOptions
) {
return pushGeoSearchArguments(['GEOSEARCH'], key, from, by, options);
},
transformReply: undefined as unknown as () => ArrayReply<BlobStringReply>
} as const satisfies Command;

View File

@@ -1,6 +1,6 @@
import { strict as assert } from 'assert';
import testUtils, { GLOBAL } from '../test-utils';
import { transformArguments, transformReply } from './GEOSEARCHSTORE';
import GEOSEARCHSTORE from './GEOSEARCHSTORE';
describe('GEOSEARCHSTORE', () => {
testUtils.isVersionGreaterThanHook([6, 2]);
@@ -8,74 +8,37 @@ describe('GEOSEARCHSTORE', () => {
describe('transformArguments', () => {
it('simple', () => {
assert.deepEqual(
transformArguments('destination', 'source', 'member', {
GEOSEARCHSTORE.transformArguments('source', 'destination', 'member', {
radius: 1,
unit: 'm'
}, {
SORT: 'ASC',
COUNT: {
value: 1,
ANY: true
}
}),
['GEOSEARCHSTORE', 'destination', 'source', 'FROMMEMBER', 'member', 'BYRADIUS', '1', 'm', 'ASC', 'COUNT', '1', 'ANY']
['GEOSEARCHSTORE', 'source', 'destination', 'FROMMEMBER', 'member', 'BYRADIUS', '1', 'm']
);
});
it('with STOREDIST', () => {
assert.deepEqual(
transformArguments('destination', 'source', 'member', {
GEOSEARCHSTORE.transformArguments('destination', 'source', 'member', {
radius: 1,
unit: 'm'
}, {
SORT: 'ASC',
COUNT: {
value: 1,
ANY: true
},
STOREDIST: true
}),
['GEOSEARCHSTORE', 'destination', 'source', 'FROMMEMBER', 'member', 'BYRADIUS', '1', 'm', 'ASC', 'COUNT', '1', 'ANY', 'STOREDIST']
['GEOSEARCHSTORE', 'destination', 'source', 'FROMMEMBER', 'member', 'BYRADIUS', '1', 'm', 'STOREDIST']
);
});
});
it('transformReply with empty array (https://github.com/redis/redis/issues/9261)', () => {
assert.throws(
() => (transformReply as any)([]),
TypeError
);
});
testUtils.testWithClient('client.geoSearchStore', async client => {
await client.geoAdd('source', {
longitude: 1,
latitude: 1,
member: 'member'
});
testUtils.testAll('geoSearchStore', async client => {
assert.equal(
await client.geoSearchStore('destination', 'source', 'member', {
await client.geoSearchStore('{tag}destination', '{tag}source', 'member', {
radius: 1,
unit: 'm'
}),
1
0
);
}, GLOBAL.SERVERS.OPEN);
testUtils.testWithCluster('cluster.geoSearchStore', async cluster => {
await cluster.geoAdd('{tag}source', {
longitude: 1,
latitude: 1,
member: 'member'
}, {
client: GLOBAL.SERVERS.OPEN,
cluster: GLOBAL.CLUSTERS.OPEN
});
assert.equal(
await cluster.geoSearchStore('{tag}destination', '{tag}source', 'member', {
radius: 1,
unit: 'm'
}),
1
);
}, GLOBAL.CLUSTERS.OPEN);
});

View File

@@ -1,38 +1,27 @@
// import { RedisCommandArgument, RedisCommandArguments } from '.';
// import { GeoSearchFrom, GeoSearchBy, GeoSearchOptions, pushGeoSearchArguments } from './generic-transformers';
import { RedisArgument, NumberReply, Command } from '../RESP/types';
import { GeoSearchFrom, GeoSearchBy, GeoSearchOptions, pushGeoSearchArguments } from './GEOSEARCH';
// export { FIRST_KEY_INDEX, IS_READ_ONLY } from './GEOSEARCH';
export interface GeoSearchStoreOptions extends GeoSearchOptions {
STOREDIST?: boolean;
}
// interface GeoSearchStoreOptions extends GeoSearchOptions {
// STOREDIST?: true;
// }
export default {
FIRST_KEY_INDEX: 1,
IS_READ_ONLY: false,
transformArguments(
destination: RedisArgument,
source: RedisArgument,
from: GeoSearchFrom,
by: GeoSearchBy,
options?: GeoSearchStoreOptions
) {
const args = pushGeoSearchArguments(['GEOSEARCHSTORE', destination], source, from, by, options);
// export function transformArguments(
// destination: RedisCommandArgument,
// source: RedisCommandArgument,
// from: GeoSearchFrom,
// by: GeoSearchBy,
// options?: GeoSearchStoreOptions
// ): RedisCommandArguments {
// const args = pushGeoSearchArguments(
// ['GEOSEARCHSTORE', destination],
// source,
// from,
// by,
// options
// );
if (options?.STOREDIST) {
args.push('STOREDIST');
}
// if (options?.STOREDIST) {
// args.push('STOREDIST');
// }
// return args;
// }
// export function transformReply(reply: number): number {
// if (typeof reply !== 'number') {
// throw new TypeError(`https://github.com/redis/redis/issues/9261`);
// }
// return reply;
// }
return args;
},
transformReply: undefined as unknown as () => NumberReply
} as const satisfies Command;

View File

@@ -1,42 +1,49 @@
import { strict as assert } from 'assert';
import testUtils, { GLOBAL } from '../test-utils';
import { RedisCommandArguments } from '.';
import { GeoReplyWith } from './generic-transformers';
import { transformArguments } from './GEOSEARCH_WITH';
import GEOSEARCH_WITH, { GEO_REPLY_WITH } from './GEOSEARCH_WITH';
import { CommandArguments } from '../RESP/types';
describe('GEOSEARCH WITH', () => {
testUtils.isVersionGreaterThanHook([6, 2]);
it('transformArguments', () => {
const expectedReply: RedisCommandArguments = ['GEOSEARCH', 'key', 'FROMMEMBER', 'member', 'BYRADIUS', '1', 'm', 'WITHDIST'];
const expectedReply: CommandArguments = ['GEOSEARCH', 'key', 'FROMMEMBER', 'member', 'BYRADIUS', '1', 'm', 'WITHDIST'];
expectedReply.preserve = ['WITHDIST'];
assert.deepEqual(
transformArguments('key', 'member', {
GEOSEARCH_WITH.transformArguments('key', 'member', {
radius: 1,
unit: 'm'
}, [GeoReplyWith.DISTANCE]),
}, [GEO_REPLY_WITH.DISTANCE]),
expectedReply
);
});
testUtils.testWithClient('client.geoSearchWith', async client => {
assert.deepEqual(
await client.geoSearchWith('key', 'member', {
testUtils.testAll('.geoSearchWith', async client => {
const [ , reply ] = await Promise.all([
client.geoAdd('key', {
member: 'member',
longitude: 1,
latitude: 2
}),
client.geoSearchWith('key', 'member', {
radius: 1,
unit: 'm'
}, [GeoReplyWith.DISTANCE]),
[]
);
}, GLOBAL.SERVERS.OPEN);
}, [
GEO_REPLY_WITH.HASH,
GEO_REPLY_WITH.DISTANCE,
GEO_REPLY_WITH.COORDINATES
])
]);
testUtils.testWithCluster('cluster.geoSearchWith', async cluster => {
assert.deepEqual(
await cluster.geoSearchWith('key', 'member', {
radius: 1,
unit: 'm'
}, [GeoReplyWith.DISTANCE]),
[]
);
}, GLOBAL.CLUSTERS.OPEN);
assert.equal(reply.length, 1);
assert.equal(reply[0].member, 'member');
assert.equal(typeof reply[0].distance, 'string');
assert.equal(typeof reply[0].hash, 'number');
assert.equal(typeof reply[0].coordinates!.longitude, 'string');
assert.equal(typeof reply[0].coordinates!.latitude, 'string');
}, {
client: GLOBAL.SERVERS.OPEN,
cluster: GLOBAL.CLUSTERS.OPEN
});
});

View File

@@ -1,23 +1,71 @@
// import { RedisCommandArgument, RedisCommandArguments } from '.';
// import { GeoSearchFrom, GeoSearchBy, GeoReplyWith, GeoSearchOptions } from './generic-transformers';
// import { transformArguments as geoSearchTransformArguments } from './GEOSEARCH';
import { ArrayReply, BlobStringReply, NumberReply, DoubleReply, Command, RedisArgument } from '../RESP/types';
import GEOSEARCH, { GeoSearchBy, GeoSearchFrom, GeoSearchOptions } from './GEOSEARCH';
// export { FIRST_KEY_INDEX, IS_READ_ONLY } from './GEOSEARCH';
export const GEO_REPLY_WITH = {
DISTANCE: 'WITHDIST',
HASH: 'WITHHASH',
COORDINATES: 'WITHCOORD'
} as const;
// export function transformArguments(
// key: RedisCommandArgument,
// from: GeoSearchFrom,
// by: GeoSearchBy,
// replyWith: Array<GeoReplyWith>,
// options?: GeoSearchOptions
// ): RedisCommandArguments {
// const args: RedisCommandArguments = geoSearchTransformArguments(key, from, by, options);
export type GeoReplyWith = typeof GEO_REPLY_WITH[keyof typeof GEO_REPLY_WITH];
// args.push(...replyWith);
export interface GeoReplyWithMember {
member: BlobStringReply;
distance?: BlobStringReply;
hash?: NumberReply;
coordinates?: {
longitude: DoubleReply;
latitude: DoubleReply;
};
}
// args.preserve = replyWith;
export default {
FIRST_KEY_INDEX: GEOSEARCH.FIRST_KEY_INDEX,
IS_READ_ONLY: GEOSEARCH.IS_READ_ONLY,
transformArguments(
key: RedisArgument,
from: GeoSearchFrom,
by: GeoSearchBy,
replyWith: Array<GeoReplyWith>,
options?: GeoSearchOptions
) {
const args = GEOSEARCH.transformArguments(key, from, by, options);
args.push(...replyWith);
args.preserve = replyWith;
return args;
},
transformReply(
reply: ArrayReply<[BlobStringReply, ...Array<any>]>,
replyWith: Array<GeoReplyWith>
) {
const replyWithSet = new Set(replyWith);
let index = 0;
const distanceIndex = replyWithSet.has(GEO_REPLY_WITH.DISTANCE) && ++index,
hashIndex = replyWithSet.has(GEO_REPLY_WITH.HASH) && ++index,
coordinatesIndex = replyWithSet.has(GEO_REPLY_WITH.COORDINATES) && ++index;
// return args;
// }
return reply.map(raw => {
const item: GeoReplyWithMember = {
member: raw[0]
};
// export { transformGeoMembersWithReply as transformReply } from './generic-transformers';
if (distanceIndex) {
item.distance = raw[distanceIndex];
}
if (hashIndex) {
item.hash = raw[hashIndex];
}
if (coordinatesIndex) {
const [longitude, latitude] = raw[coordinatesIndex];
item.coordinates = {
longitude,
latitude
};
}
return item;
});
}
} as const satisfies Command;

View File

@@ -45,6 +45,23 @@ import DECR from './DECR';
import DECRBY from './DECRBY';
import DEL from './DEL';
import DUMP from './DUMP';
import GEOADD from './GEOADD';
import GEODIST from './GEODIST';
import GEOHASH from './GEOHASH';
import GEOPOS from './GEOPOS';
import GEORADIUS_RO_WITH from './GEORADIUS_RO_WITH';
import GEORADIUS_RO from './GEORADIUS_RO';
import GEORADIUS_STORE from './GEORADIUS_STORE';
import GEORADIUS_WITH from './GEORADIUS_WITH';
import GEORADIUS from './GEORADIUS';
import GEORADIUSBYMEMBER_RO_WITH from './GEORADIUSBYMEMBER_RO_WITH';
import GEORADIUSBYMEMBER_RO from './GEORADIUSBYMEMBER_RO';
import GEORADIUSBYMEMBER_STORE from './GEORADIUSBYMEMBER_STORE';
import GEORADIUSBYMEMBER_WITH from './GEORADIUSBYMEMBER_WITH';
import GEORADIUSBYMEMBER from './GEORADIUSBYMEMBER';
import GEOSEARCH_WITH from './GEOSEARCH_WITH';
import GEOSEARCH from './GEOSEARCH';
import GEOSEARCHSTORE from './GEOSEARCHSTORE';
import GET from './GET';
import GETBIT from './GETBIT';
import GETDEL from './GETDEL';
@@ -290,6 +307,40 @@ export default {
del: DEL,
DUMP,
dump: DUMP,
GEOADD,
geoAdd: GEOADD,
GEODIST,
geoDist: GEODIST,
GEOHASH,
geoHash: GEOHASH,
GEOPOS,
geoPos: GEOPOS,
GEORADIUS_RO_WITH,
geoRadiusRoWith: GEORADIUS_RO_WITH,
GEORADIUS_RO,
geoRadiusRo: GEORADIUS_RO,
GEORADIUS_STORE,
geoRadiusStore: GEORADIUS_STORE,
GEORADIUS_WITH,
geoRadiusWith: GEORADIUS_WITH,
GEORADIUS,
geoRadius: GEORADIUS,
GEORADIUSBYMEMBER_RO_WITH,
geoRadiusByMemberRoWith: GEORADIUSBYMEMBER_RO_WITH,
GEORADIUSBYMEMBER_RO,
geoRadiusByMemberRo: GEORADIUSBYMEMBER_RO,
GEORADIUSBYMEMBER_STORE,
geoRadiusByMemberStore: GEORADIUSBYMEMBER_STORE,
GEORADIUSBYMEMBER_WITH,
geoRadiusByMemberWith: GEORADIUSBYMEMBER_WITH,
GEORADIUSBYMEMBER,
geoRadiusByMember: GEORADIUSBYMEMBER,
GEOSEARCH_WITH,
geoSearchWith: GEOSEARCH_WITH,
GEOSEARCH,
geoSearch: GEOSEARCH,
GEOSEARCHSTORE,
geoSearchStore: GEOSEARCHSTORE,
GET,
get: GET,
GETBIT,