From fd772d5754cc2ddc3004bef746988ce186c83ce5 Mon Sep 17 00:00:00 2001 From: Yusuke Sakurai Date: Sat, 14 Mar 2020 19:48:05 +0900 Subject: [PATCH] fix: bitfield (#64) --- command.ts | 8 ++++---- redis.ts | 25 +++++++++++++++++++++++-- tests/geo_test.ts | 1 - tests/string_test.ts | 17 +++++++++++++++++ 4 files changed, 44 insertions(+), 7 deletions(-) diff --git a/command.ts b/command.ts index 7aaa64f5..120f9e9e 100644 --- a/command.ts +++ b/command.ts @@ -92,13 +92,13 @@ export type RedisCommands = { bitcount(key: string): Promise; bitcount(key: string, start: number, end: number): Promise; bitfield(key: string, opts?: { - get?: { type: string; offset: number }; - set?: { type: string; offset: number }; - incrby?: { type: string; offset: number; increment: number }; + get?: { type: string; offset: number | string }; + set?: { type: string; offset: number | string; value: number }; + incrby?: { type: string; offset: number | string; increment: number }; }): Promise; bitfield(key: string, opts?: { get?: { type: string; offset: number }; - set?: { type: string; offset: number }; + set?: { type: string; offset: number; value: number }; incrby?: { type: string; offset: number; increment: number }; overflow: "WRAP" | "SAT" | "FAIL"; }): Promise<(Integer | BulkNil)[]>; diff --git a/redis.ts b/redis.ts index 2e077c4f..3fa16af7 100644 --- a/redis.ts +++ b/redis.ts @@ -112,8 +112,29 @@ class RedisImpl implements RedisCommands { } else return this.execIntegerReply("BITCOUNT", key); } - bitfield(key: string) { - return this.execArrayReply("BITFIELD", key) as Promise; + bitfield(key: string, opts?: { + get?: { type: string; offset: number | string }; + set?: { type: string; offset: number | string; value: number }; + incrby?: { type: string; offset: number | string; increment: number }; + overflow?: "WRAP" | "SAT" | "FAIL"; + }) { + const args: (number | string)[] = [key]; + if (opts?.get) { + const { type, offset } = opts.get; + args.push("GET", type, offset); + } + if (opts?.set) { + const { type, offset, value } = opts.set; + args.push("SET", type, offset, value); + } + if (opts?.incrby) { + const { type, offset, increment } = opts.incrby; + args.push("INCRBY", type, offset, increment); + } + if (opts?.overflow) { + args.push("OVERFLOW", opts.overflow); + } + return this.execArrayReply("BITFIELD", ...args) as Promise; } bitop(operation: string, destkey: string, ...keys: string[]) { diff --git a/tests/geo_test.ts b/tests/geo_test.ts index f0ce2ed4..525b16b7 100644 --- a/tests/geo_test.ts +++ b/tests/geo_test.ts @@ -1,4 +1,3 @@ -import { connect } from "../redis.ts"; import { assertEquals } from "../vendor/https/deno.land/std/testing/asserts.ts"; diff --git a/tests/string_test.ts b/tests/string_test.ts index 45329e30..981e085f 100644 --- a/tests/string_test.ts +++ b/tests/string_test.ts @@ -25,6 +25,23 @@ test("bitfieldWithoutOperations", async () => { assertEquals(v, []); }); +test("bitfield with opts", async () => { + await client.set("key", "4660"); + const v = await client.bitfield("key", { + get: { type: "u8", offset: 0 }, + set: { type: "i5", offset: 1, value: 0 }, + incrby: { type: "u16", offset: 2, increment: 2 } + }); + assertEquals(v, [52, 13, 218]); +}); + +test("bitfield with overflow", async () => { + const v = await client.bitfield("key", { + overflow: "FAIL" + }); + assertEquals(v, []); +}); + test("bitop", async () => { await client.set("key1", "foo"); // 01100110 01101111 01101111 await client.set("key2", "bar"); // 01100010 01100001 01110010