Skip to content

Commit 33287c7

Browse files
authored
Merge pull request #838 from go-redis/feature/do
Feature/do
2 parents e0dc0be + fea1be3 commit 33287c7

8 files changed

+173
-73
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
- Added Options.MinIdleConns.
66
- Added Options.MaxConnAge.
77
- PoolStats.FreeConns is renamed to PoolStats.IdleConns.
8+
- Add Client.Do to simplify creating custom commands.
89

910
## v6.13
1011

cluster.go

+9-2
Original file line numberDiff line numberDiff line change
@@ -898,6 +898,13 @@ func (c *ClusterClient) Close() error {
898898
return c.nodes.Close()
899899
}
900900

901+
// Do creates a Cmd from the args and processes the cmd.
902+
func (c *ClusterClient) Do(args ...interface{}) *Cmd {
903+
cmd := NewCmd(args...)
904+
c.Process(cmd)
905+
return cmd
906+
}
907+
901908
func (c *ClusterClient) WrapProcess(
902909
fn func(oldProcess func(Cmder) error) func(Cmder) error,
903910
) {
@@ -1242,7 +1249,7 @@ func (c *ClusterClient) defaultProcessPipeline(cmds []Cmder) error {
12421249
cmdsMap = failedCmds
12431250
}
12441251

1245-
return firstCmdsErr(cmds)
1252+
return cmdsFirstErr(cmds)
12461253
}
12471254

12481255
func (c *ClusterClient) mapCmdsByNode(cmds []Cmder) (map[*clusterNode][]Cmder, error) {
@@ -1424,7 +1431,7 @@ func (c *ClusterClient) defaultProcessTxPipeline(cmds []Cmder) error {
14241431
}
14251432
}
14261433

1427-
return firstCmdsErr(cmds)
1434+
return cmdsFirstErr(cmds)
14281435
}
14291436

14301437
func (c *ClusterClient) mapCmdsBySlot(cmds []Cmder) map[int][]Cmder {

command.go

+72-4
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ type Cmder interface {
2525
readTimeout() *time.Duration
2626

2727
Err() error
28-
fmt.Stringer
2928
}
3029

3130
func setCmdsErr(cmds []Cmder, e error) {
@@ -36,7 +35,7 @@ func setCmdsErr(cmds []Cmder, e error) {
3635
}
3736
}
3837

39-
func firstCmdsErr(cmds []Cmder) error {
38+
func cmdsFirstErr(cmds []Cmder) error {
4039
for _, cmd := range cmds {
4140
if err := cmd.Err(); err != nil {
4241
return err
@@ -167,8 +166,77 @@ func (cmd *Cmd) Result() (interface{}, error) {
167166
return cmd.val, cmd.err
168167
}
169168

170-
func (cmd *Cmd) String() string {
171-
return cmdString(cmd, cmd.val)
169+
func (cmd *Cmd) String() (string, error) {
170+
if cmd.err != nil {
171+
return "", cmd.err
172+
}
173+
switch val := cmd.val.(type) {
174+
case string:
175+
return val, nil
176+
default:
177+
err := fmt.Errorf("redis: unexpected type=%T for String", val)
178+
return "", err
179+
}
180+
}
181+
182+
func (cmd *Cmd) Int64() (int64, error) {
183+
if cmd.err != nil {
184+
return 0, cmd.err
185+
}
186+
switch val := cmd.val.(type) {
187+
case int64:
188+
return val, nil
189+
case string:
190+
return strconv.ParseInt(val, 10, 64)
191+
default:
192+
err := fmt.Errorf("redis: unexpected type=%T for Int64", val)
193+
return 0, err
194+
}
195+
}
196+
197+
func (cmd *Cmd) Uint64() (uint64, error) {
198+
if cmd.err != nil {
199+
return 0, cmd.err
200+
}
201+
switch val := cmd.val.(type) {
202+
case int64:
203+
return uint64(val), nil
204+
case string:
205+
return strconv.ParseUint(val, 10, 64)
206+
default:
207+
err := fmt.Errorf("redis: unexpected type=%T for Uint64", val)
208+
return 0, err
209+
}
210+
}
211+
212+
func (cmd *Cmd) Float64() (float64, error) {
213+
if cmd.err != nil {
214+
return 0, cmd.err
215+
}
216+
switch val := cmd.val.(type) {
217+
case int64:
218+
return float64(val), nil
219+
case string:
220+
return strconv.ParseFloat(val, 64)
221+
default:
222+
err := fmt.Errorf("redis: unexpected type=%T for Float64", val)
223+
return 0, err
224+
}
225+
}
226+
227+
func (cmd *Cmd) Bool() (bool, error) {
228+
if cmd.err != nil {
229+
return false, cmd.err
230+
}
231+
switch val := cmd.val.(type) {
232+
case int64:
233+
return val != 0, nil
234+
case string:
235+
return strconv.ParseBool(val)
236+
default:
237+
err := fmt.Errorf("redis: unexpected type=%T for Bool", val)
238+
return false, err
239+
}
172240
}
173241

174242
func (cmd *Cmd) readReply(cn *pool.Conn) error {

example_instrumentation_test.go

+6-6
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@ import (
77
)
88

99
func Example_instrumentation() {
10-
cl := redis.NewClient(&redis.Options{
10+
redisdb := redis.NewClient(&redis.Options{
1111
Addr: ":6379",
1212
})
13-
cl.WrapProcess(func(old func(cmd redis.Cmder) error) func(cmd redis.Cmder) error {
13+
redisdb.WrapProcess(func(old func(cmd redis.Cmder) error) func(cmd redis.Cmder) error {
1414
return func(cmd redis.Cmder) error {
1515
fmt.Printf("starting processing: <%s>\n", cmd)
1616
err := old(cmd)
@@ -19,17 +19,17 @@ func Example_instrumentation() {
1919
}
2020
})
2121

22-
cl.Ping()
22+
redisdb.Ping()
2323
// Output: starting processing: <ping: >
2424
// finished processing: <ping: PONG>
2525
}
2626

2727
func ExamplePipeline_instrumentation() {
28-
client := redis.NewClient(&redis.Options{
28+
redisdb := redis.NewClient(&redis.Options{
2929
Addr: ":6379",
3030
})
3131

32-
client.WrapProcessPipeline(func(old func([]redis.Cmder) error) func([]redis.Cmder) error {
32+
redisdb.WrapProcessPipeline(func(old func([]redis.Cmder) error) func([]redis.Cmder) error {
3333
return func(cmds []redis.Cmder) error {
3434
fmt.Printf("pipeline starting processing: %v\n", cmds)
3535
err := old(cmds)
@@ -38,7 +38,7 @@ func ExamplePipeline_instrumentation() {
3838
}
3939
})
4040

41-
client.Pipelined(func(pipe redis.Pipeliner) error {
41+
redisdb.Pipelined(func(pipe redis.Pipeliner) error {
4242
pipe.Ping()
4343
pipe.Ping()
4444
return nil

0 commit comments

Comments
 (0)