Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

support Redis function #598

Merged
merged 1 commit into from
Oct 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 88 additions & 0 deletions src/sw/redis++/async_redis.h
Original file line number Diff line number Diff line change
Expand Up @@ -1613,6 +1613,94 @@ class AsyncRedis {
return evalsha<Result>(script, keys.begin(), keys.end(), args.begin(), args.end(), std::forward<Callback>(cb));
}

template <typename Result, typename Keys, typename Args>
Future<Result> fcall(const StringView &func,
Keys keys_first,
Keys keys_last,
Args args_first,
Args args_last) {
return _command<Result>(fmt::fcall<Keys, Args>,
func, keys_first, keys_last, args_first, args_last);
}

template <typename Result, typename Keys, typename Args, typename Callback>
auto fcall(const StringView &func,
Keys keys_first,
Keys keys_last,
Args args_first,
Args args_last,
Callback &&cb)
-> typename std::enable_if<IsInvocable<typename std::decay<Callback>::type, Future<Result> &&>::value, void>::type {
_callback_fmt_command<Result>(std::forward<Callback>(cb), fmt::fcall<Keys, Args>,
func, keys_first, keys_last, args_first, args_last);
}

template <typename Result>
Future<Result> fcall(const StringView &func,
std::initializer_list<StringView> keys,
std::initializer_list<StringView> args) {
return fcall<Result>(func,
keys.begin(), keys.end(),
args.begin(), args.end());
}

template <typename Result, typename Callback>
auto fcall(const StringView &func,
std::initializer_list<StringView> keys,
std::initializer_list<StringView> args,
Callback &&cb)
-> typename std::enable_if<IsInvocable<typename std::decay<Callback>::type, Future<Result> &&>::value, void>::type {
return fcall<Result>(func, keys.begin(), keys.end(), args.begin(), args.end(), std::forward<Callback>(cb));
}

template <typename Result, typename Keys, typename Args>
Future<Result> fcall_ro(const StringView &func,
Keys keys_first,
Keys keys_last,
Args args_first,
Args args_last) {
return _command<Result>(fmt::fcall_ro<Keys, Args>,
func, keys_first, keys_last, args_first, args_last);
}

template <typename Result, typename Keys, typename Args, typename Callback>
auto fcall_ro(const StringView &func,
Keys keys_first,
Keys keys_last,
Args args_first,
Args args_last,
Callback &&cb)
-> typename std::enable_if<IsInvocable<typename std::decay<Callback>::type, Future<Result> &&>::value, void>::type {
_callback_fmt_command<Result>(std::forward<Callback>(cb), fmt::fcall_ro<Keys, Args>,
func, keys_first, keys_last, args_first, args_last);
}

template <typename Result>
Future<Result> fcall_ro(const StringView &func,
std::initializer_list<StringView> keys,
std::initializer_list<StringView> args) {
return fcall_ro<Result>(func,
keys.begin(), keys.end(),
args.begin(), args.end());
}

template <typename Result, typename Callback>
auto fcall_ro(const StringView &func,
std::initializer_list<StringView> keys,
std::initializer_list<StringView> args,
Callback &&cb)
-> typename std::enable_if<IsInvocable<typename std::decay<Callback>::type, Future<Result> &&>::value, void>::type {
return fcall_ro<Result>(func, keys.begin(), keys.end(), args.begin(), args.end(), std::forward<Callback>(cb));
}

Future<std::string> function_load(const StringView &code, bool replace = false) {
return _command<std::string>(fmt::function_load, code, replace);
}

Future<void> function_delete(const StringView &lib_name) {
return _command<void>(fmt::function_delete, lib_name);
}

// PUBSUB commands.

Future<long long> publish(const StringView &channel, const StringView &message) {
Expand Down
48 changes: 48 additions & 0 deletions src/sw/redis++/async_redis_cluster.h
Original file line number Diff line number Diff line change
Expand Up @@ -1075,6 +1075,54 @@ class AsyncRedisCluster {
args.begin(), args.end());
}

template <typename Result, typename Keys, typename Args>
Future<Result> fcall(const StringView &func,
Keys keys_first,
Keys keys_last,
Args args_first,
Args args_last) {
if (keys_first == keys_last) {
throw Error("DO NOT support function without key");
}

return _generic_command<Result>(fmt::fcall<Keys, Args>, *keys_first, func,
keys_first, keys_last,
args_first, args_last);
}

template <typename Result>
Future<Result> fcall(const StringView &func,
std::initializer_list<StringView> keys,
std::initializer_list<StringView> args) {
return fcall<Result>(func,
keys.begin(), keys.end(),
args.begin(), args.end());
}

template <typename Result, typename Keys, typename Args>
Future<Result> fcall_ro(const StringView &func,
Keys keys_first,
Keys keys_last,
Args args_first,
Args args_last) {
if (keys_first == keys_last) {
throw Error("DO NOT support function without key");
}

return _generic_command<Result>(fmt::fcall_ro<Keys, Args>, *keys_first, func,
keys_first, keys_last,
args_first, args_last);
}

template <typename Result>
Future<Result> fcall_ro(const StringView &func,
std::initializer_list<StringView> keys,
std::initializer_list<StringView> args) {
return fcall_ro<Result>(func,
keys.begin(), keys.end(),
args.begin(), args.end());
}

// PUBSUB commands.

