Skip to content

Commit

Permalink
revert addCommand/addScript changes to multi-commands
Browse files Browse the repository at this point in the history
addCommand needs to be there for sendCommand like ability within a multi.

If its there, it might as well be used by createCommand() et al, to avoid repeating code.

addScript is there (even though only used once), but now made private to keep the logic for bookkeeping near each other.
  • Loading branch information
sjpotter committed Oct 29, 2024
1 parent c1d69ae commit 7f52e7c
Show file tree
Hide file tree
Showing 3 changed files with 126 additions and 59 deletions.
37 changes: 22 additions & 15 deletions packages/client/lib/client/multi-command.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,59 +91,53 @@ export default class RedisClientMultiCommand<REPLIES = []> {
static #createCommand(command: Command, resp: RespVersions) {
const transformReply = getTransformReply(command, resp);

return function (this: RedisClientMultiCommand, ...args: Array<unknown>): RedisClientMultiCommand {
return function (this: RedisClientMultiCommand, ...args: Array<unknown>) {
const parser = new BasicCommandParser();
command.parseCommand(parser, ...args);

const redisArgs: CommandArguments = parser.redisArgs;
redisArgs.preserve = parser.preserve;

this.#multi.addCommand(
return this.addCommand(
redisArgs,
transformReply
);

return this;
};
}

static #createModuleCommand(command: Command, resp: RespVersions) {
const transformReply = getTransformReply(command, resp);

return function (this: { _self: RedisClientMultiCommand }, ...args: Array<unknown>): RedisClientMultiCommand {
return function (this: { _self: RedisClientMultiCommand }, ...args: Array<unknown>) {
const parser = new BasicCommandParser();
command.parseCommand(parser, ...args);

const redisArgs: CommandArguments = parser.redisArgs;
redisArgs.preserve = parser.preserve;

this._self.#multi.addCommand(
return this._self.addCommand(
redisArgs,
transformReply
);

return this._self;
};
}

static #createFunctionCommand(name: string, fn: RedisFunction, resp: RespVersions) {
const prefix = functionArgumentsPrefix(name, fn);
const transformReply = getTransformReply(fn, resp);

return function (this: { _self: RedisClientMultiCommand }, ...args: Array<unknown>): RedisClientMultiCommand {
return function (this: { _self: RedisClientMultiCommand }, ...args: Array<unknown>) {
const parser = new BasicCommandParser();
parser.push(...prefix);
fn.parseCommand(parser, ...args);

const redisArgs: CommandArguments = parser.redisArgs;
redisArgs.preserve = parser.preserve;

this._self.#multi.addCommand(
return this._self.addCommand(
redisArgs,
transformReply
);

return this._self;
};
}

Expand All @@ -157,13 +151,11 @@ export default class RedisClientMultiCommand<REPLIES = []> {
const redisArgs: CommandArguments = parser.redisArgs;
redisArgs.preserve = parser.preserve;

this.#multi.addScript(
return this.#addScript(
script,
redisArgs,
transformReply
);

return this;
};
}

Expand Down Expand Up @@ -204,6 +196,21 @@ export default class RedisClientMultiCommand<REPLIES = []> {

select = this.SELECT;

addCommand(args: CommandArguments, transformReply?: TransformReply) {
this.#multi.addCommand(args, transformReply);
return this;
}

#addScript(
script: RedisScript,
args: CommandArguments,
transformReply?: TransformReply
) {
this.#multi.addScript(script, args, transformReply);

return this;
}

