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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,25 +1,30 @@
// import { RedisCommandArgument, RedisCommandArguments } from '.'; import { RedisArgument, ArrayReply, BlobStringReply, Command } from '../RESP/types';
// import { GeoSearchOptions, pushGeoRadiusArguments, GeoUnits } from './generic-transformers'; 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( return args;
// key: RedisCommandArgument, }
// member: string,
// radius: number,
// unit: GeoUnits,
// options?: GeoSearchOptions
// ): RedisCommandArguments {
// return pushGeoRadiusArguments(
// ['GEORADIUSBYMEMBER'],
// key,
// member,
// radius,
// unit,
// options
// );
// }
// 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 { strict as assert } from 'assert';
import testUtils, { GLOBAL } from '../test-utils'; import testUtils, { GLOBAL } from '../test-utils';
import { transformArguments } from './GEORADIUSBYMEMBER_RO'; import GEORADIUSBYMEMBER_RO from './GEORADIUSBYMEMBER_RO';
describe('GEORADIUSBYMEMBER_RO', () => { describe('GEORADIUSBYMEMBER_RO', () => {
it('transformArguments', () => { it('transformArguments', () => {
assert.deepEqual( assert.deepEqual(
transformArguments('key', 'member', 3 , 'm'), GEORADIUSBYMEMBER_RO.transformArguments('key', 'member', 3, 'm'),
['GEORADIUSBYMEMBER_RO', 'key', 'member', '3', 'm'] ['GEORADIUSBYMEMBER_RO', 'key', 'member', '3', 'm']
); );
}); });
testUtils.testWithClient('client.geoRadiusByMemberRo', async client => { testUtils.testAll('geoRadiusByMemberRo', async client => {
assert.deepEqual( assert.deepEqual(
await client.geoRadiusByMemberRo('key', 'member', 3 , 'm'), await client.geoRadiusByMemberRo('key', 'member', 3, 'm'),
[] []
); );
}, GLOBAL.SERVERS.OPEN); }, {
client: GLOBAL.SERVERS.OPEN,
testUtils.testWithCluster('cluster.geoRadiusByMemberRo', async cluster => { cluster: GLOBAL.CLUSTERS.OPEN
assert.deepEqual( });
await cluster.geoRadiusByMemberRo('key', 'member', 3 , 'm'),
[]
);
}, GLOBAL.CLUSTERS.OPEN);
}); });

View File

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

View File

