forked from mirror/redis
Unexport as much as possible.
This commit is contained in:
parent
7f11168689
commit
773f2a03f3
|
@ -0,0 +1,333 @@
|
||||||
|
package redis
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Cmder interface {
|
||||||
|
args() []string
|
||||||
|
parseReply(reader) (interface{}, error)
|
||||||
|
setErr(error)
|
||||||
|
setVal(interface{})
|
||||||
|
|
||||||
|
writeTimeout() *time.Duration
|
||||||
|
readTimeout() *time.Duration
|
||||||
|
|
||||||
|
Err() error
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
type baseCmd struct {
|
||||||
|
_args []string
|
||||||
|
|
||||||
|
val interface{}
|
||||||
|
err error
|
||||||
|
|
||||||
|
_writeTimeout, _readTimeout *time.Duration
|
||||||
|
}
|
||||||
|
|
||||||
|
func newBaseCmd(args ...string) *baseCmd {
|
||||||
|
return &baseCmd{
|
||||||
|
_args: args,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cmd *baseCmd) String() string {
|
||||||
|
args := strings.Join(cmd._args, " ")
|
||||||
|
if cmd.err != nil {
|
||||||
|
return args + ": " + cmd.err.Error()
|
||||||
|
} else if cmd.val != nil {
|
||||||
|
return args + ": " + fmt.Sprint(cmd.val)
|
||||||
|
}
|
||||||
|
return args
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cmd *baseCmd) Err() error {
|
||||||
|
if cmd.err != nil {
|
||||||
|
return cmd.err
|
||||||
|
}
|
||||||
|
if cmd.val == nil {
|
||||||
|
return errValNotSet
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cmd *baseCmd) args() []string {
|
||||||
|
return cmd._args
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cmd *baseCmd) setErr(err error) {
|
||||||
|
if err == nil {
|
||||||
|
panic("non-nil value expected")
|
||||||
|
}
|
||||||
|
cmd.err = err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cmd *baseCmd) setVal(val interface{}) {
|
||||||
|
if val == nil {
|
||||||
|
panic("non-nil value expected")
|
||||||
|
}
|
||||||
|
cmd.val = val
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cmd *baseCmd) parseReply(rd reader) (interface{}, error) {
|
||||||
|
return parseReply(rd)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cmd *baseCmd) readTimeout() *time.Duration {
|
||||||
|
return cmd._readTimeout
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cmd *baseCmd) setReadTimeout(d time.Duration) {
|
||||||
|
cmd._readTimeout = &d
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cmd *baseCmd) writeTimeout() *time.Duration {
|
||||||
|
return cmd._writeTimeout
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cmd *baseCmd) setWriteTimeout(d time.Duration) {
|
||||||
|
cmd._writeTimeout = &d
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
type Cmd struct {
|
||||||
|
*baseCmd
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewCmd(args ...string) *Cmd {
|
||||||
|
return &Cmd{
|
||||||
|
baseCmd: newBaseCmd(args...),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cmd *Cmd) Val() interface{} {
|
||||||
|
return cmd.val
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
type StatusCmd struct {
|
||||||
|
*baseCmd
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewStatusCmd(args ...string) *StatusCmd {
|
||||||
|
return &StatusCmd{
|
||||||
|
baseCmd: newBaseCmd(args...),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cmd *StatusCmd) Val() string {
|
||||||
|
if cmd.val == nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return cmd.val.(string)
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
type IntCmd struct {
|
||||||
|
*baseCmd
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewIntCmd(args ...string) *IntCmd {
|
||||||
|
return &IntCmd{
|
||||||
|
baseCmd: newBaseCmd(args...),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cmd *IntCmd) Val() int64 {
|
||||||
|
if cmd.val == nil {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
return cmd.val.(int64)
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
type BoolCmd struct {
|
||||||
|
*baseCmd
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewBoolCmd(args ...string) *BoolCmd {
|
||||||
|
return &BoolCmd{
|
||||||
|
baseCmd: newBaseCmd(args...),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cmd *BoolCmd) parseReply(rd reader) (interface{}, error) {
|
||||||
|
v, err := parseReply(rd)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return v.(int64) == 1, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cmd *BoolCmd) Val() bool {
|
||||||
|
if cmd.val == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return cmd.val.(bool)
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
type StringCmd struct {
|
||||||
|
*baseCmd
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewStringCmd(args ...string) *StringCmd {
|
||||||
|
return &StringCmd{
|
||||||
|
baseCmd: newBaseCmd(args...),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cmd *StringCmd) Val() string {
|
||||||
|
if cmd.val == nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return cmd.val.(string)
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
type FloatCmd struct {
|
||||||
|
*baseCmd
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewFloatCmd(args ...string) *FloatCmd {
|
||||||
|
return &FloatCmd{
|
||||||
|
baseCmd: newBaseCmd(args...),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cmd *FloatCmd) parseReply(rd reader) (interface{}, error) {
|
||||||
|
v, err := parseReply(rd)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return strconv.ParseFloat(v.(string), 64)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cmd *FloatCmd) Val() float64 {
|
||||||
|
if cmd.val == nil {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
return cmd.val.(float64)
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
type SliceCmd struct {
|
||||||
|
*baseCmd
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewSliceCmd(args ...string) *SliceCmd {
|
||||||
|
return &SliceCmd{
|
||||||
|
baseCmd: newBaseCmd(args...),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cmd *SliceCmd) Val() []interface{} {
|
||||||
|
if cmd.val == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return cmd.val.([]interface{})
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
type StringSliceCmd struct {
|
||||||
|
*baseCmd
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewStringSliceCmd(args ...string) *StringSliceCmd {
|
||||||
|
return &StringSliceCmd{
|
||||||
|
baseCmd: newBaseCmd(args...),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cmd *StringSliceCmd) parseReply(rd reader) (interface{}, error) {
|
||||||
|
return parseStringSliceReply(rd)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cmd *StringSliceCmd) Val() []string {
|
||||||
|
if cmd.val == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return cmd.val.([]string)
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
type BoolSliceCmd struct {
|
||||||
|
*baseCmd
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewBoolSliceCmd(args ...string) *BoolSliceCmd {
|
||||||
|
return &BoolSliceCmd{
|
||||||
|
baseCmd: newBaseCmd(args...),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cmd *BoolSliceCmd) parseReply(rd reader) (interface{}, error) {
|
||||||
|
return parseBoolSliceReply(rd)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cmd *BoolSliceCmd) Val() []bool {
|
||||||
|
if cmd.val == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return cmd.val.([]bool)
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
type StringStringMapCmd struct {
|
||||||
|
*baseCmd
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewStringStringMapCmd(args ...string) *StringStringMapCmd {
|
||||||
|
return &StringStringMapCmd{
|
||||||
|
baseCmd: newBaseCmd(args...),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cmd *StringStringMapCmd) parseReply(rd reader) (interface{}, error) {
|
||||||
|
return parseStringStringMapReply(rd)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cmd *StringStringMapCmd) Val() map[string]string {
|
||||||
|
if cmd.val == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return cmd.val.(map[string]string)
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
type StringFloatMapCmd struct {
|
||||||
|
*baseCmd
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewStringFloatMapCmd(args ...string) *StringFloatMapCmd {
|
||||||
|
return &StringFloatMapCmd{
|
||||||
|
baseCmd: newBaseCmd(args...),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cmd *StringFloatMapCmd) parseReply(rd reader) (interface{}, error) {
|
||||||
|
return parseStringFloatMapReply(rd)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cmd *StringFloatMapCmd) Val() map[string]float64 {
|
||||||
|
if cmd.val == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return cmd.val.(map[string]float64)
|
||||||
|
}
|
572
v2/commands.go
572
v2/commands.go
File diff suppressed because it is too large
Load Diff
|
@ -53,13 +53,13 @@ func ExamplePipeline() {
|
||||||
})
|
})
|
||||||
defer client.Close()
|
defer client.Close()
|
||||||
|
|
||||||
var set *redis.StatusReq
|
var set *redis.StatusCmd
|
||||||
var get *redis.StringReq
|
var get *redis.StringCmd
|
||||||
reqs, err := client.Pipelined(func(c *redis.Pipeline) {
|
cmds, err := client.Pipelined(func(c *redis.Pipeline) {
|
||||||
set = c.Set("key1", "hello1")
|
set = c.Set("key1", "hello1")
|
||||||
get = c.Get("key2")
|
get = c.Get("key2")
|
||||||
})
|
})
|
||||||
fmt.Println(err, reqs)
|
fmt.Println(err, cmds)
|
||||||
fmt.Println(set)
|
fmt.Println(set)
|
||||||
fmt.Println(get)
|
fmt.Println(get)
|
||||||
// Output: (nil) [SET key1 hello1: OK GET key2: (nil)]
|
// Output: (nil) [SET key1 hello1: OK GET key2: (nil)]
|
||||||
|
@ -67,7 +67,7 @@ func ExamplePipeline() {
|
||||||
// GET key2: (nil)
|
// GET key2: (nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func incr(tx *redis.Multi) ([]redis.Req, error) {
|
func incr(tx *redis.Multi) ([]redis.Cmder, error) {
|
||||||
get := tx.Get("key")
|
get := tx.Get("key")
|
||||||
if err := get.Err(); err != nil && err != redis.Nil {
|
if err := get.Err(); err != nil && err != redis.Nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -75,14 +75,14 @@ func incr(tx *redis.Multi) ([]redis.Req, error) {
|
||||||
|
|
||||||
val, _ := strconv.ParseInt(get.Val(), 10, 64)
|
val, _ := strconv.ParseInt(get.Val(), 10, 64)
|
||||||
|
|
||||||
reqs, err := tx.Exec(func() {
|
cmds, err := tx.Exec(func() {
|
||||||
tx.Set("key", strconv.FormatInt(val+1, 10))
|
tx.Set("key", strconv.FormatInt(val+1, 10))
|
||||||
})
|
})
|
||||||
// Transaction failed. Repeat.
|
// Transaction failed. Repeat.
|
||||||
if err == redis.Nil {
|
if err == redis.Nil {
|
||||||
return incr(tx)
|
return incr(tx)
|
||||||
}
|
}
|
||||||
return reqs, err
|
return cmds, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func ExampleTransaction() {
|
func ExampleTransaction() {
|
||||||
|
@ -99,8 +99,8 @@ func ExampleTransaction() {
|
||||||
watch := tx.Watch("key")
|
watch := tx.Watch("key")
|
||||||
_ = watch.Err()
|
_ = watch.Err()
|
||||||
|
|
||||||
reqs, err := incr(tx)
|
cmds, err := incr(tx)
|
||||||
fmt.Println(err, reqs)
|
fmt.Println(err, cmds)
|
||||||
|
|
||||||
// Output: <nil> [SET key 1: OK]
|
// Output: <nil> [SET key 1: OK]
|
||||||
}
|
}
|
||||||
|
@ -130,10 +130,10 @@ func ExamplePubSub() {
|
||||||
// &{mychannel hello} <nil>
|
// &{mychannel hello} <nil>
|
||||||
}
|
}
|
||||||
|
|
||||||
func Get(client *redis.Client, key string) *redis.StringReq {
|
func Get(client *redis.Client, key string) *redis.StringCmd {
|
||||||
req := redis.NewStringReq("GET", key)
|
cmd := redis.NewStringCmd("GET", key)
|
||||||
client.Process(req)
|
client.Process(cmd)
|
||||||
return req
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
func ExampleCustomCommand() {
|
func ExampleCustomCommand() {
|
||||||
|
|
64
v2/multi.go
64
v2/multi.go
|
@ -28,38 +28,38 @@ func (c *Multi) Close() error {
|
||||||
return c.Client.Close()
|
return c.Client.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Multi) Watch(keys ...string) *StatusReq {
|
func (c *Multi) Watch(keys ...string) *StatusCmd {
|
||||||
args := append([]string{"WATCH"}, keys...)
|
args := append([]string{"WATCH"}, keys...)
|
||||||
req := NewStatusReq(args...)
|
cmd := NewStatusCmd(args...)
|
||||||
c.Process(req)
|
c.Process(cmd)
|
||||||
return req
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Multi) Unwatch(keys ...string) *StatusReq {
|
func (c *Multi) Unwatch(keys ...string) *StatusCmd {
|
||||||
args := append([]string{"UNWATCH"}, keys...)
|
args := append([]string{"UNWATCH"}, keys...)
|
||||||
req := NewStatusReq(args...)
|
cmd := NewStatusCmd(args...)
|
||||||
c.Process(req)
|
c.Process(cmd)
|
||||||
return req
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Multi) Discard() error {
|
func (c *Multi) Discard() error {
|
||||||
if c.reqs == nil {
|
if c.cmds == nil {
|
||||||
return errDiscard
|
return errDiscard
|
||||||
}
|
}
|
||||||
c.reqs = c.reqs[:1]
|
c.cmds = c.cmds[:1]
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Multi) Exec(f func()) ([]Req, error) {
|
func (c *Multi) Exec(f func()) ([]Cmder, error) {
|
||||||
c.reqs = []Req{NewStatusReq("MULTI")}
|
c.cmds = []Cmder{NewStatusCmd("MULTI")}
|
||||||
f()
|
f()
|
||||||
c.reqs = append(c.reqs, NewIfaceSliceReq("EXEC"))
|
c.cmds = append(c.cmds, NewSliceCmd("EXEC"))
|
||||||
|
|
||||||
reqs := c.reqs
|
cmds := c.cmds
|
||||||
c.reqs = nil
|
c.cmds = nil
|
||||||
|
|
||||||
if len(reqs) == 2 {
|
if len(cmds) == 2 {
|
||||||
return []Req{}, nil
|
return []Cmder{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
cn, err := c.conn()
|
cn, err := c.conn()
|
||||||
|
@ -68,30 +68,30 @@ func (c *Multi) Exec(f func()) ([]Req, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Synchronize writes and reads to the connection using mutex.
|
// Synchronize writes and reads to the connection using mutex.
|
||||||
err = c.execReqs(reqs, cn)
|
err = c.execCmds(cmds, cn)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.removeConn(cn)
|
c.removeConn(cn)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
c.putConn(cn)
|
c.putConn(cn)
|
||||||
return reqs[1 : len(reqs)-1], nil
|
return cmds[1 : len(cmds)-1], nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Multi) execReqs(reqs []Req, cn *conn) error {
|
func (c *Multi) execCmds(cmds []Cmder, cn *conn) error {
|
||||||
err := c.writeReq(cn, reqs...)
|
err := c.writeCmd(cn, cmds...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
statusReq := NewStatusReq()
|
statusCmd := NewStatusCmd()
|
||||||
|
|
||||||
// Omit last request (EXEC).
|
// Omit last cmduest (EXEC).
|
||||||
reqsLen := len(reqs) - 1
|
cmdsLen := len(cmds) - 1
|
||||||
|
|
||||||
// Parse queued replies.
|
// Parse queued replies.
|
||||||
for i := 0; i < reqsLen; i++ {
|
for i := 0; i < cmdsLen; i++ {
|
||||||
_, err = statusReq.ParseReply(cn.Rd)
|
_, err = statusCmd.parseReply(cn.Rd)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -110,14 +110,14 @@ func (c *Multi) execReqs(reqs []Req, cn *conn) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse replies.
|
// Parse replies.
|
||||||
// Loop starts from 1 to omit first request (MULTI).
|
// Loop starts from 1 to omit first cmduest (MULTI).
|
||||||
for i := 1; i < reqsLen; i++ {
|
for i := 1; i < cmdsLen; i++ {
|
||||||
req := reqs[i]
|
cmd := cmds[i]
|
||||||
val, err := req.ParseReply(cn.Rd)
|
val, err := cmd.parseReply(cn.Rd)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
req.SetErr(err)
|
cmd.setErr(err)
|
||||||
} else {
|
} else {
|
||||||
req.SetVal(val)
|
cmd.setVal(val)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,7 @@ var (
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
func appendReq(buf []byte, args []string) []byte {
|
func appendCmd(buf []byte, args []string) []byte {
|
||||||
buf = append(buf, '*')
|
buf = append(buf, '*')
|
||||||
buf = strconv.AppendUint(buf, uint64(len(args)), 10)
|
buf = strconv.AppendUint(buf, uint64(len(args)), 10)
|
||||||
buf = append(buf, '\r', '\n')
|
buf = append(buf, '\r', '\n')
|
||||||
|
|
|
@ -12,18 +12,18 @@ func (c *Client) Pipeline() *Pipeline {
|
||||||
opt: c.opt,
|
opt: c.opt,
|
||||||
connPool: c.connPool,
|
connPool: c.connPool,
|
||||||
|
|
||||||
reqs: make([]Req, 0),
|
cmds: make([]Cmder, 0),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) Pipelined(f func(*Pipeline)) ([]Req, error) {
|
func (c *Client) Pipelined(f func(*Pipeline)) ([]Cmder, error) {
|
||||||
pc := c.Pipeline()
|
pc := c.Pipeline()
|
||||||
f(pc)
|
f(pc)
|
||||||
reqs, err := pc.Exec()
|
cmds, err := pc.Exec()
|
||||||
pc.Close()
|
pc.Close()
|
||||||
return reqs, err
|
return cmds, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Pipeline) Close() error {
|
func (c *Pipeline) Close() error {
|
||||||
|
@ -31,55 +31,55 @@ func (c *Pipeline) Close() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Pipeline) Discard() error {
|
func (c *Pipeline) Discard() error {
|
||||||
c.reqs = c.reqs[:0]
|
c.cmds = c.cmds[:0]
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Always returns list of commands and error of the first failed
|
// Always returns list of commands and error of the first failed
|
||||||
// command if any.
|
// command if any.
|
||||||
func (c *Pipeline) Exec() ([]Req, error) {
|
func (c *Pipeline) Exec() ([]Cmder, error) {
|
||||||
reqs := c.reqs
|
cmds := c.cmds
|
||||||
c.reqs = make([]Req, 0)
|
c.cmds = make([]Cmder, 0)
|
||||||
|
|
||||||
if len(reqs) == 0 {
|
if len(cmds) == 0 {
|
||||||
return []Req{}, nil
|
return []Cmder{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
cn, err := c.conn()
|
cn, err := c.conn()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return reqs, err
|
return cmds, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := c.execReqs(reqs, cn); err != nil {
|
if err := c.execCmds(cmds, cn); err != nil {
|
||||||
c.freeConn(cn, err)
|
c.freeConn(cn, err)
|
||||||
return reqs, err
|
return cmds, err
|
||||||
}
|
}
|
||||||
|
|
||||||
c.putConn(cn)
|
c.putConn(cn)
|
||||||
return reqs, nil
|
return cmds, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Pipeline) execReqs(reqs []Req, cn *conn) error {
|
func (c *Pipeline) execCmds(cmds []Cmder, cn *conn) error {
|
||||||
err := c.writeReq(cn, reqs...)
|
err := c.writeCmd(cn, cmds...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
for _, req := range reqs {
|
for _, cmd := range cmds {
|
||||||
req.SetErr(err)
|
cmd.setErr(err)
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
var firstReqErr error
|
var firstCmdErr error
|
||||||
for _, req := range reqs {
|
for _, cmd := range cmds {
|
||||||
val, err := req.ParseReply(cn.Rd)
|
val, err := cmd.parseReply(cn.Rd)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
req.SetErr(err)
|
cmd.setErr(err)
|
||||||
if err != nil {
|
if firstCmdErr == nil {
|
||||||
firstReqErr = err
|
firstCmdErr = err
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
req.SetVal(val)
|
cmd.setVal(val)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return firstReqErr
|
return firstCmdErr
|
||||||
}
|
}
|
||||||
|
|
14
v2/pubsub.go
14
v2/pubsub.go
|
@ -18,8 +18,8 @@ func (c *Client) PubSub() *PubSub {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) Publish(channel, message string) *IntReq {
|
func (c *Client) Publish(channel, message string) *IntCmd {
|
||||||
req := NewIntReq("PUBLISH", channel, message)
|
req := NewIntCmd("PUBLISH", channel, message)
|
||||||
c.Process(req)
|
c.Process(req)
|
||||||
return req
|
return req
|
||||||
}
|
}
|
||||||
|
@ -52,7 +52,7 @@ func (c *PubSub) ReceiveTimeout(timeout time.Duration) (interface{}, error) {
|
||||||
}
|
}
|
||||||
cn.readTimeout = timeout
|
cn.readTimeout = timeout
|
||||||
|
|
||||||
replyIface, err := NewIfaceSliceReq().ParseReply(cn.Rd)
|
replyIface, err := NewSliceCmd().parseReply(cn.Rd)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -91,8 +91,8 @@ func (c *PubSub) subscribe(cmd string, channels ...string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
args := append([]string{cmd}, channels...)
|
args := append([]string{cmd}, channels...)
|
||||||
req := NewIfaceSliceReq(args...)
|
req := NewSliceCmd(args...)
|
||||||
return c.writeReq(cn, req)
|
return c.writeCmd(cn, req)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *PubSub) Subscribe(channels ...string) error {
|
func (c *PubSub) Subscribe(channels ...string) error {
|
||||||
|
@ -110,8 +110,8 @@ func (c *PubSub) unsubscribe(cmd string, channels ...string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
args := append([]string{cmd}, channels...)
|
args := append([]string{cmd}, channels...)
|
||||||
req := NewIfaceSliceReq(args...)
|
req := NewSliceCmd(args...)
|
||||||
return c.writeReq(cn, req)
|
return c.writeCmd(cn, req)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *PubSub) Unsubscribe(channels ...string) error {
|
func (c *PubSub) Unsubscribe(channels ...string) error {
|
||||||
|
|
34
v2/redis.go
34
v2/redis.go
|
@ -18,13 +18,13 @@ type baseClient struct {
|
||||||
|
|
||||||
opt *Options
|
opt *Options
|
||||||
|
|
||||||
reqs []Req
|
cmds []Cmder
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *baseClient) writeReq(cn *conn, reqs ...Req) error {
|
func (c *baseClient) writeCmd(cn *conn, cmds ...Cmder) error {
|
||||||
buf := make([]byte, 0, 1000)
|
buf := make([]byte, 0, 1000)
|
||||||
for _, req := range reqs {
|
for _, cmd := range cmds {
|
||||||
buf = appendReq(buf, req.Args())
|
buf = appendCmd(buf, cmd.args())
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err := cn.Write(buf)
|
_, err := cn.Write(buf)
|
||||||
|
@ -93,46 +93,46 @@ func (c *baseClient) putConn(cn *conn) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *baseClient) Process(req Req) {
|
func (c *baseClient) Process(cmd Cmder) {
|
||||||
if c.reqs == nil {
|
if c.cmds == nil {
|
||||||
c.run(req)
|
c.run(cmd)
|
||||||
} else {
|
} else {
|
||||||
c.reqs = append(c.reqs, req)
|
c.cmds = append(c.cmds, cmd)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *baseClient) run(req Req) {
|
func (c *baseClient) run(cmd Cmder) {
|
||||||
cn, err := c.conn()
|
cn, err := c.conn()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
req.SetErr(err)
|
cmd.setErr(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
cn.writeTimeout = c.opt.WriteTimeout
|
cn.writeTimeout = c.opt.WriteTimeout
|
||||||
if timeout := req.writeTimeout(); timeout != nil {
|
if timeout := cmd.writeTimeout(); timeout != nil {
|
||||||
cn.writeTimeout = *timeout
|
cn.writeTimeout = *timeout
|
||||||
}
|
}
|
||||||
|
|
||||||
cn.readTimeout = c.opt.ReadTimeout
|
cn.readTimeout = c.opt.ReadTimeout
|
||||||
if timeout := req.readTimeout(); timeout != nil {
|
if timeout := cmd.readTimeout(); timeout != nil {
|
||||||
cn.readTimeout = *timeout
|
cn.readTimeout = *timeout
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := c.writeReq(cn, req); err != nil {
|
if err := c.writeCmd(cn, cmd); err != nil {
|
||||||
c.removeConn(cn)
|
c.removeConn(cn)
|
||||||
req.SetErr(err)
|
cmd.setErr(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
val, err := req.ParseReply(cn.Rd)
|
val, err := cmd.parseReply(cn.Rd)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.freeConn(cn, err)
|
c.freeConn(cn, err)
|
||||||
req.SetErr(err)
|
cmd.setErr(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
c.putConn(cn)
|
c.putConn(cn)
|
||||||
req.SetVal(val)
|
cmd.setVal(val)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *baseClient) Close() error {
|
func (c *baseClient) Close() error {
|
||||||
|
|
|
@ -155,9 +155,9 @@ func (t *RedisConnectorTest) TestUnixConnector(c *C) {
|
||||||
// c.Assert(err, IsNil)
|
// c.Assert(err, IsNil)
|
||||||
|
|
||||||
// ping := pipeline.Ping()
|
// ping := pipeline.Ping()
|
||||||
// reqs, err := pipeline.RunQueued()
|
// cmds, err := pipeline.RunQueued()
|
||||||
// c.Assert(err, IsNil)
|
// c.Assert(err, IsNil)
|
||||||
// c.Assert(reqs, HasLen, 1)
|
// c.Assert(cmds, HasLen, 1)
|
||||||
// c.Assert(ping.Err(), IsNil)
|
// c.Assert(ping.Err(), IsNil)
|
||||||
// c.Assert(ping.Val(), Equals, "PONG")
|
// c.Assert(ping.Val(), Equals, "PONG")
|
||||||
|
|
||||||
|
@ -181,12 +181,12 @@ func (t *RedisConnectorTest) TestUnixConnector(c *C) {
|
||||||
// multi, err := t.client.MultiClient()
|
// multi, err := t.client.MultiClient()
|
||||||
// c.Assert(err, IsNil)
|
// c.Assert(err, IsNil)
|
||||||
|
|
||||||
// var ping *redis.StatusReq
|
// var ping *redis.StatusCmd
|
||||||
// reqs, err := multi.Exec(func() {
|
// cmds, err := multi.Exec(func() {
|
||||||
// ping = multi.Ping()
|
// ping = multi.Ping()
|
||||||
// })
|
// })
|
||||||
// c.Assert(err, IsNil)
|
// c.Assert(err, IsNil)
|
||||||
// c.Assert(reqs, HasLen, 1)
|
// c.Assert(cmds, HasLen, 1)
|
||||||
// c.Assert(ping.Err(), IsNil)
|
// c.Assert(ping.Err(), IsNil)
|
||||||
// c.Assert(ping.Val(), Equals, "PONG")
|
// c.Assert(ping.Val(), Equals, "PONG")
|
||||||
|
|
||||||
|
@ -257,7 +257,7 @@ func (t *RedisTest) resetRedis(c *C) {
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
func (t *RedisTest) TestReqStringMethod(c *C) {
|
func (t *RedisTest) TestCmdStringMethod(c *C) {
|
||||||
set := t.client.Set("foo", "bar")
|
set := t.client.Set("foo", "bar")
|
||||||
c.Assert(set.String(), Equals, "SET foo bar: OK")
|
c.Assert(set.String(), Equals, "SET foo bar: OK")
|
||||||
|
|
||||||
|
@ -265,7 +265,7 @@ func (t *RedisTest) TestReqStringMethod(c *C) {
|
||||||
c.Assert(get.String(), Equals, "GET foo: bar")
|
c.Assert(get.String(), Equals, "GET foo: bar")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *RedisTest) TestReqStringMethodError(c *C) {
|
func (t *RedisTest) TestCmdStringMethodError(c *C) {
|
||||||
get2 := t.client.Get("key_does_not_exists")
|
get2 := t.client.Get("key_does_not_exists")
|
||||||
c.Assert(get2.String(), Equals, "GET key_does_not_exists: (nil)")
|
c.Assert(get2.String(), Equals, "GET key_does_not_exists: (nil)")
|
||||||
}
|
}
|
||||||
|
@ -2403,9 +2403,9 @@ func (t *RedisTest) TestPipeline(c *C) {
|
||||||
incr := pipeline.Incr("key3")
|
incr := pipeline.Incr("key3")
|
||||||
getNil := pipeline.Get("key4")
|
getNil := pipeline.Get("key4")
|
||||||
|
|
||||||
reqs, err := pipeline.Exec()
|
cmds, err := pipeline.Exec()
|
||||||
c.Assert(err, Equals, redis.Nil)
|
c.Assert(err, Equals, redis.Nil)
|
||||||
c.Assert(reqs, HasLen, 4)
|
c.Assert(cmds, HasLen, 4)
|
||||||
|
|
||||||
c.Assert(set.Err(), IsNil)
|
c.Assert(set.Err(), IsNil)
|
||||||
c.Assert(set.Val(), Equals, "OK")
|
c.Assert(set.Val(), Equals, "OK")
|
||||||
|
@ -2428,18 +2428,18 @@ func (t *RedisTest) TestPipelineDiscardQueued(c *C) {
|
||||||
|
|
||||||
pipeline.Get("key")
|
pipeline.Get("key")
|
||||||
pipeline.Discard()
|
pipeline.Discard()
|
||||||
reqs, err := pipeline.Exec()
|
cmds, err := pipeline.Exec()
|
||||||
c.Assert(err, IsNil)
|
c.Assert(err, IsNil)
|
||||||
c.Assert(reqs, HasLen, 0)
|
c.Assert(cmds, HasLen, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *RedisTest) TestPipelineFunc(c *C) {
|
func (t *RedisTest) TestPipelineFunc(c *C) {
|
||||||
var get *redis.StringReq
|
var get *redis.StringCmd
|
||||||
reqs, err := t.client.Pipelined(func(c *redis.Pipeline) {
|
cmds, err := t.client.Pipelined(func(c *redis.Pipeline) {
|
||||||
get = c.Get("foo")
|
get = c.Get("foo")
|
||||||
})
|
})
|
||||||
c.Assert(err, Equals, redis.Nil)
|
c.Assert(err, Equals, redis.Nil)
|
||||||
c.Assert(reqs, HasLen, 1)
|
c.Assert(cmds, HasLen, 1)
|
||||||
c.Assert(get.Err(), Equals, redis.Nil)
|
c.Assert(get.Err(), Equals, redis.Nil)
|
||||||
c.Assert(get.Val(), Equals, "")
|
c.Assert(get.Val(), Equals, "")
|
||||||
}
|
}
|
||||||
|
@ -2460,9 +2460,9 @@ func (t *RedisTest) TestPipelineRunQueuedOnEmptyQueue(c *C) {
|
||||||
c.Assert(pipeline.Close(), IsNil)
|
c.Assert(pipeline.Close(), IsNil)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
reqs, err := pipeline.Exec()
|
cmds, err := pipeline.Exec()
|
||||||
c.Assert(err, IsNil)
|
c.Assert(err, IsNil)
|
||||||
c.Assert(reqs, HasLen, 0)
|
c.Assert(cmds, HasLen, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *RedisTest) TestPipelineIncrFromGoroutines(c *C) {
|
func (t *RedisTest) TestPipelineIncrFromGoroutines(c *C) {
|
||||||
|
@ -2481,12 +2481,12 @@ func (t *RedisTest) TestPipelineIncrFromGoroutines(c *C) {
|
||||||
}
|
}
|
||||||
wg.Wait()
|
wg.Wait()
|
||||||
|
|
||||||
reqs, err := pipeline.Exec()
|
cmds, err := pipeline.Exec()
|
||||||
c.Assert(err, IsNil)
|
c.Assert(err, IsNil)
|
||||||
c.Assert(reqs, HasLen, 20000)
|
c.Assert(cmds, HasLen, 20000)
|
||||||
for _, req := range reqs {
|
for _, cmd := range cmds {
|
||||||
if req.Err() != nil {
|
if cmd.Err() != nil {
|
||||||
c.Errorf("got %v, expected nil", req.Err())
|
c.Errorf("got %v, expected nil", cmd.Err())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2511,9 +2511,9 @@ func (t *RedisTest) TestPipelineEchoFromGoroutines(c *C) {
|
||||||
echo1 := pipeline.Echo(msg1)
|
echo1 := pipeline.Echo(msg1)
|
||||||
echo2 := pipeline.Echo(msg2)
|
echo2 := pipeline.Echo(msg2)
|
||||||
|
|
||||||
reqs, err := pipeline.Exec()
|
cmds, err := pipeline.Exec()
|
||||||
c.Assert(err, IsNil)
|
c.Assert(err, IsNil)
|
||||||
c.Assert(reqs, HasLen, 2)
|
c.Assert(cmds, HasLen, 2)
|
||||||
|
|
||||||
c.Assert(echo1.Err(), IsNil)
|
c.Assert(echo1.Err(), IsNil)
|
||||||
c.Assert(echo1.Val(), Equals, msg1)
|
c.Assert(echo1.Val(), Equals, msg1)
|
||||||
|
@ -2536,15 +2536,15 @@ func (t *RedisTest) TestMultiExec(c *C) {
|
||||||
}()
|
}()
|
||||||
|
|
||||||
var (
|
var (
|
||||||
set *redis.StatusReq
|
set *redis.StatusCmd
|
||||||
get *redis.StringReq
|
get *redis.StringCmd
|
||||||
)
|
)
|
||||||
reqs, err := multi.Exec(func() {
|
cmds, err := multi.Exec(func() {
|
||||||
set = multi.Set("key", "hello")
|
set = multi.Set("key", "hello")
|
||||||
get = multi.Get("key")
|
get = multi.Get("key")
|
||||||
})
|
})
|
||||||
c.Assert(err, IsNil)
|
c.Assert(err, IsNil)
|
||||||
c.Assert(reqs, HasLen, 2)
|
c.Assert(cmds, HasLen, 2)
|
||||||
|
|
||||||
c.Assert(set.Err(), IsNil)
|
c.Assert(set.Err(), IsNil)
|
||||||
c.Assert(set.Val(), Equals, "OK")
|
c.Assert(set.Val(), Equals, "OK")
|
||||||
|
@ -2559,13 +2559,13 @@ func (t *RedisTest) TestMultiExecDiscard(c *C) {
|
||||||
c.Assert(multi.Close(), IsNil)
|
c.Assert(multi.Close(), IsNil)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
reqs, err := multi.Exec(func() {
|
cmds, err := multi.Exec(func() {
|
||||||
multi.Set("key1", "hello1")
|
multi.Set("key1", "hello1")
|
||||||
multi.Discard()
|
multi.Discard()
|
||||||
multi.Set("key2", "hello2")
|
multi.Set("key2", "hello2")
|
||||||
})
|
})
|
||||||
c.Assert(err, IsNil)
|
c.Assert(err, IsNil)
|
||||||
c.Assert(reqs, HasLen, 1)
|
c.Assert(cmds, HasLen, 1)
|
||||||
|
|
||||||
get := t.client.Get("key1")
|
get := t.client.Get("key1")
|
||||||
c.Assert(get.Err(), Equals, redis.Nil)
|
c.Assert(get.Err(), Equals, redis.Nil)
|
||||||
|
@ -2582,9 +2582,9 @@ func (t *RedisTest) TestMultiExecEmpty(c *C) {
|
||||||
c.Assert(multi.Close(), IsNil)
|
c.Assert(multi.Close(), IsNil)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
reqs, err := multi.Exec(func() {})
|
cmds, err := multi.Exec(func() {})
|
||||||
c.Assert(err, IsNil)
|
c.Assert(err, IsNil)
|
||||||
c.Assert(reqs, HasLen, 0)
|
c.Assert(cmds, HasLen, 0)
|
||||||
|
|
||||||
ping := multi.Ping()
|
ping := multi.Ping()
|
||||||
c.Check(ping.Err(), IsNil)
|
c.Check(ping.Err(), IsNil)
|
||||||
|
@ -2597,9 +2597,9 @@ func (t *RedisTest) TestMultiExecOnEmptyQueue(c *C) {
|
||||||
c.Assert(multi.Close(), IsNil)
|
c.Assert(multi.Close(), IsNil)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
reqs, err := multi.Exec(func() {})
|
cmds, err := multi.Exec(func() {})
|
||||||
c.Assert(err, IsNil)
|
c.Assert(err, IsNil)
|
||||||
c.Assert(reqs, HasLen, 0)
|
c.Assert(cmds, HasLen, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *RedisTest) TestMultiExecIncr(c *C) {
|
func (t *RedisTest) TestMultiExecIncr(c *C) {
|
||||||
|
@ -2608,16 +2608,16 @@ func (t *RedisTest) TestMultiExecIncr(c *C) {
|
||||||
c.Assert(multi.Close(), IsNil)
|
c.Assert(multi.Close(), IsNil)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
reqs, err := multi.Exec(func() {
|
cmds, err := multi.Exec(func() {
|
||||||
for i := int64(0); i < 20000; i++ {
|
for i := int64(0); i < 20000; i++ {
|
||||||
multi.Incr("key")
|
multi.Incr("key")
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
c.Assert(err, IsNil)
|
c.Assert(err, IsNil)
|
||||||
c.Assert(reqs, HasLen, 20000)
|
c.Assert(cmds, HasLen, 20000)
|
||||||
for _, req := range reqs {
|
for _, cmd := range cmds {
|
||||||
if req.Err() != nil {
|
if cmd.Err() != nil {
|
||||||
c.Errorf("got %v, expected nil", req.Err())
|
c.Errorf("got %v, expected nil", cmd.Err())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2626,7 +2626,7 @@ func (t *RedisTest) TestMultiExecIncr(c *C) {
|
||||||
c.Assert(get.Val(), Equals, "20000")
|
c.Assert(get.Val(), Equals, "20000")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *RedisTest) transactionalIncr(c *C) ([]redis.Req, error) {
|
func (t *RedisTest) transactionalIncr(c *C) ([]redis.Cmder, error) {
|
||||||
multi := t.client.Multi()
|
multi := t.client.Multi()
|
||||||
defer func() {
|
defer func() {
|
||||||
c.Assert(multi.Close(), IsNil)
|
c.Assert(multi.Close(), IsNil)
|
||||||
|
@ -2643,13 +2643,13 @@ func (t *RedisTest) transactionalIncr(c *C) ([]redis.Req, error) {
|
||||||
v, err := strconv.ParseInt(get.Val(), 10, 64)
|
v, err := strconv.ParseInt(get.Val(), 10, 64)
|
||||||
c.Assert(err, IsNil)
|
c.Assert(err, IsNil)
|
||||||
|
|
||||||
reqs, err := multi.Exec(func() {
|
cmds, err := multi.Exec(func() {
|
||||||
multi.Set("key", strconv.FormatInt(v+1, 10))
|
multi.Set("key", strconv.FormatInt(v+1, 10))
|
||||||
})
|
})
|
||||||
if err == redis.Nil {
|
if err == redis.Nil {
|
||||||
return t.transactionalIncr(c)
|
return t.transactionalIncr(c)
|
||||||
}
|
}
|
||||||
return reqs, err
|
return cmds, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *RedisTest) TestWatchUnwatch(c *C) {
|
func (t *RedisTest) TestWatchUnwatch(c *C) {
|
||||||
|
@ -2661,10 +2661,10 @@ func (t *RedisTest) TestWatchUnwatch(c *C) {
|
||||||
for i := 0; i < 1000; i++ {
|
for i := 0; i < 1000; i++ {
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
go func() {
|
go func() {
|
||||||
reqs, err := t.transactionalIncr(c)
|
cmds, err := t.transactionalIncr(c)
|
||||||
c.Assert(reqs, HasLen, 1)
|
c.Assert(cmds, HasLen, 1)
|
||||||
c.Assert(err, IsNil)
|
c.Assert(err, IsNil)
|
||||||
c.Assert(reqs[0].Err(), IsNil)
|
c.Assert(cmds[0].Err(), IsNil)
|
||||||
wg.Done()
|
wg.Done()
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
337
v2/req.go
337
v2/req.go
|
@ -1,337 +0,0 @@
|
||||||
package redis
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Req interface {
|
|
||||||
Args() []string
|
|
||||||
ParseReply(reader) (interface{}, error)
|
|
||||||
SetErr(error)
|
|
||||||
Err() error
|
|
||||||
SetVal(interface{})
|
|
||||||
IfaceVal() interface{}
|
|
||||||
|
|
||||||
writeTimeout() *time.Duration
|
|
||||||
readTimeout() *time.Duration
|
|
||||||
}
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
type baseReq struct {
|
|
||||||
args []string
|
|
||||||
|
|
||||||
val interface{}
|
|
||||||
err error
|
|
||||||
|
|
||||||
_writeTimeout, _readTimeout *time.Duration
|
|
||||||
}
|
|
||||||
|
|
||||||
func newBaseReq(args ...string) *baseReq {
|
|
||||||
return &baseReq{
|
|
||||||
args: args,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *baseReq) Args() []string {
|
|
||||||
return r.args
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *baseReq) SetErr(err error) {
|
|
||||||
if err == nil {
|
|
||||||
panic("non-nil value expected")
|
|
||||||
}
|
|
||||||
r.err = err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *baseReq) Err() error {
|
|
||||||
if r.err != nil {
|
|
||||||
return r.err
|
|
||||||
}
|
|
||||||
if r.val == nil {
|
|
||||||
return errValNotSet
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *baseReq) SetVal(val interface{}) {
|
|
||||||
if val == nil {
|
|
||||||
panic("non-nil value expected")
|
|
||||||
}
|
|
||||||
r.val = val
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *baseReq) IfaceVal() interface{} {
|
|
||||||
return r.val
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *baseReq) ParseReply(rd reader) (interface{}, error) {
|
|
||||||
return parseReply(rd)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *baseReq) String() string {
|
|
||||||
args := strings.Join(r.args, " ")
|
|
||||||
if r.err != nil {
|
|
||||||
return args + ": " + r.err.Error()
|
|
||||||
} else if r.val != nil {
|
|
||||||
return args + ": " + fmt.Sprint(r.val)
|
|
||||||
}
|
|
||||||
return args
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *baseReq) readTimeout() *time.Duration {
|
|
||||||
return r._readTimeout
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *baseReq) setReadTimeout(d time.Duration) {
|
|
||||||
r._readTimeout = &d
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *baseReq) writeTimeout() *time.Duration {
|
|
||||||
return r._writeTimeout
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *baseReq) setWriteTimeout(d time.Duration) {
|
|
||||||
r._writeTimeout = &d
|
|
||||||
}
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
type IfaceReq struct {
|
|
||||||
*baseReq
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewIfaceReq(args ...string) *IfaceReq {
|
|
||||||
return &IfaceReq{
|
|
||||||
baseReq: newBaseReq(args...),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *IfaceReq) Val() interface{} {
|
|
||||||
return r.val
|
|
||||||
}
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
type StatusReq struct {
|
|
||||||
*baseReq
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewStatusReq(args ...string) *StatusReq {
|
|
||||||
return &StatusReq{
|
|
||||||
baseReq: newBaseReq(args...),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *StatusReq) Val() string {
|
|
||||||
if r.val == nil {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
return r.val.(string)
|
|
||||||
}
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
type IntReq struct {
|
|
||||||
*baseReq
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewIntReq(args ...string) *IntReq {
|
|
||||||
return &IntReq{
|
|
||||||
baseReq: newBaseReq(args...),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *IntReq) Val() int64 {
|
|
||||||
if r.val == nil {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
return r.val.(int64)
|
|
||||||
}
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
type BoolReq struct {
|
|
||||||
*baseReq
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewBoolReq(args ...string) *BoolReq {
|
|
||||||
return &BoolReq{
|
|
||||||
baseReq: newBaseReq(args...),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *BoolReq) ParseReply(rd reader) (interface{}, error) {
|
|
||||||
v, err := parseReply(rd)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return v.(int64) == 1, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *BoolReq) Val() bool {
|
|
||||||
if r.val == nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return r.val.(bool)
|
|
||||||
}
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
type StringReq struct {
|
|
||||||
*baseReq
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewStringReq(args ...string) *StringReq {
|
|
||||||
return &StringReq{
|
|
||||||
baseReq: newBaseReq(args...),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *StringReq) Val() string {
|
|
||||||
if r.val == nil {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
return r.val.(string)
|
|
||||||
}
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
type FloatReq struct {
|
|
||||||
*baseReq
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewFloatReq(args ...string) *FloatReq {
|
|
||||||
return &FloatReq{
|
|
||||||
baseReq: newBaseReq(args...),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *FloatReq) ParseReply(rd reader) (interface{}, error) {
|
|
||||||
v, err := parseReply(rd)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return strconv.ParseFloat(v.(string), 64)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *FloatReq) Val() float64 {
|
|
||||||
if r.val == nil {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
return r.val.(float64)
|
|
||||||
}
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
type IfaceSliceReq struct {
|
|
||||||
*baseReq
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewIfaceSliceReq(args ...string) *IfaceSliceReq {
|
|
||||||
return &IfaceSliceReq{
|
|
||||||
baseReq: newBaseReq(args...),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *IfaceSliceReq) Val() []interface{} {
|
|
||||||
if r.val == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return r.val.([]interface{})
|
|
||||||
}
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
type StringSliceReq struct {
|
|
||||||
*baseReq
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewStringSliceReq(args ...string) *StringSliceReq {
|
|
||||||
return &StringSliceReq{
|
|
||||||
baseReq: newBaseReq(args...),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *StringSliceReq) ParseReply(rd reader) (interface{}, error) {
|
|
||||||
return parseStringSliceReply(rd)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *StringSliceReq) Val() []string {
|
|
||||||
if r.val == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return r.val.([]string)
|
|
||||||
}
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
type BoolSliceReq struct {
|
|
||||||
*baseReq
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewBoolSliceReq(args ...string) *BoolSliceReq {
|
|
||||||
return &BoolSliceReq{
|
|
||||||
baseReq: newBaseReq(args...),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *BoolSliceReq) ParseReply(rd reader) (interface{}, error) {
|
|
||||||
return parseBoolSliceReply(rd)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *BoolSliceReq) Val() []bool {
|
|
||||||
if r.val == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return r.val.([]bool)
|
|
||||||
}
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
type StringStringMapReq struct {
|
|
||||||
*baseReq
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewStringStringMapReq(args ...string) *StringStringMapReq {
|
|
||||||
return &StringStringMapReq{
|
|
||||||
baseReq: newBaseReq(args...),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *StringStringMapReq) ParseReply(rd reader) (interface{}, error) {
|
|
||||||
return parseStringStringMapReply(rd)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *StringStringMapReq) Val() map[string]string {
|
|
||||||
if r.val == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return r.val.(map[string]string)
|
|
||||||
}
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
type StringFloatMapReq struct {
|
|
||||||
*baseReq
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewStringFloatMapReq(args ...string) *StringFloatMapReq {
|
|
||||||
return &StringFloatMapReq{
|
|
||||||
baseReq: newBaseReq(args...),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *StringFloatMapReq) ParseReply(rd reader) (interface{}, error) {
|
|
||||||
return parseStringFloatMapReply(rd)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *StringFloatMapReq) Val() map[string]float64 {
|
|
||||||
if r.val == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return r.val.(map[string]float64)
|
|
||||||
}
|
|
|
@ -1,93 +0,0 @@
|
||||||
package redis_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/vmihailenco/bufio"
|
|
||||||
. "launchpad.net/gocheck"
|
|
||||||
|
|
||||||
"github.com/vmihailenco/redis"
|
|
||||||
)
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
type LineReader struct {
|
|
||||||
line []byte
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewLineReader(line []byte) *LineReader {
|
|
||||||
return &LineReader{line: line}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *LineReader) Read(buf []byte) (int, error) {
|
|
||||||
return copy(buf, r.line), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
type RequestTest struct{}
|
|
||||||
|
|
||||||
var _ = Suite(&RequestTest{})
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
func (t *RequestTest) SetUpTest(c *C) {}
|
|
||||||
|
|
||||||
func (t *RequestTest) TearDownTest(c *C) {}
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
func (t *RequestTest) benchmarkReq(c *C, reqString string, req redis.Req, checker Checker, expected interface{}) {
|
|
||||||
c.StopTimer()
|
|
||||||
|
|
||||||
lineReader := NewLineReader([]byte(reqString))
|
|
||||||
rd := bufio.NewReaderSize(lineReader, 1024)
|
|
||||||
|
|
||||||
for i := 0; i < 10; i++ {
|
|
||||||
vIface, err := req.ParseReply(rd)
|
|
||||||
c.Check(err, IsNil)
|
|
||||||
c.Check(vIface, checker, expected)
|
|
||||||
req.SetVal(vIface)
|
|
||||||
}
|
|
||||||
|
|
||||||
c.StartTimer()
|
|
||||||
|
|
||||||
for i := 0; i < c.N; i++ {
|
|
||||||
v, _ := req.ParseReply(rd)
|
|
||||||
req.SetVal(v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t *RequestTest) BenchmarkStatusReq(c *C) {
|
|
||||||
t.benchmarkReq(c, "+OK\r\n", redis.NewStatusReq(), Equals, "OK")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t *RequestTest) BenchmarkIntReq(c *C) {
|
|
||||||
t.benchmarkReq(c, ":1\r\n", redis.NewIntReq(), Equals, int64(1))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t *RequestTest) BenchmarkStringReq(c *C) {
|
|
||||||
t.benchmarkReq(c, "$5\r\nhello\r\n", redis.NewStringReq(), Equals, "hello")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t *RequestTest) BenchmarkFloatReq(c *C) {
|
|
||||||
t.benchmarkReq(c, "$5\r\n1.111\r\n", redis.NewFloatReq(), Equals, 1.111)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t *RequestTest) BenchmarkStringSliceReq(c *C) {
|
|
||||||
t.benchmarkReq(
|
|
||||||
c,
|
|
||||||
"*2\r\n$5\r\nhello\r\n$5\r\nhello\r\n",
|
|
||||||
redis.NewStringSliceReq(),
|
|
||||||
DeepEquals,
|
|
||||||
[]string{"hello", "hello"},
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t *RequestTest) BenchmarkIfaceSliceReq(c *C) {
|
|
||||||
t.benchmarkReq(
|
|
||||||
c,
|
|
||||||
"*2\r\n$5\r\nhello\r\n$5\r\nhello\r\n",
|
|
||||||
redis.NewIfaceSliceReq(),
|
|
||||||
DeepEquals,
|
|
||||||
[]interface{}{"hello", "hello"},
|
|
||||||
)
|
|
||||||
}
|
|
10
v2/script.go
10
v2/script.go
|
@ -20,23 +20,23 @@ func NewScript(src string) *Script {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Script) Load(c *Client) *StringReq {
|
func (s *Script) Load(c *Client) *StringCmd {
|
||||||
return c.ScriptLoad(s.src)
|
return c.ScriptLoad(s.src)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Script) Exists(c *Client) *BoolSliceReq {
|
func (s *Script) Exists(c *Client) *BoolSliceCmd {
|
||||||
return c.ScriptExists(s.src)
|
return c.ScriptExists(s.src)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Script) Eval(c *Client, keys []string, args []string) *IfaceReq {
|
func (s *Script) Eval(c *Client, keys []string, args []string) *Cmd {
|
||||||
return c.Eval(s.src, keys, args)
|
return c.Eval(s.src, keys, args)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Script) EvalSha(c *Client, keys []string, args []string) *IfaceReq {
|
func (s *Script) EvalSha(c *Client, keys []string, args []string) *Cmd {
|
||||||
return c.EvalSha(s.hash, keys, args)
|
return c.EvalSha(s.hash, keys, args)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Script) Run(c *Client, keys []string, args []string) *IfaceReq {
|
func (s *Script) Run(c *Client, keys []string, args []string) *Cmd {
|
||||||
r := s.EvalSha(c, keys, args)
|
r := s.EvalSha(c, keys, args)
|
||||||
if err := r.Err(); err != nil && strings.HasPrefix(err.Error(), "NOSCRIPT ") {
|
if err := r.Err(); err != nil && strings.HasPrefix(err.Error(), "NOSCRIPT ") {
|
||||||
return s.Eval(c, keys, args)
|
return s.Eval(c, keys, args)
|
||||||
|
|
Loading…
Reference in New Issue