async exec<T extends MultiReply = MULTI_REPLY['GENERIC']>(execAsPipeline = false): Promise<MultiReplyType<T, REPLIES>> {
if (execAsPipeline) return this.execAsPipeline<T>();

Expand Down
79 changes: 56 additions & 23 deletions packages/client/lib/cluster/multi-command.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import COMMANDS from '../commands';
import RedisMultiCommand, { MULTI_REPLY, MultiReply, MultiReplyType, RedisMultiQueuedCommand } from '../multi-command';
import { ReplyWithTypeMapping, CommandReply, Command, CommandArguments, CommanderConfig, RedisFunctions, RedisModules, RedisScripts, RespVersions, RedisScript, RedisFunction, TypeMapping, RedisArgument } from '../RESP/types';
import { ReplyWithTypeMapping, CommandReply, Command, CommandArguments, CommanderConfig, RedisFunctions, RedisModules, RedisScripts, RespVersions, TransformReply, RedisScript, RedisFunction, TypeMapping, RedisArgument } from '../RESP/types';
import { attachConfig, functionArgumentsPrefix, getTransformReply } from '../commander';
import { BasicCommandParser } from '../client/parser';
import { Tail } from '../commands/generic-transformers';
Expand Down Expand Up @@ -95,44 +95,48 @@ export default class RedisClusterMultiCommand<REPLIES = []> {
static #createCommand(command: Command, resp: RespVersions) {
const transformReply = getTransformReply(command, resp);

return function (this: RedisClusterMultiCommand, ...args: Array<unknown>): RedisClusterMultiCommand {
return function (this: RedisClusterMultiCommand, ...args: Array<unknown>) {
const parser = new BasicCommandParser();
command.parseCommand(parser, ...args);

const redisArgs: CommandArguments = parser.redisArgs;
redisArgs.preserve = parser.preserve;
const firstKey = parser.firstKey;

this.#setState(firstKey, command.IS_READ_ONLY);
this.#multi.addCommand(redisArgs, transformReply);

return this;

return this.addCommand(
firstKey,
command.IS_READ_ONLY,
redisArgs,
transformReply
);
};
}

static #createModuleCommand(command: Command, resp: RespVersions) {
const transformReply = getTransformReply(command, resp);

return function (this: { _self: RedisClusterMultiCommand }, ...args: Array<unknown>): RedisClusterMultiCommand {
return function (this: { _self: RedisClusterMultiCommand }, ...args: Array<unknown>) {
const parser = new BasicCommandParser();
command.parseCommand(parser, ...args);

const redisArgs: CommandArguments = parser.redisArgs;
redisArgs.preserve = parser.preserve;
const firstKey = parser.firstKey;

this._self.#setState(firstKey, command.IS_READ_ONLY);
this._self.#multi.addCommand(redisArgs, transformReply);

return this._self;
return this._self.addCommand(
firstKey,
command.IS_READ_ONLY,
redisArgs,
transformReply
);
};
}

static #createFunctionCommand(name: string, fn: RedisFunction, resp: RespVersions) {
const prefix = functionArgumentsPrefix(name, fn);
const transformReply = getTransformReply(fn, resp);

return function (this: { _self: RedisClusterMultiCommand }, ...args: Array<unknown>): RedisClusterMultiCommand {
return function (this: { _self: RedisClusterMultiCommand }, ...args: Array<unknown>) {
const parser = new BasicCommandParser();
parser.push(...prefix);
fn.parseCommand(parser, ...args);
Expand All @@ -141,28 +145,33 @@ export default class RedisClusterMultiCommand<REPLIES = []> {
redisArgs.preserve = parser.preserve;
const firstKey = parser.firstKey;

this._self.#setState(firstKey, fn.IS_READ_ONLY);
this._self.#multi.addCommand(redisArgs, transformReply);

return this._self;
return this._self.addCommand(
firstKey,
fn.IS_READ_ONLY,
redisArgs,
transformReply
);
};
}

static #createScriptCommand(script: RedisScript, resp: RespVersions) {
const transformReply = getTransformReply(script, resp);

return function (this: RedisClusterMultiCommand, ...args: Array<unknown>): RedisClusterMultiCommand {
return function (this: RedisClusterMultiCommand, ...args: Array<unknown>) {
const parser = new BasicCommandParser();
script.parseCommand(parser, ...args);

const scriptArgs: CommandArguments = parser.redisArgs;
scriptArgs.preserve = parser.preserve;
const firstKey = parser.firstKey;

this.#setState(firstKey, script.IS_READ_ONLY);
this.#multi.addScript(script, scriptArgs, transformReply);

return this;
return this.#addScript(
firstKey,
script.IS_READ_ONLY,
script,
scriptArgs,
transformReply
);
};
}

Expand All @@ -183,7 +192,7 @@ export default class RedisClusterMultiCommand<REPLIES = []> {
});
}

readonly #multi: RedisMultiCommand;
readonly #multi: RedisMultiCommand

readonly #executeMulti: ClusterMultiExecute;
readonly #executePipeline: ClusterMultiExecute;
Expand All @@ -210,6 +219,30 @@ export default class RedisClusterMultiCommand<REPLIES = []> {
this.#isReadonly &&= isReadonly;
}

addCommand(
firstKey: RedisArgument | undefined,
isReadonly: boolean | undefined,
args: CommandArguments,
transformReply?: TransformReply
) {
this.#setState(firstKey, isReadonly);
this.#multi.addCommand(args, transformReply);
return this;
}

#addScript(
firstKey: RedisArgument | undefined,
isReadonly: boolean | undefined,
script: RedisScript,
args: CommandArguments,
transformReply?: TransformReply
) {
this.#setState(firstKey, isReadonly);
this.#multi.addScript(script, args, transformReply);

return this;
}

