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 for CLIENT SETINFO #2659

Merged
merged 13 commits into from
Sep 14, 2023
6 changes: 6 additions & 0 deletions command.go
Original file line number Diff line number Diff line change
Expand Up @@ -5292,3 +5292,9 @@ func (cmd *ACLLogCmd) readReply(rd *proto.Reader) error {

return nil
}

// LibraryInfo holds the library info.
type LibraryInfo struct {
LibName *string
LibVer *string
}
30 changes: 30 additions & 0 deletions commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -517,6 +517,7 @@ type StatefulCmdable interface {
Select(ctx context.Context, index int) *StatusCmd
SwapDB(ctx context.Context, index1, index2 int) *StatusCmd
ClientSetName(ctx context.Context, name string) *BoolCmd
ClientSetInfo(ctx context.Context, info LibraryInfo) *StatusCmd
Hello(ctx context.Context, ver int, username, password, clientName string) *MapStringInterfaceCmd
}

Expand Down Expand Up @@ -574,6 +575,35 @@ func (c statefulCmdable) ClientSetName(ctx context.Context, name string) *BoolCm
return cmd
}

// ClientSetInfo sends a CLIENT SETINFO command with the provided info.
func (c statefulCmdable) ClientSetInfo(ctx context.Context, info LibraryInfo) *StatusCmd {
err := info.Validate()
if err != nil {
panic(err.Error())
}

var cmd *StatusCmd
if info.LibName != nil {
cmd = NewStatusCmd(ctx, "client", "setinfo", "LIB-NAME", *info.LibName)
} else {
cmd = NewStatusCmd(ctx, "client", "setinfo", "LIB-VER", *info.LibVer)
}

_ = c(ctx, cmd)
return cmd
}

// Validate checks if only one field in the struct is non-nil.
func (info LibraryInfo) Validate() error {
if info.LibName != nil && info.LibVer != nil {
return errors.New("both LibName and LibVer cannot be set at the same time")
}
if info.LibName == nil && info.LibVer == nil {
return errors.New("at least one of LibName and LibVer should be set")
}
return nil
}

// Hello Set the resp protocol used.
func (c statefulCmdable) Hello(ctx context.Context,
ver int, username, password, clientName string) *MapStringInterfaceCmd {
Expand Down
51 changes: 51 additions & 0 deletions commands_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,57 @@ var _ = Describe("Commands", func() {
Expect(get.Val()).To(Equal("theclientname"))
})

It("should ClientSetInfo", func() {

pipe := client.Pipeline()

// Test setting the libName
libName := "go-redis"
libInfo := redis.LibraryInfo{LibName: &libName}
setInfo := pipe.ClientSetInfo(ctx, libInfo)
_, err := pipe.Exec(ctx)

Expect(err).NotTo(HaveOccurred())
Expect(setInfo.Err()).NotTo(HaveOccurred())
Expect(setInfo.Val()).To(Equal("OK"))

// Test setting the libVer
libVer := "vX.x"
libInfo = redis.LibraryInfo{LibVer: &libVer}
setInfo = pipe.ClientSetInfo(ctx, libInfo)
_, err = pipe.Exec(ctx)

Expect(err).NotTo(HaveOccurred())
Expect(setInfo.Err()).NotTo(HaveOccurred())
Expect(setInfo.Val()).To(Equal("OK"))

// Test setting both fields, expect a panic
libInfo = redis.LibraryInfo{LibName: &libName, LibVer: &libVer}

Expect(func() {
defer func() {
if r := recover(); r != nil {
err := r.(error)
Expect(err).To(MatchError("both LibName and LibVer cannot be set at the same time"))
}
}()
pipe.ClientSetInfo(ctx, libInfo)
}).To(Panic())

// Test setting neither field, expect a panic
libInfo = redis.LibraryInfo{}

Expect(func() {
defer func() {
if r := recover(); r != nil {
err := r.(error)
Expect(err).To(MatchError("at least one of LibName and LibVer should be set"))
}
}()
pipe.ClientSetInfo(ctx, libInfo)
}).To(Panic())
})

It("should ConfigGet", func() {
val, err := client.ConfigGet(ctx, "*").Result()
Expect(err).NotTo(HaveOccurred())
Expand Down
Loading