Skip to content

Commit

Permalink
Node: Add GEOADD
Browse files Browse the repository at this point in the history
  • Loading branch information
TJ Zhang committed Jul 19, 2024
1 parent 34e253c commit bad84c5
Show file tree
Hide file tree
Showing 7 changed files with 201 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@
* Python: Added transaction supports for DUMP, RESTORE, FUNCTION DUMP and FUNCTION RESTORE ([#1814](https://github.com/valkey-io/valkey-glide/pull/1814))
* Node: Added FlushAll command ([#1958](https://github.com/valkey-io/valkey-glide/pull/1958))
* Node: Added DBSize command ([#1932](https://github.com/valkey-io/valkey-glide/pull/1932))
* Node: Added GeoAdd command ([#1980](https://github.com/valkey-io/valkey-glide/pull/1980))

#### Breaking Changes
* Node: Update XREAD to return a Map of Map ([#1494](https://github.com/valkey-io/valkey-glide/pull/1494))
Expand Down
35 changes: 35 additions & 0 deletions node/src/BaseClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import {
createExists,
createExpire,
createExpireAt,
createGeoAdd,
createGet,
createGetDel,
createHDel,
Expand Down Expand Up @@ -135,6 +136,9 @@ import {
connection_request,
response,
} from "./ProtobufMessage";
import { GeoAddOptions } from "./command-options/geospatial/GeoAddOptions";
import { GeospatialData } from "./command-options/geospatial/GeospatialData";
import { ConditionalChange } from "./command-options/ConditionalChange";

/* eslint-disable-next-line @typescript-eslint/no-explicit-any */
type PromiseFunction = (value?: any) => void;
Expand Down Expand Up @@ -3206,6 +3210,37 @@ export class BaseClient {
return this.createWritePromise(createLPos(key, element, options));
}

/**
* Adds geospatial members with their positions to the specified sorted set stored at `key`.`
* If a member is already a part of the sorted set, its position is updated.
*
* See https://valkey.io/commands/geoadd/ for more details.
*
* @param key - The key of the sorted set.
* @param membersToGeospatialData - A mapping of member names to their corresponding positions - see
* {@link GeospatialData}. The command will report an error when the user attempts to index
* coordinates outside the specified ranges.
* @param options - The GeoAdd options - see {@link GeoAddOptions}.
* @returns The number of elements added to the sorted set. If `changed` is set to
* `true` in the options, returns the number of elements updated in the sorted set.
*
* @example
* ```typescript
* const options = new GeoAddOptions({updateMode: ConditionalChange.ONLY_IF_EXISTS, changed: true});
* let num = await client.geoadd("mySortedSet", {"Palermo", new GeospatialData({13.361389, 38.115556})}, options);
* console.log(num); // Output: 1 - Indicates that the position of an existing member in the sorted set "mySortedSet" has been updated.
* ```
*/
public geoadd(
key: string,
membersToGeospatialData: Map<string, GeospatialData>,
options?: GeoAddOptions,
): Promise<number> {
return this.createWritePromise(
createGeoAdd(key, membersToGeospatialData, options),
);
}

/**
* @internal
*/
Expand Down
23 changes: 23 additions & 0 deletions node/src/Commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import Long from "long";
import { LPosOptions } from "./command-options/LPosOptions";

import { command_request } from "./ProtobufMessage";
import { GeospatialData } from "./command-options/geospatial/GeospatialData";
import { GeoAddOptions } from "./command-options/geospatial/GeoAddOptions";

import RequestType = command_request.RequestType;

Expand Down Expand Up @@ -1752,3 +1754,24 @@ export function createLPos(
export function createDBSize(): command_request.Command {
return createCommand(RequestType.DBSize, []);
}

/**
* @internal
*/
export function createGeoAdd(
key: string,
membersToGeospatialData: Map<string, GeospatialData>,
options?: GeoAddOptions,
): command_request.Command {
let args: string[] = [key];
membersToGeospatialData.forEach((coord, member) => {
args.concat(coord.toArgs());
args.push(member);
});

if (options) {
args = args.concat(options.toArgs());
}

return createCommand(RequestType.GeoAdd, args);
}
29 changes: 29 additions & 0 deletions node/src/Transaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -127,9 +127,12 @@ import {
createZRemRangeByRank,
createZRemRangeByScore,
createZScore,
createGeoAdd,
createFunctionLoad,
} from "./Commands";
import { command_request } from "./ProtobufMessage";
import { GeoAddOptions } from "./command-options/geospatial/GeoAddOptions";
import { GeospatialData } from "./command-options/geospatial/GeospatialData";

/**
* Base class encompassing shared commands for both standalone and cluster mode implementations in a transaction.
Expand Down Expand Up @@ -1797,6 +1800,32 @@ export class BaseTransaction<T extends BaseTransaction<T>> {
public dbsize(): T {
return this.addAndReturn(createDBSize());
}

/**
* Adds geospatial members with their positions to the specified sorted set stored at `key`.`
* If a member is already a part of the sorted set, its position is updated.
*
* See https://valkey.io/commands/geoadd/ for more details.
*
* @param key - The key of the sorted set.
* @param membersToGeospatialData - A mapping of member names to their corresponding positions - see
* {@link GeospatialData}. The command will report an error when the user attempts to index
* coordinates outside the specified ranges.
* @param options - The GeoAdd options - see {@link GeoAddOptions}.
*
* Command Response - The number of elements added to the sorted set. If `changed` is set to
* `true` in the options, returns the number of elements updated in the sorted set.
* ```
*/
public geoadd(
key: string,
membersToGeospatialData: Map<string, GeospatialData>,
options?: GeoAddOptions,
): T {
return this.addAndReturn(
createGeoAdd(key, membersToGeospatialData, options),
);
}
}

/**
Expand Down
19 changes: 19 additions & 0 deletions node/src/command-options/ConditionalChange.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/**
* Copyright Valkey GLIDE Project Contributors - SPDX Identifier: Apache-2.0
*/

/**
*
* An optional condition to the GeoAdd command.
*/
export enum ConditionalChange {
/**
* Only update elements that already exist. Don't add new elements. Equivalent to `XX` in the Valkey API.
*/
ONLY_IF_EXISTS = "XX",

/**
* Only add new elements. Don't update already existing elements. Equivalent to `NX` in the Valkey API.
* */
ONLY_IF_DOES_NOT_EXIST = "NX",
}
55 changes: 55 additions & 0 deletions node/src/command-options/geospatial/GeoAddOptions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/**
* Copyright Valkey GLIDE Project Contributors - SPDX Identifier: Apache-2.0
*/

import { ConditionalChange } from "../ConditionalChange";

/**
* Optional arguments for the GeoAdd command.
*
* See https://valkey.io/commands/geoadd/ for more details.
*/
export class GeoAddOptions {
/** Redis API keyword use to modify the return value from the number of new elements added, to the total number of elements changed. */
public static CHANGED_VALKEY_API = "CH";

private updateMode?: ConditionalChange;

private changed?: boolean;

/**
*
* default constructor for GeoAddOptions.
*
* @param updateMode - Options for handling existing members. See {@link ConditionalChange}.
* @param latitude - If `true`, returns the count of changed elements instead of new elements added.
*/
constructor(options: {
updateMode?: ConditionalChange;
changed?: boolean;
}) {
this.updateMode = options.updateMode;
this.changed = options.changed;
}

/**
*
* Converts GeoAddOptions into a string[].
*
* @returns string[]
*/
public toArgs(): string[] {
const args: string[] = [];

if (this.updateMode !== undefined) {
args.push(this.updateMode.toString());
}

if (this.changed !== undefined) {
args.push(GeoAddOptions.CHANGED_VALKEY_API);
args.push(this.changed.toString());
}

return args;
}
}
39 changes: 39 additions & 0 deletions node/src/command-options/geospatial/GeospatialData.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/**
* Copyright Valkey GLIDE Project Contributors - SPDX Identifier: Apache-2.0
*/

/**
* Represents a geographic position defined by longitude and latitude.
* The exact limits, as specified by `EPSG:900913 / EPSG:3785 / OSGEO:41001` are the
* following:
*
* Valid longitudes are from `-180` to `180` degrees.
* Valid latitudes are from `-85.05112878` to `85.05112878` degrees.
*/
export class GeospatialData {
private longitude: number;

private latitude: number;

/**
*
* default constructor for GeospatialData.
*
* @param longitude - The longitude coordinate.
* @param latitude - The latitude coordinate.
*/
constructor(coord: { longitude: number; latitude: number }) {
this.longitude = coord.longitude;
this.latitude = coord.latitude;
}

/**
*
* Converts GeospatialData into a string[].
*
* @returns string[]
*/
public toArgs(): string[] {
return [this.longitude.toString(), this.latitude.toString()];
}
}

0 comments on commit bad84c5

Please sign in to comment.