async exec<T extends MultiReply = MULTI_REPLY['GENERIC']>(execAsPipeline = false) {
if (execAsPipeline) return this.execAsPipeline<T>();

Expand Down
69 changes: 48 additions & 21 deletions packages/client/lib/sentinel/multi-commands.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import COMMANDS from '../commands';
import RedisMultiCommand, { MULTI_REPLY, MultiReply, MultiReplyType } from '../multi-command';
import { ReplyWithTypeMapping, CommandReply, Command, CommandArguments, CommanderConfig, RedisFunctions, RedisModules, RedisScripts, RespVersions, RedisScript, RedisFunction, TypeMapping } from '../RESP/types';
import { ReplyWithTypeMapping, CommandReply, Command, CommandArguments, CommanderConfig, RedisFunctions, RedisModules, RedisScripts, RespVersions, TransformReply, RedisScript, RedisFunction, TypeMapping } from '../RESP/types';
import { attachConfig, functionArgumentsPrefix, getTransformReply } from '../commander';
import { RedisSentinelType } from './types';
import { BasicCommandParser } from '../client/parser';
Expand Down Expand Up @@ -90,70 +90,75 @@ export default class RedisSentinelMultiCommand<REPLIES = []> {
private static _createCommand(command: Command, resp: RespVersions) {
const transformReply = getTransformReply(command, resp);

return function (this: RedisSentinelMultiCommand, ...args: Array<unknown>): RedisSentinelMultiCommand {
return function (this: RedisSentinelMultiCommand, ...args: Array<unknown>) {
const parser = new BasicCommandParser();
command.parseCommand(parser, ...args);

const redisArgs: CommandArguments = parser.redisArgs;
redisArgs.preserve = parser.preserve;

this.#setState(command.IS_READ_ONLY);
this.#multi.addCommand(redisArgs, transformReply);

return this;
return this.addCommand(
command.IS_READ_ONLY,
redisArgs,
transformReply
);
};
}

private static _createModuleCommand(command: Command, resp: RespVersions) {
const transformReply = getTransformReply(command, resp);

return function (this: { _self: RedisSentinelMultiCommand }, ...args: Array<unknown>): RedisSentinelMultiCommand {
return function (this: { _self: RedisSentinelMultiCommand }, ...args: Array<unknown>) {
const parser = new BasicCommandParser();
command.parseCommand(parser, ...args);

const redisArgs: CommandArguments = parser.redisArgs;
redisArgs.preserve = parser.preserve;

this._self.#setState(command.IS_READ_ONLY);
this._self.#multi.addCommand(redisArgs, transformReply);

return this._self;
return this._self.addCommand(
command.IS_READ_ONLY,
redisArgs,
transformReply
);
};
}

private static _createFunctionCommand(name: string, fn: RedisFunction, resp: RespVersions) {
const prefix = functionArgumentsPrefix(name, fn);
const transformReply = getTransformReply(fn, resp);

return function (this: { _self: RedisSentinelMultiCommand }, ...args: Array<unknown>): RedisSentinelMultiCommand {
return function (this: { _self: RedisSentinelMultiCommand }, ...args: Array<unknown>) {
const parser = new BasicCommandParser();
parser.push(...prefix);
fn.parseCommand(parser, ...args);

const redisArgs: CommandArguments = parser.redisArgs;
redisArgs.preserve = parser.preserve;

this._self.#setState(fn.IS_READ_ONLY);
this._self.#multi.addCommand(redisArgs, transformReply);

return this._self;
return this._self.addCommand(
fn.IS_READ_ONLY,
redisArgs,
transformReply
);
};
}

private static _createScriptCommand(script: RedisScript, resp: RespVersions) {
const transformReply = getTransformReply(script, resp);

return function (this: RedisSentinelMultiCommand, ...args: Array<unknown>): RedisSentinelMultiCommand {
return function (this: RedisSentinelMultiCommand, ...args: Array<unknown>) {
const parser = new BasicCommandParser();
script.parseCommand(parser, ...args);

const scriptArgs: CommandArguments = parser.redisArgs;
scriptArgs.preserve = parser.preserve;

this.#setState(script.IS_READ_ONLY);
this.#multi.addScript(script, scriptArgs, transformReply);

return this;
return this.#addScript(
script.IS_READ_ONLY,
script,
scriptArgs,
transformReply
);
};
}

Expand Down Expand Up @@ -189,6 +194,28 @@ export default class RedisSentinelMultiCommand<REPLIES = []> {
this.#isReadonly &&= isReadonly;
}

addCommand(
isReadonly: boolean | undefined,
args: CommandArguments,
transformReply?: TransformReply
) {
this.#setState(isReadonly);
this.#multi.addCommand(args, transformReply);
return this;
}

#addScript(
isReadonly: boolean | undefined,
script: RedisScript,
args: CommandArguments,
transformReply?: TransformReply
) {
this.#setState(isReadonly);
this.#multi.addScript(script, args, transformReply);

return this;
}

async exec<T extends MultiReply = MULTI_REPLY['GENERIC']>(execAsPipeline = false) {
if (execAsPipeline) return this.execAsPipeline<T>();

Expand Down

0 comments on commit 7f52e7c

Please sign in to comment.