From 343016bf72212bb22c07d3e56393ef78f252c397 Mon Sep 17 00:00:00 2001 From: Nic Gibson Date: Mon, 30 Oct 2023 16:07:42 +0000 Subject: [PATCH] add InfoMap command (#2665) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add an extended version of Info() to parse the results from a call to redis.Info so that it’s simpler to operate on any given item in the result. Signed-off-by: Nic Gibson --- command.go | 83 ++++++++++++++++++++++++++++++++++++++++++++++++ commands.go | 11 +++++++ commands_test.go | 14 ++++++++ 3 files changed, 108 insertions(+) diff --git a/command.go b/command.go index 00e356bb..c641a3fa 100644 --- a/command.go +++ b/command.go @@ -1,9 +1,11 @@ package redis import ( + "bufio" "context" "fmt" "net" + "regexp" "strconv" "strings" "time" @@ -5298,3 +5300,84 @@ type LibraryInfo struct { LibName *string LibVer *string } + +// ------------------------------------------- + +type InfoCmd struct { + baseCmd + val map[string]map[string]string +} + +var _ Cmder = (*InfoCmd)(nil) + +func NewInfoCmd(ctx context.Context, args ...interface{}) *InfoCmd { + return &InfoCmd{ + baseCmd: baseCmd{ + ctx: ctx, + args: args, + }, + } +} + +func (cmd *InfoCmd) SetVal(val map[string]map[string]string) { + cmd.val = val +} + +func (cmd *InfoCmd) Val() map[string]map[string]string { + return cmd.val +} + +func (cmd *InfoCmd) Result() (map[string]map[string]string, error) { + return cmd.Val(), cmd.Err() +} + +func (cmd *InfoCmd) String() string { + return cmdString(cmd, cmd.val) +} + +func (cmd *InfoCmd) readReply(rd *proto.Reader) error { + val, err := rd.ReadString() + if err != nil { + return err + } + + section := "" + scanner := bufio.NewScanner(strings.NewReader(val)) + moduleRe := regexp.MustCompile(`module:name=(.+?),(.+)$`) + + for scanner.Scan() { + line := scanner.Text() + if strings.HasPrefix(line, "#") { + if cmd.val == nil { + cmd.val = make(map[string]map[string]string) + } + section = strings.TrimPrefix(line, "# ") + cmd.val[section] = make(map[string]string) + } else if line != "" { + if section == "Modules" { + kv := moduleRe.FindStringSubmatch(line) + if len(kv) == 3 { + cmd.val[section][kv[1]] = kv[2] + } + } else { + kv := strings.SplitN(line, ":", 2) + if len(kv) == 2 { + cmd.val[section][kv[0]] = kv[1] + } + } + } + } + + return nil + +} + +func (cmd *InfoCmd) Item(section, key string) string { + if cmd.val == nil { + return "" + } else if cmd.val[section] == nil { + return "" + } else { + return cmd.val[section][key] + } +} diff --git a/commands.go b/commands.go index a9149953..842cc23a 100644 --- a/commands.go +++ b/commands.go @@ -571,6 +571,17 @@ func (c cmdable) Info(ctx context.Context, sections ...string) *StringCmd { return cmd } +func (c cmdable) InfoMap(ctx context.Context, sections ...string) *InfoCmd { + args := make([]interface{}, 1+len(sections)) + args[0] = "info" + for i, section := range sections { + args[i+1] = section + } + cmd := NewInfoCmd(ctx, args...) + _ = c(ctx, cmd) + return cmd +} + func (c cmdable) LastSave(ctx context.Context) *IntCmd { cmd := NewIntCmd(ctx, "lastsave") _ = c(ctx, cmd) diff --git a/commands_test.go b/commands_test.go index 8e00c836..fdc41c5a 100644 --- a/commands_test.go +++ b/commands_test.go @@ -335,6 +335,20 @@ var _ = Describe("Commands", func() { Expect(info.Val()).NotTo(Equal("")) }) + It("should InfoMap", Label("redis.info"), func() { + info := client.InfoMap(ctx) + Expect(info.Err()).NotTo(HaveOccurred()) + Expect(info.Val()).NotTo(BeNil()) + + info = client.InfoMap(ctx, "dummy") + Expect(info.Err()).NotTo(HaveOccurred()) + Expect(info.Val()).To(BeNil()) + + info = client.InfoMap(ctx, "server") + Expect(info.Err()).NotTo(HaveOccurred()) + Expect(info.Val()).To(HaveLen(1)) + }) + It("should Info cpu", func() { info := client.Info(ctx, "cpu") Expect(info.Err()).NotTo(HaveOccurred())