Skip to content

Commit

Permalink
feat: support Redis Functions introduced in Redis 7.0
Browse files Browse the repository at this point in the history
  • Loading branch information
luin committed Mar 14, 2022
1 parent 53ca412 commit 32eb381
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 52 deletions.
30 changes: 15 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,21 +18,21 @@ Supports Redis >= 2.6.12 and (Node.js >= 12.22.0). Completely compatible with Re
ioredis is a robust, full-featured Redis client that is
used in the world's biggest online commerce company [Alibaba](http://www.alibaba.com/) and many other awesome companies.

0. Full-featured. It supports [Cluster](http://redis.io/topics/cluster-tutorial), [Sentinel](http://redis.io/topics/sentinel), [Streams](https://redis.io/topics/streams-intro), [Pipelining](http://redis.io/topics/pipelining) and of course [Lua scripting](http://redis.io/commands/eval) & [Pub/Sub](http://redis.io/topics/pubsub) (with the support of binary messages).
1. High performance 🚀.
2. Delightful API 😄. It works with Node callbacks and Native promises.
3. Transformation of command arguments and replies.
4. Transparent key prefixing.
5. Abstraction for Lua scripting, allowing you to define custom commands.
6. Support for binary data.
7. Support for TLS 🔒.
8. Support for offline queue and ready checking.
9. Support for ES6 types, such as `Map` and `Set`.
10. Support for GEO commands 📍.
11. Support for Redis ACL.
12. Sophisticated error handling strategy.
13. Support for NAT mapping.
14. Support for autopipelining
0. Full-featured. It supports [Cluster](http://redis.io/topics/cluster-tutorial), [Sentinel](http://redis.io/topics/sentinel), [Streams](https://redis.io/topics/streams-intro), [Pipelining](http://redis.io/topics/pipelining), and of course [Lua scripting](http://redis.io/commands/eval), [Redis Functions](https://redis.io/topics/functions-intro), [Pub/Sub](http://redis.io/topics/pubsub) (with the support of binary messages).
0. High performance 🚀.
0. Delightful API 😄. It works with Node callbacks and Native promises.
0. Transformation of command arguments and replies.
0. Transparent key prefixing.
0. Abstraction for Lua scripting, allowing you to [define custom commands](https://github.com/luin/ioredis#lua-scripting).
0. Supports [binary data](https://github.com/luin/ioredis#handle-binary-data).
0. Supports [TLS](https://github.com/luin/ioredis#tls-options) 🔒.
0. Supports offline queue and ready checking.
0. Supports ES6 types, such as `Map` and `Set`.
0. Supports GEO commands 📍.
0. Supports Redis ACL.
0. Sophisticated error handling strategy.
0. Supports NAT mapping.
0. Supports autopipelining

# Versions

Expand Down
17 changes: 17 additions & 0 deletions bin/generateRedisCommander/returnTypes.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,23 @@ module.exports = {
if (hasToken(types, ["NX", "XX"])) return "'OK' | null";
return "'OK'";
},
function: (types) => {
if (
matchSubcommand(types, [
"LOAD",
"DELETE",
"DUMP",
"FLUSH",
"KILL",
"RESTORE",
])
) {
return "string";
}
if (matchSubcommand(types, ["LIST"])) {
return "unknown[]";
}
},
ping: (types) => {
return types.length ? "string" : "'PONG'";
},
Expand Down
80 changes: 47 additions & 33 deletions lib/utils/RedisCommander.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1144,79 +1144,93 @@ interface RedisCommander<Context extends ClientContext = { type: "default" }> {
flushdb(sync: 'SYNC', callback?: Callback<'OK'>): Result<'OK', Context>;

/**
* List information about all the functions
* Dump all functions into a serialized binary payload
* - _group_: scripting
* - _complexity_: O(N) where N is the number of functions
* - _since_: 7.0.0
*/
function(subcommand: 'LIST', callback?: Callback<unknown>): Result<unknown, Context>;
function(subcommand: 'LIST', withcode: 'WITHCODE', callback?: Callback<unknown>): Result<unknown, Context>;
function(subcommand: 'LIST', libraryNamePatternToken: 'LIBRARYNAME', libraryNamePattern: string | Buffer, callback?: Callback<unknown>): Result<unknown, Context>;
function(subcommand: 'LIST', libraryNamePatternToken: 'LIBRARYNAME', libraryNamePattern: string | Buffer, withcode: 'WITHCODE', callback?: Callback<unknown>): Result<unknown, Context>;
function(subcommand: 'DUMP', callback?: Callback<string>): Result<string, Context>;
functionBuffer(subcommand: 'DUMP', callback?: Callback<Buffer>): Result<Buffer, Context>;

/**
* Restore all the functions on the given payload
* Show helpful text about the different subcommands
* - _group_: scripting
* - _complexity_: O(N) where N is the number of functions on the payload
* - _complexity_: O(1)
* - _since_: 7.0.0
*/
function(subcommand: 'RESTORE', serializedValue: string | Buffer | number, callback?: Callback<unknown>): Result<unknown, Context>;
function(subcommand: 'RESTORE', serializedValue: string | Buffer | number, flush: 'FLUSH', callback?: Callback<unknown>): Result<unknown, Context>;
function(subcommand: 'RESTORE', serializedValue: string | Buffer | number, append: 'APPEND', callback?: Callback<unknown>): Result<unknown, Context>;
function(subcommand: 'RESTORE', serializedValue: string | Buffer | number, replace: 'REPLACE', callback?: Callback<unknown>): Result<unknown, Context>;
function(subcommand: 'HELP', callback?: Callback<unknown>): Result<unknown, Context>;

/**
* Delete a function by name
* Deleting all functions
* - _group_: scripting
* - _complexity_: O(1)
* - _complexity_: O(N) where N is the number of functions deleted
* - _since_: 7.0.0
*/
function(subcommand: 'DELETE', libraryName: string | Buffer, callback?: Callback<unknown>): Result<unknown, Context>;
function(subcommand: 'FLUSH', callback?: Callback<string>): Result<string, Context>;
functionBuffer(subcommand: 'FLUSH', callback?: Callback<Buffer>): Result<Buffer, Context>;
function(subcommand: 'FLUSH', async: 'ASYNC', callback?: Callback<string>): Result<string, Context>;
functionBuffer(subcommand: 'FLUSH', async: 'ASYNC', callback?: Callback<Buffer>): Result<Buffer, Context>;
function(subcommand: 'FLUSH', sync: 'SYNC', callback?: Callback<string>): Result<string, Context>;
functionBuffer(subcommand: 'FLUSH', sync: 'SYNC', callback?: Callback<Buffer>): Result<Buffer, Context>;

/**
* Create a function with the given arguments (name, code, description)
* Kill the function currently in execution.
* - _group_: scripting
* - _complexity_: O(1) (considering compilation time is redundant)
* - _complexity_: O(1)
* - _since_: 7.0.0
*/
function(subcommand: 'LOAD', engineName: string | Buffer, libraryName: string | Buffer, functionCode: string | Buffer, callback?: Callback<unknown>): Result<unknown, Context>;
function(subcommand: 'LOAD', engineName: string | Buffer, libraryName: string | Buffer, libraryDescriptionToken: 'DESCRIPTION', libraryDescription: string | Buffer, functionCode: string | Buffer, callback?: Callback<unknown>): Result<unknown, Context>;
function(subcommand: 'LOAD', engineName: string | Buffer, libraryName: string | Buffer, replace: 'REPLACE', functionCode: string | Buffer, callback?: Callback<unknown>): Result<unknown, Context>;
function(subcommand: 'LOAD', engineName: string | Buffer, libraryName: string | Buffer, replace: 'REPLACE', libraryDescriptionToken: 'DESCRIPTION', libraryDescription: string | Buffer, functionCode: string | Buffer, callback?: Callback<unknown>): Result<unknown, Context>;
function(subcommand: 'KILL', callback?: Callback<string>): Result<string, Context>;
functionBuffer(subcommand: 'KILL', callback?: Callback<Buffer>): Result<Buffer, Context>;

/**
* Kill the function currently in execution.
* Delete a function by name
* - _group_: scripting
* - _complexity_: O(1)
* - _since_: 7.0.0
*/
function(subcommand: 'KILL', callback?: Callback<unknown>): Result<unknown, Context>;
function(subcommand: 'DELETE', libraryName: string | Buffer, callback?: Callback<string>): Result<string, Context>;
functionBuffer(subcommand: 'DELETE', libraryName: string | Buffer, callback?: Callback<Buffer>): Result<Buffer, Context>;

/**
* Dump all functions into a serialized binary payload
* Restore all the functions on the given payload
* - _group_: scripting
* - _complexity_: O(N) where N is the number of functions
* - _complexity_: O(N) where N is the number of functions on the payload
* - _since_: 7.0.0
*/
function(subcommand: 'DUMP', callback?: Callback<unknown>): Result<unknown, Context>;
function(subcommand: 'RESTORE', serializedValue: string | Buffer | number, callback?: Callback<string>): Result<string, Context>;
functionBuffer(subcommand: 'RESTORE', serializedValue: string | Buffer | number, callback?: Callback<Buffer>): Result<Buffer, Context>;
function(subcommand: 'RESTORE', serializedValue: string | Buffer | number, flush: 'FLUSH', callback?: Callback<string>): Result<string, Context>;
functionBuffer(subcommand: 'RESTORE', serializedValue: string | Buffer | number, flush: 'FLUSH', callback?: Callback<Buffer>): Result<Buffer, Context>;
function(subcommand: 'RESTORE', serializedValue: string | Buffer | number, append: 'APPEND', callback?: Callback<string>): Result<string, Context>;
functionBuffer(subcommand: 'RESTORE', serializedValue: string | Buffer | number, append: 'APPEND', callback?: Callback<Buffer>): Result<Buffer, Context>;
function(subcommand: 'RESTORE', serializedValue: string | Buffer | number, replace: 'REPLACE', callback?: Callback<string>): Result<string, Context>;
functionBuffer(subcommand: 'RESTORE', serializedValue: string | Buffer | number, replace: 'REPLACE', callback?: Callback<Buffer>): Result<Buffer, Context>;

/**
* Show helpful text about the different subcommands
* List information about all the functions
* - _group_: scripting
* - _complexity_: O(1)
* - _complexity_: O(N) where N is the number of functions
* - _since_: 7.0.0
*/
function(subcommand: 'HELP', callback?: Callback<unknown>): Result<unknown, Context>;
function(subcommand: 'LIST', callback?: Callback<unknown[]>): Result<unknown[], Context>;
function(subcommand: 'LIST', withcode: 'WITHCODE', callback?: Callback<unknown[]>): Result<unknown[], Context>;
function(subcommand: 'LIST', libraryNamePatternToken: 'LIBRARYNAME', libraryNamePattern: string | Buffer, callback?: Callback<unknown[]>): Result<unknown[], Context>;
function(subcommand: 'LIST', libraryNamePatternToken: 'LIBRARYNAME', libraryNamePattern: string | Buffer, withcode: 'WITHCODE', callback?: Callback<unknown[]>): Result<unknown[], Context>;

/**
* Deleting all functions
* Create a function with the given arguments (name, code, description)
* - _group_: scripting
* - _complexity_: O(N) where N is the number of functions deleted
* - _complexity_: O(1) (considering compilation time is redundant)
* - _since_: 7.0.0
*/
function(subcommand: 'FLUSH', callback?: Callback<unknown>): Result<unknown, Context>;
function(subcommand: 'FLUSH', async: 'ASYNC', callback?: Callback<unknown>): Result<unknown, Context>;
function(subcommand: 'FLUSH', sync: 'SYNC', callback?: Callback<unknown>): Result<unknown, Context>;
function(subcommand: 'LOAD', engineName: string | Buffer, libraryName: string | Buffer, functionCode: string | Buffer, callback?: Callback<string>): Result<string, Context>;
functionBuffer(subcommand: 'LOAD', engineName: string | Buffer, libraryName: string | Buffer, functionCode: string | Buffer, callback?: Callback<Buffer>): Result<Buffer, Context>;
function(subcommand: 'LOAD', engineName: string | Buffer, libraryName: string | Buffer, libraryDescriptionToken: 'DESCRIPTION', libraryDescription: string | Buffer, functionCode: string | Buffer, callback?: Callback<string>): Result<string, Context>;
functionBuffer(subcommand: 'LOAD', engineName: string | Buffer, libraryName: string | Buffer, libraryDescriptionToken: 'DESCRIPTION', libraryDescription: string | Buffer, functionCode: string | Buffer, callback?: Callback<Buffer>): Result<Buffer, Context>;
function(subcommand: 'LOAD', engineName: string | Buffer, libraryName: string | Buffer, replace: 'REPLACE', functionCode: string | Buffer, callback?: Callback<string>): Result<string, Context>;
functionBuffer(subcommand: 'LOAD', engineName: string | Buffer, libraryName: string | Buffer, replace: 'REPLACE', functionCode: string | Buffer, callback?: Callback<Buffer>): Result<Buffer, Context>;
function(subcommand: 'LOAD', engineName: string | Buffer, libraryName: string | Buffer, replace: 'REPLACE', libraryDescriptionToken: 'DESCRIPTION', libraryDescription: string | Buffer, functionCode: string | Buffer, callback?: Callback<string>): Result<string, Context>;
functionBuffer(subcommand: 'LOAD', engineName: string | Buffer, libraryName: string | Buffer, replace: 'REPLACE', libraryDescriptionToken: 'DESCRIPTION', libraryDescription: string | Buffer, functionCode: string | Buffer, callback?: Callback<Buffer>): Result<Buffer, Context>;

/**
* Return information about the function currently running (name, description, duration)
Expand Down
6 changes: 3 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
"url": "https://opencollective.com/ioredis"
},
"dependencies": {
"@ioredis/commands": "^1.0.2",
"@ioredis/commands": "^1.1.0",
"cluster-key-slot": "^1.1.0",
"debug": "^4.3.3",
"denque": "^2.0.1",
Expand Down

0 comments on commit 32eb381

Please sign in to comment.