1
0
mirror of https://github.com/redis/go-redis.git synced 2025-06-12 14:21:52 +03:00

Implement FUNCTION group of commands (#2475)

* Implements function load, load replace and flush

* Implements `FUNCTIONS LIST`

* Fixes ineffectual assignment to err

* Extends other tests from the `FUNCTION` group

* Changes RdsFunction to Function

* Renames FunctionList command, for consistency

* Small fixes after review

* More fixes after review

* Implements the `LIBRARYNAME` and `WITHCODE` args for `FUNCTION LIST`

* Implements `FUNCTION DUMP`. Solves https://github.com/redis/go-redis/issues/2396

* Use a pointer instead of value for `First()`

* Implements `FUNCTION RESTORE`. Closes #2401.

* chore: tidy code

Signed-off-by: monkey92t <golang@88.com>

---------

Signed-off-by: monkey92t <golang@88.com>
Co-authored-by: monkey92t <golang@88.com>
This commit is contained in:
Elena Kolevska
2023-03-09 15:01:37 +00:00
committed by GitHub
parent cbfe6cd076
commit 6501a8b15e
3 changed files with 452 additions and 0 deletions

View File

@ -3840,3 +3840,155 @@ func (cmd *ZSliceWithKeyCmd) readReply(rd *proto.Reader) (err error) {
return nil
}
type Function struct {
Name string
Description string
Flags []string
}
type Library struct {
Name string
Engine string
Functions []Function
Code string
}
type FunctionListCmd struct {
baseCmd
val []Library
}
var _ Cmder = (*FunctionListCmd)(nil)
func NewFunctionListCmd(ctx context.Context, args ...interface{}) *FunctionListCmd {
return &FunctionListCmd{
baseCmd: baseCmd{
ctx: ctx,
args: args,
},
}
}
func (cmd *FunctionListCmd) SetVal(val []Library) {
cmd.val = val
}
func (cmd *FunctionListCmd) String() string {
return cmdString(cmd, cmd.val)
}
func (cmd *FunctionListCmd) Val() []Library {
return cmd.val
}
func (cmd *FunctionListCmd) Result() ([]Library, error) {
return cmd.val, cmd.err
}
func (cmd *FunctionListCmd) First() (*Library, error) {
if cmd.err != nil {
return nil, cmd.err
}
if len(cmd.val) > 0 {
return &cmd.val[0], nil
}
return nil, Nil
}
func (cmd *FunctionListCmd) readReply(rd *proto.Reader) (err error) {
n, err := rd.ReadArrayLen()
if err != nil {
return err
}
libraries := make([]Library, n)
for i := 0; i < n; i++ {
nn, err := rd.ReadMapLen()
if err != nil {
return err
}
library := Library{}
for f := 0; f < nn; f++ {
key, err := rd.ReadString()
if err != nil {
return err
}
switch key {
case "library_name":
library.Name, err = rd.ReadString()
case "engine":
library.Engine, err = rd.ReadString()
case "functions":
library.Functions, err = cmd.readFunctions(rd)
case "library_code":
library.Code, err = rd.ReadString()
default:
return fmt.Errorf("redis: function list unexpected key %s", key)
}
if err != nil {
return err
}
}
libraries[i] = library
}
cmd.val = libraries
return nil
}
func (cmd *FunctionListCmd) readFunctions(rd *proto.Reader) ([]Function, error) {
n, err := rd.ReadArrayLen()
if err != nil {
return nil, err
}
functions := make([]Function, n)
for i := 0; i < n; i++ {
nn, err := rd.ReadMapLen()
if err != nil {
return nil, err
}
function := Function{}
for f := 0; f < nn; f++ {
key, err := rd.ReadString()
if err != nil {
return nil, err
}
switch key {
case "name":
if function.Name, err = rd.ReadString(); err != nil {
return nil, err
}
case "description":
if function.Description, err = rd.ReadString(); err != nil && err != Nil {
return nil, err
}
case "flags":
// resp set
nx, err := rd.ReadArrayLen()
if err != nil {
return nil, err
}
function.Flags = make([]string, nx)
for j := 0; j < nx; j++ {
if function.Flags[j], err = rd.ReadString(); err != nil {
return nil, err
}
}
default:
return nil, fmt.Errorf("redis: function list unexpected key %s", key)
}
}
functions[i] = function
}
return functions, nil
}