From 0e637a4868511039da5188bd70c60e04ba2b5b87 Mon Sep 17 00:00:00 2001 From: Nic Gibson Date: Tue, 1 Aug 2023 17:07:49 +0100 Subject: [PATCH] add InfoMap command 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 b6df28fbe..8b49a7ddd 100644 --- a/command.go +++ b/command.go @@ -1,9 +1,11 @@ package redis import ( + "bufio" "context" "fmt" "net" + "regexp" "strconv" "strings" "time" @@ -5168,3 +5170,84 @@ func (cmd *ACLLogCmd) readReply(rd *proto.Reader) error { return nil } + +// ------------------------------------------- + +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 34f4d2c22..28e79710b 100644 --- a/commands.go +++ b/commands.go @@ -3268,6 +3268,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 f88cb21e8..823f64ee7 100644 --- a/commands_test.go +++ b/commands_test.go @@ -273,6 +273,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())