From 5fe051b771e726678749804cdb4f70b777d3a8f6 Mon Sep 17 00:00:00 2001 From: ogzhanolguncu Date: Wed, 18 Oct 2023 15:40:21 +0300 Subject: [PATCH 1/3] Add GEOHASH command to sdk --- pkg/commands/geo_hash.test.ts | 34 ++++++++++++++++++++++++++++++++++ pkg/commands/geo_hash.ts | 20 ++++++++++++++++++++ pkg/commands/mod.ts | 1 + pkg/pipeline.ts | 7 +++++++ pkg/redis.ts | 17 ++++++++++++----- 5 files changed, 74 insertions(+), 5 deletions(-) create mode 100644 pkg/commands/geo_hash.test.ts create mode 100644 pkg/commands/geo_hash.ts diff --git a/pkg/commands/geo_hash.test.ts b/pkg/commands/geo_hash.test.ts new file mode 100644 index 00000000..02a42f07 --- /dev/null +++ b/pkg/commands/geo_hash.test.ts @@ -0,0 +1,34 @@ +import { assertEquals } from "https://deno.land/std@0.203.0/assert/assert_equals.ts"; +import { newHttpClient } from "../test-utils.ts"; + +import { GeoAddCommand } from "./geo_add.ts"; +import { GeoHashCommand } from "./geo_hash.ts"; + +const client = newHttpClient(); + +Deno.test("should accept two member array and return valid hash", async () => { + const key = "Sicily"; + const members = ["Palermo", "Catania"]; + await new GeoAddCommand([ + key, + { longitude: 13.361389, latitude: 38.115556, member: members[0] }, + { longitude: 15.087269, latitude: 37.502669, member: members[1] }, + ]).exec(client); + + const response = await new GeoHashCommand([key, members]).exec(client); + assertEquals(response.length, 2); +}); + +Deno.test("should accept three different string members and return valid hash", async () => { + const key = "Sicily"; + const members = ["Palermo", "Catania", "Marsala"]; + await new GeoAddCommand([ + key, + { longitude: 13.361389, latitude: 38.115556, member: members[0] }, + { longitude: 15.087269, latitude: 37.502669, member: members[1] }, + { longitude: 12.4372, latitude: 37.7981, member: members[2] }, + ]).exec(client); + + const response = await new GeoHashCommand([key, "Palermo", "Catania", "Marsala"]).exec(client); + assertEquals(response.length, 3); +}); diff --git a/pkg/commands/geo_hash.ts b/pkg/commands/geo_hash.ts new file mode 100644 index 00000000..f52dc0d6 --- /dev/null +++ b/pkg/commands/geo_hash.ts @@ -0,0 +1,20 @@ +import { Command, CommandOptions } from "./command.ts"; + +/** + * @see https://redis.io/commands/geohash + */ +export class GeoHashCommand + extends Command<(string | null)[], TData> { + constructor( + cmd: [string, ...string[]] | [string, string[]], + opts?: CommandOptions<(string | null)[], TData>, + ) { + const [key] = cmd; + // Check if the second argument is an array of strings (members). + // If it is, use it directly; if not, it means the members were passed individually, + // so we slice the cmd from the second element onwards to get the members. + const members = Array.isArray(cmd[1]) ? cmd[1] : cmd.slice(1); + + super(["GEOHASH", key, ...members], opts); + } +} diff --git a/pkg/commands/mod.ts b/pkg/commands/mod.ts index 10dbaa00..0d4189f6 100644 --- a/pkg/commands/mod.ts +++ b/pkg/commands/mod.ts @@ -16,6 +16,7 @@ export * from "./expireat.ts"; export * from "./flushall.ts"; export * from "./flushdb.ts"; export * from "./geo_add.ts"; +export * from "./geo_hash.ts"; export * from "./get.ts"; export * from "./getbit.ts"; export * from "./getdel.ts"; diff --git a/pkg/pipeline.ts b/pkg/pipeline.ts index 7e46ec14..e415d40f 100644 --- a/pkg/pipeline.ts +++ b/pkg/pipeline.ts @@ -15,6 +15,7 @@ import { ExpireCommand, FlushAllCommand, FlushDBCommand, + GeoHashCommand, GetBitCommand, GetCommand, GetDelCommand, @@ -1152,6 +1153,12 @@ export class Pipeline[] = []> { forget: (...args: CommandArgs) => this.chain(new JsonForgetCommand(args, this.commandOptions)), + /** + * @see https://redis.io/commands/geohash + */ + geohash: (...args: CommandArgs) => + new GeoHashCommand(args, this.commandOptions).exec(this.client), + /** * @see https://redis.io/commands/json.get */ diff --git a/pkg/redis.ts b/pkg/redis.ts index 0d5d1fb4..0f2da3ea 100644 --- a/pkg/redis.ts +++ b/pkg/redis.ts @@ -156,6 +156,7 @@ import { Script } from "./script.ts"; import { ZMScoreCommand } from "./commands/zmscore.ts"; import { ZDiffStoreCommand } from "./commands/zdiffstore.ts"; import type { RedisOptions, Telemetry } from "./types.ts"; +import { GeoHashCommand } from "./commands/geo_hash.ts"; // See https://github.com/upstash/upstash-redis/issues/342 // why we need this export @@ -248,6 +249,12 @@ export class Redis { geoadd: (...args: CommandArgs) => new GeoAddCommand(args, this.opts).exec(this.client), + /** + * @see https://redis.io/commands/geohash + */ + geohash: (...args: CommandArgs) => + new GeoHashCommand(args, this.opts).exec(this.client), + /** * @see https://redis.io/commands/json.get */ @@ -416,7 +423,9 @@ export class Redis { new BitOpCommand( [op as any, destinationKey, sourceKey, ...sourceKeys], this.opts, - ).exec(this.client); + ).exec( + this.client, + ); /** * @see https://redis.io/commands/bitpos @@ -604,10 +613,8 @@ export class Redis { count?: number, withValues?: boolean, ) => - new HRandFieldCommand( - [key, count, withValues] as any, - this.opts, - ).exec(this.client); + new HRandFieldCommand([key, count, withValues] as any, this.opts) + .exec(this.client); /** * @see https://redis.io/commands/hscan From 679603d2048068b36112bb7d79dc90d2026d4c19 Mon Sep 17 00:00:00 2001 From: chronark Date: Thu, 19 Oct 2023 10:55:32 +0200 Subject: [PATCH 2/3] fix: members are generic --- deno.lock | 7 +++++++ pkg/commands/geo_hash.test.ts | 20 +++++++++++++++++++- pkg/commands/geo_hash.ts | 8 ++++---- 3 files changed, 30 insertions(+), 5 deletions(-) diff --git a/deno.lock b/deno.lock index e4023815..06a0d0ca 100644 --- a/deno.lock +++ b/deno.lock @@ -44,6 +44,13 @@ "https://deno.land/std@0.201.0/assert/unreachable.ts": "4600dc0baf7d9c15a7f7d234f00c23bca8f3eba8b140286aaca7aa998cf9a536", "https://deno.land/std@0.201.0/fmt/colors.ts": "87544aa2bc91087bb37f9c077970c85bfb041b48e4c37356129d7b450a415b6f", "https://deno.land/std@0.201.0/testing/asserts.ts": "b4e4b1359393aeff09e853e27901a982c685cb630df30426ed75496961931946", + "https://deno.land/std@0.203.0/assert/_constants.ts": "8a9da298c26750b28b326b297316cdde860bc237533b07e1337c021379e6b2a9", + "https://deno.land/std@0.203.0/assert/_diff.ts": "1a3c044aedf77647d6cac86b798c6417603361b66b54c53331b312caeb447aea", + "https://deno.land/std@0.203.0/assert/_format.ts": "a69126e8a469009adf4cf2a50af889aca364c349797e63174884a52ff75cf4c7", + "https://deno.land/std@0.203.0/assert/assert_equals.ts": "d8ec8a22447fbaf2fc9d7c3ed2e66790fdb74beae3e482855d75782218d68227", + "https://deno.land/std@0.203.0/assert/assertion_error.ts": "4d0bde9b374dfbcbe8ac23f54f567b77024fb67dbb1906a852d67fe050d42f56", + "https://deno.land/std@0.203.0/assert/equal.ts": "9f1a46d5993966d2596c44e5858eec821859b45f783a5ee2f7a695dfc12d8ece", + "https://deno.land/std@0.203.0/fmt/colors.ts": "c51c4642678eb690dcf5ffee5918b675bf01a33fba82acf303701ae1a4f8c8d9", "https://deno.land/std@0.204.0/assert/_constants.ts": "8a9da298c26750b28b326b297316cdde860bc237533b07e1337c021379e6b2a9", "https://deno.land/std@0.204.0/assert/_diff.ts": "58e1461cc61d8eb1eacbf2a010932bf6a05b79344b02ca38095f9b805795dc48", "https://deno.land/std@0.204.0/assert/_format.ts": "a69126e8a469009adf4cf2a50af889aca364c349797e63174884a52ff75cf4c7", diff --git a/pkg/commands/geo_hash.test.ts b/pkg/commands/geo_hash.test.ts index 02a42f07..ba7aa2a4 100644 --- a/pkg/commands/geo_hash.test.ts +++ b/pkg/commands/geo_hash.test.ts @@ -29,6 +29,24 @@ Deno.test("should accept three different string members and return valid hash", { longitude: 12.4372, latitude: 37.7981, member: members[2] }, ]).exec(client); - const response = await new GeoHashCommand([key, "Palermo", "Catania", "Marsala"]).exec(client); + const response = await new GeoHashCommand([ + key, + "Palermo", + "Catania", + "Marsala", + ]).exec(client); assertEquals(response.length, 3); }); + +Deno.test("should accept two objects as members", async () => { + const key = "Sicily"; + const members = [{ name: "Palermo" }, { name: "Catania" }]; + await new GeoAddCommand([ + key, + { longitude: 13.361389, latitude: 38.115556, member: members[0] }, + { longitude: 15.087269, latitude: 37.502669, member: members[1] }, + ]).exec(client); + + const response = await new GeoHashCommand([key, members]).exec(client); + assertEquals(response.length, 2); +}); diff --git a/pkg/commands/geo_hash.ts b/pkg/commands/geo_hash.ts index f52dc0d6..740bf954 100644 --- a/pkg/commands/geo_hash.ts +++ b/pkg/commands/geo_hash.ts @@ -3,11 +3,11 @@ import { Command, CommandOptions } from "./command.ts"; /** * @see https://redis.io/commands/geohash */ -export class GeoHashCommand - extends Command<(string | null)[], TData> { +export class GeoHashCommand + extends Command<(string | null)[], (string | null)[]> { constructor( - cmd: [string, ...string[]] | [string, string[]], - opts?: CommandOptions<(string | null)[], TData>, + cmd: [string, ...TMember[] | TMember[]], + opts?: CommandOptions<(string | null)[], (string | null)[]>, ) { const [key] = cmd; // Check if the second argument is an array of strings (members). From 01cfa5eeefc595b7bcd72a1e314353bff3eb5046 Mon Sep 17 00:00:00 2001 From: ogzhanolguncu Date: Thu, 26 Oct 2023 15:10:49 +0300 Subject: [PATCH 3/3] Update test file --- pkg/commands/geo_hash.test.ts | 48 ++++++++++++++++++----------------- 1 file changed, 25 insertions(+), 23 deletions(-) diff --git a/pkg/commands/geo_hash.test.ts b/pkg/commands/geo_hash.test.ts index 02a42f07..a23e8d06 100644 --- a/pkg/commands/geo_hash.test.ts +++ b/pkg/commands/geo_hash.test.ts @@ -1,4 +1,4 @@ -import { assertEquals } from "https://deno.land/std@0.203.0/assert/assert_equals.ts"; +import { describe, expect, test } from "bun:test"; import { newHttpClient } from "../test-utils.ts"; import { GeoAddCommand } from "./geo_add.ts"; @@ -6,29 +6,31 @@ import { GeoHashCommand } from "./geo_hash.ts"; const client = newHttpClient(); -Deno.test("should accept two member array and return valid hash", async () => { - const key = "Sicily"; - const members = ["Palermo", "Catania"]; - await new GeoAddCommand([ - key, - { longitude: 13.361389, latitude: 38.115556, member: members[0] }, - { longitude: 15.087269, latitude: 37.502669, member: members[1] }, - ]).exec(client); +describe("GEOHASH tests", () => { + test("should accept two member array and return valid hash", async () => { + const key = "Sicily"; + const members = ["Palermo", "Catania"]; + await new GeoAddCommand([ + key, + { longitude: 13.361389, latitude: 38.115556, member: members[0] }, + { longitude: 15.087269, latitude: 37.502669, member: members[1] }, + ]).exec(client); - const response = await new GeoHashCommand([key, members]).exec(client); - assertEquals(response.length, 2); -}); + const response = await new GeoHashCommand([key, members]).exec(client); + expect(response.length).toEqual(2); + }); -Deno.test("should accept three different string members and return valid hash", async () => { - const key = "Sicily"; - const members = ["Palermo", "Catania", "Marsala"]; - await new GeoAddCommand([ - key, - { longitude: 13.361389, latitude: 38.115556, member: members[0] }, - { longitude: 15.087269, latitude: 37.502669, member: members[1] }, - { longitude: 12.4372, latitude: 37.7981, member: members[2] }, - ]).exec(client); + test("should accept three different string members and return valid hash", async () => { + const key = "Sicily"; + const members = ["Palermo", "Catania", "Marsala"]; + await new GeoAddCommand([ + key, + { longitude: 13.361389, latitude: 38.115556, member: members[0] }, + { longitude: 15.087269, latitude: 37.502669, member: members[1] }, + { longitude: 12.4372, latitude: 37.7981, member: members[2] }, + ]).exec(client); - const response = await new GeoHashCommand([key, "Palermo", "Catania", "Marsala"]).exec(client); - assertEquals(response.length, 3); + const response = await new GeoHashCommand([key, "Palermo", "Catania", "Marsala"]).exec(client); + expect(response.length).toEqual(3); + }); });