Future<long long> publish(const StringView &channel, const StringView &message) {
Expand Down
50 changes: 50 additions & 0 deletions src/sw/redis++/cmd_formatter.h
Original file line number Diff line number Diff line change
Expand Up @@ -791,6 +791,56 @@ FormattedCommand evalsha(const StringView &script,
return format_cmd(args);
}

template <typename Keys, typename Args>
FormattedCommand fcall(const StringView &func,
Keys keys_first,
Keys keys_last,
Args args_first,
Args args_last) {
CmdArgs args;
auto keys_num = std::distance(keys_first, keys_last);

args << "FCALL" << func << keys_num
<< std::make_pair(keys_first, keys_last)
<< std::make_pair(args_first, args_last);

return format_cmd(args);
}

template <typename Keys, typename Args>
FormattedCommand fcall_ro(const StringView &func,
Keys keys_first,
Keys keys_last,
Args args_first,
Args args_last) {
CmdArgs args;
auto keys_num = std::distance(keys_first, keys_last);

args << "FCALL_RO" << func << keys_num
<< std::make_pair(keys_first, keys_last)
<< std::make_pair(args_first, args_last);

return format_cmd(args);
}

inline FormattedCommand function_load(const StringView &code, bool replace) {
CmdArgs cmd_args;

cmd_args << "FUNCTION" << "LOAD";

if (replace) {
cmd_args << "REPLACE";
}

cmd_args << code;

return format_cmd(cmd_args);
}

inline FormattedCommand function_delete(const StringView &lib_name) {
return format_cmd("FUNCTION DELETE %b", lib_name.data(), lib_name.size());
}

// PUBSUB commands.

inline FormattedCommand psubscribe(const StringView &pattern) {
Expand Down
56 changes: 56 additions & 0 deletions src/sw/redis++/command.h
Original file line number Diff line number Diff line change
Expand Up @@ -1568,6 +1568,62 @@ inline void script_load(Connection &connection, const StringView &script) {
connection.send("SCRIPT LOAD %b", script.data(), script.size());
}

template <typename Keys, typename Args>
inline void fcall(Connection &connection,
const StringView &func,
Keys keys_first,
Keys keys_last,
Args args_first,
Args args_last) {
CmdArgs cmd_args;

auto keys_num = std::distance(keys_first, keys_last);

cmd_args << "FCALL" << func << keys_num
<< std::make_pair(keys_first, keys_last)
<< std::make_pair(args_first, args_last);

connection.send(cmd_args);
}

template <typename Keys, typename Args>
inline void fcall_ro(Connection &connection,
const StringView &func,
Keys keys_first,
Keys keys_last,
Args args_first,
Args args_last) {
CmdArgs cmd_args;

auto keys_num = std::distance(keys_first, keys_last);

cmd_args << "FCALL_RO" << func << keys_num
<< std::make_pair(keys_first, keys_last)
<< std::make_pair(args_first, args_last);

connection.send(cmd_args);
}

inline void function_load(Connection &connection,
const StringView &code,
bool replace) {
CmdArgs cmd_args;

cmd_args << "FUNCTION" << "LOAD";

if (replace) {
cmd_args << "REPLACE";
}

cmd_args << code;

connection.send(cmd_args);
}

inline void function_delete(Connection &connection, const StringView &lib_name) {
connection.send("FUNCTION DELETE %b", lib_name.data(), lib_name.size());
}

// PUBSUB commands.

inline void psubscribe(Connection &connection, const StringView &pattern) {
Expand Down
12 changes: 12 additions & 0 deletions src/sw/redis++/redis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -855,6 +855,18 @@ std::string Redis::script_load(const StringView &script) {
return reply::parse<std::string>(*reply);
}

std::string Redis::function_load(const StringView &code, bool replace) {
auto reply = command(cmd::function_load, code, replace);

return reply::parse<std::string>(*reply);
}

void Redis::function_delete(const StringView &lib_name) {
auto reply = command(cmd::function_delete, lib_name);

reply::parse<void>(*reply);
}

// PUBSUB commands.

long long Redis::publish(const StringView &channel, const StringView &message) {
Expand Down
56 changes: 56 additions & 0 deletions src/sw/redis++/redis.h
Original file line number Diff line number Diff line change
Expand Up @@ -3247,6 +3247,62 @@ class Redis {

std::string script_load(const StringView &script);

template <typename Result, typename Keys, typename Args>
Result fcall(const StringView &func,
Keys keys_first,
Keys keys_last,
Args args_first,
Args args_last);

template <typename Result>
Result fcall(const StringView &func,
std::initializer_list<StringView> keys,
std::initializer_list<StringView> args);

template <typename Keys, typename Args, typename Output>
void fcall(const StringView &func,
Keys keys_first,
Keys keys_last,
Args args_first,
Args args_last,
Output output);

template <typename Output>
void fcall(const StringView &func,
std::initializer_list<StringView> keys,
std::initializer_list<StringView> args,
Output output);

template <typename Result, typename Keys, typename Args>
Result fcall_ro(const StringView &func,
Keys keys_first,
Keys keys_last,
Args args_first,
Args args_last);

template <typename Result>
Result fcall_ro(const StringView &func,
std::initializer_list<StringView> keys,
std::initializer_list<StringView> args);

template <typename Keys, typename Args, typename Output>
void fcall_ro(const StringView &func,
Keys keys_first,
Keys keys_last,
Args args_first,
Args args_last,
Output output);

template <typename Output>
void fcall_ro(const StringView &func,
std::initializer_list<StringView> keys,
std::initializer_list<StringView> args,
Output output);

std::string function_load(const StringView &code, bool replace = false);

void function_delete(const StringView &lib_name);

// PUBSUB commands.

long long publish(const StringView &channel, const StringView &message);
Expand Down
Loading
Loading