@@ -1,31 +1,44 @@
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 { RedisCommandArguments } from '.'; import GEORADIUSBYMEMBER_RO_WITH from './GEORADIUSBYMEMBER_RO_WITH';
import { GeoReplyWith } from './generic-transformers'; import { CommandArguments } from '../RESP/types';
import { transformArguments } from './GEORADIUSBYMEMBER_RO_WITH'; import { GEO_REPLY_WITH } from './GEOSEARCH_WITH';
describe('GEORADIUSBYMEMBER_RO WITH', () => { describe('GEORADIUSBYMEMBER_RO WITH', () => {
it('transformArguments', () => { 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']; expectedReply.preserve = ['WITHDIST'];
assert.deepEqual( assert.deepEqual(
transformArguments('key', 'member', 3 , 'm', [GeoReplyWith.DISTANCE]), GEORADIUSBYMEMBER_RO_WITH.transformArguments('key', 'member', 3, 'm', [
GEO_REPLY_WITH.DISTANCE
]),
expectedReply expectedReply
); );
}); });
testUtils.testWithClient('client.geoRadiusByMemberRoWith', async client => { testUtils.testAll('geoRadiusByMemberRoWith', async client => {
assert.deepEqual( const [, reply] = await Promise.all([
await client.geoRadiusByMemberRoWith('key', 'member', 3 , 'm', [GeoReplyWith.DISTANCE]), client.geoAdd('key', {
[] member: 'member',
); longitude: 1,
}, GLOBAL.SERVERS.OPEN); 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.equal(reply.length, 1);
assert.deepEqual( assert.equal(reply[0].member, 'member');
await cluster.geoRadiusByMemberRoWith('key', 'member', 3 , 'm', [GeoReplyWith.DISTANCE]), assert.equal(typeof reply[0].distance, 'string');
[] assert.equal(typeof reply[0].hash, 'number');
); assert.equal(typeof reply[0].coordinates?.longitude, 'string');
}, GLOBAL.CLUSTERS.OPEN); 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 { Command } from '../RESP/types';
// import { GeoReplyWith, GeoSearchOptions, GeoUnits } from './generic-transformers'; import GEORADIUSBYMEMBER_WITH, { transformGeoRadiusByMemberWithArguments } from './GEORADIUSBYMEMBER_WITH';
// import { transformArguments as geoRadiusTransformArguments } from './GEORADIUSBYMEMBER_RO';
// export { FIRST_KEY_INDEX, IS_READ_ONLY } from './GEORADIUSBYMEMBER_RO'; export default {
FIRST_KEY_INDEX: GEORADIUSBYMEMBER_WITH.FIRST_KEY_INDEX,
// export function transformArguments( IS_READ_ONLY: true,
// key: RedisCommandArgument, transformArguments: transformGeoRadiusByMemberWithArguments.bind(undefined, 'GEORADIUSBYMEMBER_RO'),
// member: string, transformReply: GEORADIUSBYMEMBER_WITH.transformReply
// radius: number, } as const satisfies Command;
// 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';

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 { strict as assert } from 'assert';
import testUtils, { GLOBAL } from '../test-utils'; import testUtils, { GLOBAL } from '../test-utils';
import { RedisCommandArguments } from '.'; import GEORADIUSBYMEMBER_WITH from './GEORADIUSBYMEMBER_WITH';
import { GeoReplyWith } from './generic-transformers'; import { CommandArguments } from '../RESP/types';
import { transformArguments } from './GEORADIUSBYMEMBER_WITH'; import { GEO_REPLY_WITH } from './GEOSEARCH_WITH';
describe('GEORADIUSBYMEMBER WITH', () => { describe('GEORADIUSBYMEMBER WITH', () => {
it('transformArguments', () => { it('transformArguments', () => {
const expectedReply: RedisCommandArguments = ['GEORADIUSBYMEMBER', 'key', 'member', '3', 'm', 'WITHDIST']; const expectedReply: CommandArguments = ['GEORADIUSBYMEMBER', 'key', 'member', '3', 'm', 'WITHDIST'];
expectedReply.preserve = ['WITHDIST']; expectedReply.preserve = ['WITHDIST'];
assert.deepEqual( assert.deepEqual(
transformArguments('key', 'member', 3 , 'm', [GeoReplyWith.DISTANCE]), GEORADIUSBYMEMBER_WITH.transformArguments('key', 'member', 3, 'm', [
GEO_REPLY_WITH.DISTANCE
]),
expectedReply expectedReply
); );
}); });
testUtils.testWithClient('client.geoRadiusByMemberWith', async client => { testUtils.testAll('geoRadiusByMemberWith', async client => {
assert.deepEqual( const [, reply] = await Promise.all([
await client.geoRadiusByMemberWith('key', 'member', 3 , 'm', [GeoReplyWith.DISTANCE]), client.geoAdd('key', {
[] member: 'member',
); longitude: 1,
}, GLOBAL.SERVERS.OPEN); 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.equal(reply.length, 1);
assert.deepEqual( assert.equal(reply[0].member, 'member');
await cluster.geoRadiusByMemberWith('key', 'member', 3 , 'm', [GeoReplyWith.DISTANCE]), assert.equal(typeof reply[0].distance, 'string');
[] assert.equal(typeof reply[0].hash, 'number');
); assert.equal(typeof reply[0].coordinates!.longitude, 'string');
}, GLOBAL.CLUSTERS.OPEN); 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 { RedisArgument, CommandArguments, ArrayReply, BlobStringReply, Command } from '../RESP/types';
// import { GeoReplyWith, GeoSearchOptions, GeoUnits } from './generic-transformers'; import GEORADIUSBYMEMBER from './GEORADIUSBYMEMBER';
// import { transformArguments as transformGeoRadiusArguments } 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( pushGeoSearchOptions(args, options);
// key: RedisCommandArgument,
// member: string,
// radius: number,
// unit: GeoUnits,
// replyWith: Array<GeoReplyWith>,
// options?: GeoSearchOptions
// ): RedisCommandArguments {
// const args: RedisCommandArguments = transformGeoRadiusArguments(
// key,
// member,
// radius,
// unit,
// options
// );
// args.push(...replyWith); args.push(...replyWith);
args.preserve = replyWith;
// args.preserve = replyWith; return args;
}
// return args; export default {
// } FIRST_KEY_INDEX: GEORADIUSBYMEMBER.FIRST_KEY_INDEX,
IS_READ_ONLY: GEORADIUSBYMEMBER.IS_READ_ONLY,
// export { transformGeoMembersWithReply as transformReply } from './generic-transformers'; 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 { strict as assert } from 'assert';
import testUtils, { GLOBAL } from '../test-utils'; import testUtils, { GLOBAL } from '../test-utils';
import { transformArguments } from './GEORADIUS_RO'; import GEORADIUS_RO from './GEORADIUS_RO';
describe('GEORADIUS_RO', () => { describe('GEORADIUS_RO', () => {
it('transformArguments', () => { it('transformArguments', () => {
assert.deepEqual( assert.deepEqual(
transformArguments('key', { GEORADIUS_RO.transformArguments('key', {
longitude: 1, longitude: 1,
latitude: 2 latitude: 2
}, 3 , 'm'), }, 3, 'm'),
['GEORADIUS_RO', 'key', '1', '2', '3', 'm'] ['GEORADIUS_RO', 'key', '1', '2', '3', 'm']
); );
}); });
testUtils.testWithClient('client.geoRadiusRo', async client => { testUtils.testAll('geoRadiusRo', async client => {
assert.deepEqual( assert.deepEqual(
await client.geoRadiusRo('key', { await client.geoRadiusRo('key', {
longitude: 1, longitude: 1,
latitude: 2 latitude: 2
}, 3 , 'm'), }, 3, 'm'),
[] []
); );
}, GLOBAL.SERVERS.OPEN); }, {
client: GLOBAL.SERVERS.OPEN,
testUtils.testWithCluster('cluster.geoRadiusRo', async cluster => { cluster: GLOBAL.CLUSTERS.OPEN
assert.deepEqual( });
await cluster.geoRadiusRo('key', {
longitude: 1,
latitude: 2
}, 3 , 'm'),
[]
);
}, GLOBAL.CLUSTERS.OPEN);
}); });

View File

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

View File

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

View File

@@ -1,30 +1,9 @@
// import { RedisCommandArgument, RedisCommandArguments } from '.'; import { Command } from '../RESP/types';
// import { GeoReplyWith, GeoSearchOptions, GeoCoordinates, GeoUnits } from './generic-transformers'; import GEORADIUS_WITH, { transformGeoRadiusWithArguments } from './GEORADIUS_WITH';
// import { transformArguments as transformGeoRadiusRoArguments } from './GEORADIUS_RO';
// export { FIRST_KEY_INDEX, IS_READ_ONLY } from './GEORADIUS_RO'; export default {
FIRST_KEY_INDEX: GEORADIUS_WITH.FIRST_KEY_INDEX,
// export function transformArguments( IS_READ_ONLY: true,
// key: RedisCommandArgument, transformArguments: transformGeoRadiusWithArguments.bind(undefined, 'GEORADIUS_RO'),
// coordinates: GeoCoordinates, transformReply: GEORADIUS_WITH.transformReply
// radius: number, } as const satisfies Command;
// 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';

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

View File

@@ -1,30 +1,33 @@
// import { RedisCommandArgument, RedisCommandArguments } from '.'; import { CommandArguments, Command, RedisArgument } from '../RESP/types';
// import { GeoReplyWith, GeoSearchOptions, GeoCoordinates, GeoUnits } from './generic-transformers'; import GEORADIUS, { transformGeoRadiusArguments } from './GEORADIUS';
// import { transformArguments as 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( export default {
// key: RedisCommandArgument, FIRST_KEY_INDEX: GEORADIUS.FIRST_KEY_INDEX,
// coordinates: GeoCoordinates, IS_READ_ONLY: GEORADIUS.IS_READ_ONLY,
// radius: number, transformArguments: transformGeoRadiusWithArguments.bind(undefined, 'GEORADIUS'),
// unit: GeoUnits, transformReply: GEOSEARCH_WITH.transformReply
// replyWith: Array<GeoReplyWith>, } as const satisfies Command;
// 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';

View File

@@ -1,13 +1,14 @@
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 './GEOSEARCH'; import GEOSEARCH from './GEOSEARCH';
describe('GEOSEARCH', () => { describe('GEOSEARCH', () => {
testUtils.isVersionGreaterThanHook([6, 2]); testUtils.isVersionGreaterThanHook([6, 2]);
it('transformArguments', () => { describe('transformArguments', () => {
it('FROMMEMBER, BYRADIUS, without options', () => {
assert.deepEqual( assert.deepEqual(
transformArguments('key', 'member', { GEOSEARCH.transformArguments('key', 'member', {
radius: 1, radius: 1,
unit: 'm' 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( assert.deepEqual(
await client.geoSearch('key', 'member', { await client.geoSearch('key', 'member', {
radius: 1, radius: 1,
@@ -23,15 +80,8 @@ describe('GEOSEARCH', () => {
}), }),
[] []
); );
}, GLOBAL.SERVERS.OPEN); }, {
client: GLOBAL.SERVERS.OPEN,
testUtils.testWithCluster('cluster.geoSearch', async cluster => { cluster: GLOBAL.CLUSTERS.OPEN
assert.deepEqual( });
await cluster.geoSearch('key', 'member', {
radius: 1,
unit: 'm'
}),
[]
);
}, GLOBAL.CLUSTERS.OPEN);
}); });

View File

@@ -1,17 +1,98 @@
// import { RedisCommandArgument, RedisCommandArguments } from '.'; import { RedisArgument, CommandArguments, ArrayReply, BlobStringReply, Command } from '../RESP/types';
// import { GeoSearchFrom, GeoSearchBy, GeoSearchOptions, pushGeoSearchArguments } from './generic-transformers';
// 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( export type GeoSearchFrom = RedisArgument | GeoCoordinates;
// key: RedisCommandArgument,
// from: GeoSearchFrom,
// by: GeoSearchBy,
// options?: GeoSearchOptions
// ): RedisCommandArguments {
// return pushGeoSearchArguments(['GEOSEARCH'], key, from, by, options);
// }
// 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 { strict as assert } from 'assert';
import testUtils, { GLOBAL } from '../test-utils'; import testUtils, { GLOBAL } from '../test-utils';
import { transformArguments, transformReply } from './GEOSEARCHSTORE'; import GEOSEARCHSTORE from './GEOSEARCHSTORE';
describe('GEOSEARCHSTORE', () => { describe('GEOSEARCHSTORE', () => {
testUtils.isVersionGreaterThanHook([6, 2]); testUtils.isVersionGreaterThanHook([6, 2]);
@@ -8,74 +8,37 @@ describe('GEOSEARCHSTORE', () => {
describe('transformArguments', () => { describe('transformArguments', () => {
it('simple', () => { it('simple', () => {
assert.deepEqual( assert.deepEqual(
transformArguments('destination', 'source', 'member', { GEOSEARCHSTORE.transformArguments('source', 'destination', 'member', {
radius: 1, radius: 1,
unit: 'm' 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', () => { it('with STOREDIST', () => {
assert.deepEqual( assert.deepEqual(
transformArguments('destination', 'source', 'member', { GEOSEARCHSTORE.transformArguments('destination', 'source', 'member', {
radius: 1, radius: 1,
unit: 'm' unit: 'm'
}, { }, {
SORT: 'ASC',
COUNT: {
value: 1,
ANY: true
},
STOREDIST: 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)', () => { testUtils.testAll('geoSearchStore', async client => {
assert.throws(
() => (transformReply as any)([]),
TypeError
);
});
testUtils.testWithClient('client.geoSearchStore', async client => {
await client.geoAdd('source', {
longitude: 1,
latitude: 1,
member: 'member'
});
assert.equal( assert.equal(
await client.geoSearchStore('destination', 'source', 'member', { await client.geoSearchStore('{tag}destination', '{tag}source', 'member', {
radius: 1, radius: 1,
unit: 'm' unit: 'm'
}), }),
1 0
); );
}, GLOBAL.SERVERS.OPEN); }, {
client: GLOBAL.SERVERS.OPEN,
testUtils.testWithCluster('cluster.geoSearchStore', async cluster => { cluster: GLOBAL.CLUSTERS.OPEN
await cluster.geoAdd('{tag}source', {
longitude: 1,
latitude: 1,
member: 'member'
}); });
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 { RedisArgument, NumberReply, Command } from '../RESP/types';
// import { GeoSearchFrom, GeoSearchBy, GeoSearchOptions, pushGeoSearchArguments } from './generic-transformers'; 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 { export default {
// STOREDIST?: true; 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( if (options?.STOREDIST) {
// destination: RedisCommandArgument, args.push('STOREDIST');
// source: RedisCommandArgument, }
// from: GeoSearchFrom,
// by: GeoSearchBy,
// options?: GeoSearchStoreOptions
// ): RedisCommandArguments {
// const args = pushGeoSearchArguments(
// ['GEOSEARCHSTORE', destination],
// source,
// from,
// by,
// options
// );
// if (options?.STOREDIST) { return args;
// args.push('STOREDIST'); },
// } transformReply: undefined as unknown as () => NumberReply
} as const satisfies Command;
// return args;
// }
// export function transformReply(reply: number): number {
// if (typeof reply !== 'number') {
// throw new TypeError(`https://github.com/redis/redis/issues/9261`);
// }
// return reply;
// }

View File

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

View File

@@ -1,23 +1,71 @@
// import { RedisCommandArgument, RedisCommandArguments } from '.'; import { ArrayReply, BlobStringReply, NumberReply, DoubleReply, Command, RedisArgument } from '../RESP/types';
// import { GeoSearchFrom, GeoSearchBy, GeoReplyWith, GeoSearchOptions } from './generic-transformers'; import GEOSEARCH, { GeoSearchBy, GeoSearchFrom, GeoSearchOptions } from './GEOSEARCH';
// import { transformArguments as geoSearchTransformArguments } 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( export type GeoReplyWith = typeof GEO_REPLY_WITH[keyof typeof GEO_REPLY_WITH];
// key: RedisCommandArgument,
// from: GeoSearchFrom,
// by: GeoSearchBy,
// replyWith: Array<GeoReplyWith>,
// options?: GeoSearchOptions
// ): RedisCommandArguments {
// const args: RedisCommandArguments = geoSearchTransformArguments(key, from, by, options);
// 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 DECRBY from './DECRBY';
import DEL from './DEL'; import DEL from './DEL';
import DUMP from './DUMP'; 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 GET from './GET';
import GETBIT from './GETBIT'; import GETBIT from './GETBIT';
import GETDEL from './GETDEL'; import GETDEL from './GETDEL';
@@ -290,6 +307,40 @@ export default {
del: DEL, del: DEL,
DUMP, DUMP,
dump: 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: GET, get: GET,
GETBIT, GETBIT,