mirror of https://github.com/go-redis/redis.git
Change API and update tests.
This commit is contained in:
parent
c5c8ec6b0c
commit
05223145e0
94
README.md
94
README.md
|
@ -33,14 +33,14 @@ Example 2:
|
|||
}
|
||||
|
||||
initConn := func(client *redis.Client) error {
|
||||
_, err := client.Auth("foo").Reply()
|
||||
if err != nil {
|
||||
return err
|
||||
auth := client.Auth("foo")
|
||||
if auth.Err() != nil {
|
||||
return auth.Err()
|
||||
}
|
||||
|
||||
_, err = client.Ping().Reply()
|
||||
if err != nil {
|
||||
return err
|
||||
ping := client.Ping()
|
||||
if ping.Err() != nil {
|
||||
return ping.Err()
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@ -53,17 +53,19 @@ Both `closeConn` and `initConn` functions can be `nil`.
|
|||
Running commands
|
||||
----------------
|
||||
|
||||
_, err := redisClient.Set("foo", "bar").Reply()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
set := redisClient.Set("foo", "bar")
|
||||
if set.Err() != nil {
|
||||
panic(set.Err())
|
||||
}
|
||||
ok := set.Val()
|
||||
|
||||
value, err := redisClient.Get("foo").Reply()
|
||||
if err != nil {
|
||||
if err != redis.Nil {
|
||||
panic(err)
|
||||
get := redisClient.Get("foo")
|
||||
if get.Err() != nil {
|
||||
if get.Err() != redis.Nil {
|
||||
panic(get.Err())
|
||||
}
|
||||
}
|
||||
val := get.Val()
|
||||
|
||||
Pipelining
|
||||
----------
|
||||
|
@ -80,16 +82,12 @@ Client has ability to run several commands with one read/write:
|
|||
panic(err)
|
||||
}
|
||||
|
||||
ok, err := setReq.Reply()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
if setReq.Err() != nil {
|
||||
panic(setReq.Err())
|
||||
}
|
||||
|
||||
value, err := getReq.Reply()
|
||||
if err != nil {
|
||||
if err != redis.Nil {
|
||||
panic(err)
|
||||
}
|
||||
if getReq.Err() != nil && getReq.Err() != redis.Nil {
|
||||
panic(getReq.Err())
|
||||
}
|
||||
|
||||
Multi/Exec
|
||||
|
@ -99,26 +97,22 @@ Example 1:
|
|||
|
||||
multiClient := redisClient.Multi()
|
||||
|
||||
futureGet1 := multiClient.Get("foo1")
|
||||
futureGet2 := multiClient.Get("foo2")
|
||||
get1 := multiClient.Get("foo1")
|
||||
get2 := multiClient.Get("foo2")
|
||||
_, err := multiClient.Exec()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
value1, err := futureGet1.Reply()
|
||||
if err != nil {
|
||||
if err != redis.Nil {
|
||||
panic(err)
|
||||
}
|
||||
if get1.Err() != nil && get1.Err() != redis.Nil {
|
||||
panic(get1.Err())
|
||||
}
|
||||
val1 := get1.Val()
|
||||
|
||||
value2, err := futureGet2.Reply()
|
||||
if err != nil {
|
||||
if err != redis.Nil {
|
||||
panic(err)
|
||||
}
|
||||
if get2.Err() != nil && get2.Err() != redis.Nil {
|
||||
panic(get2.Err())
|
||||
}
|
||||
val2 := get2.Val()
|
||||
|
||||
Example 2:
|
||||
|
||||
|
@ -132,11 +126,8 @@ Example 2:
|
|||
}
|
||||
|
||||
for req := range reqs {
|
||||
value, err := req.Reply()
|
||||
if err != nil {
|
||||
if err != redis.Nil {
|
||||
panic(err)
|
||||
}
|
||||
if req.Err() != nil && req.Err() != redis.Nil {
|
||||
panic(req.Err())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -145,14 +136,17 @@ Pub/sub
|
|||
|
||||
Publish:
|
||||
|
||||
_, err := redisClient.Publish("mychannel", "hello").Reply()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
pub := redisClient.Publish("mychannel", "hello")
|
||||
if pub.Err() != nil {
|
||||
panic(pub.Err())
|
||||
}
|
||||
|
||||
Subscribe:
|
||||
|
||||
pubsub := redisClient.PubSubClient()
|
||||
pubsub, err := redisClient.PubSubClient()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
ch, err := pubsub.Subscribe("mychannel")
|
||||
if err != nil {
|
||||
|
@ -164,18 +158,18 @@ Subscribe:
|
|||
if msg.Err != nil {
|
||||
panic(err)
|
||||
}
|
||||
fmt.Println(msg.Message)
|
||||
message := msg.Message
|
||||
}
|
||||
}
|
||||
|
||||
Thread safety
|
||||
-------------
|
||||
|
||||
redis.Client methods are thread safe. Following code is correct:
|
||||
Commands are thread safe. Following code is correct:
|
||||
|
||||
for i := 0; i < 1000; i++ {
|
||||
go func() {
|
||||
redisClient.Incr("foo").Reply()
|
||||
redisClient.Incr("foo")
|
||||
}()
|
||||
}
|
||||
|
||||
|
@ -186,15 +180,13 @@ Example:
|
|||
|
||||
func Get(client *redis.Client, key string) *redis.BulkReq {
|
||||
req := redis.NewBulkReq("GET", key)
|
||||
client.Queue(req)
|
||||
client.Process(req)
|
||||
return req
|
||||
}
|
||||
|
||||
value, err := Get(redisClient, "foo").Reply()
|
||||
if err != nil {
|
||||
if err != redis.Nil {
|
||||
panic(err)
|
||||
}
|
||||
get := Get(redisClient, "foo")
|
||||
if get.Err() != nil && get.Err() != redis.Nil {
|
||||
panic(get.Err())
|
||||
}
|
||||
|
||||
Connection pool
|
||||
|
|
|
@ -326,7 +326,7 @@ func (c *Client) SetEx(key string, seconds int64, value string) *StatusReq {
|
|||
return req
|
||||
}
|
||||
|
||||
func (c *Client) SetNx(key, value string) *BoolReq {
|
||||
func (c *Client) SetNX(key, value string) *BoolReq {
|
||||
req := NewBoolReq("SETNX", key, value)
|
||||
c.Process(req)
|
||||
return req
|
||||
|
@ -679,8 +679,8 @@ func (c *Client) ZCount(key, min, max string) *IntReq {
|
|||
return req
|
||||
}
|
||||
|
||||
func (c *Client) ZIncrBy(key string, increment int64, member string) *IntReq {
|
||||
req := NewIntReq("ZINCRBY", key, strconv.FormatInt(increment, 10), member)
|
||||
func (c *Client) ZIncrBy(key string, increment int64, member string) *FloatReq {
|
||||
req := NewFloatReq("ZINCRBY", key, strconv.FormatInt(increment, 10), member)
|
||||
c.Process(req)
|
||||
return req
|
||||
}
|
||||
|
|
22
redis.go
22
redis.go
|
@ -6,7 +6,6 @@ import (
|
|||
"io"
|
||||
"net"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/vmihailenco/bufreader"
|
||||
)
|
||||
|
@ -34,16 +33,16 @@ func AuthSelectFunc(password string, db int64) InitConnFunc {
|
|||
|
||||
return func(client *Client) error {
|
||||
if password != "" {
|
||||
_, err := client.Auth(password).Reply()
|
||||
if err != nil {
|
||||
return err
|
||||
auth := client.Auth(password)
|
||||
if auth.Err() != nil {
|
||||
return auth.Err()
|
||||
}
|
||||
}
|
||||
|
||||
if db >= 0 {
|
||||
_, err := client.Select(db).Reply()
|
||||
if err != nil {
|
||||
return err
|
||||
sel := client.Select(db)
|
||||
if sel.Err() != nil {
|
||||
return sel.Err()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -105,13 +104,6 @@ func (c *Client) WriteReq(buf []byte, conn *Conn) error {
|
|||
}
|
||||
|
||||
func (c *Client) ReadReply(conn *Conn) error {
|
||||
if false {
|
||||
err := conn.RW.(*net.TCPConn).SetReadDeadline(time.Now().Add(time.Second))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
_, err := conn.Rd.ReadFrom(conn.RW)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -120,8 +112,6 @@ func (c *Client) ReadReply(conn *Conn) error {
|
|||
}
|
||||
|
||||
func (c *Client) WriteRead(buf []byte, conn *Conn) error {
|
||||
c.mtx.Lock()
|
||||
defer c.mtx.Unlock()
|
||||
if err := c.WriteReq(buf, conn); err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
1937
redis_test.go
1937
redis_test.go
File diff suppressed because it is too large
Load Diff
80
request.go
80
request.go
|
@ -82,7 +82,7 @@ type Req interface {
|
|||
SetErr(error)
|
||||
Err() error
|
||||
SetVal(interface{})
|
||||
Val() interface{}
|
||||
InterfaceVal() interface{}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
@ -112,7 +112,13 @@ func (r *BaseReq) SetErr(err error) {
|
|||
}
|
||||
|
||||
func (r *BaseReq) Err() error {
|
||||
if r.err != nil {
|
||||
return r.err
|
||||
}
|
||||
if r.val == nil {
|
||||
return errResultMissing
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *BaseReq) SetVal(val interface{}) {
|
||||
|
@ -122,7 +128,7 @@ func (r *BaseReq) SetVal(val interface{}) {
|
|||
r.val = val
|
||||
}
|
||||
|
||||
func (r *BaseReq) Val() interface{} {
|
||||
func (r *BaseReq) InterfaceVal() interface{} {
|
||||
return r.val
|
||||
}
|
||||
|
||||
|
@ -157,13 +163,11 @@ func (r *StatusReq) ParseReply(rd *bufreader.Reader) (interface{}, error) {
|
|||
return string(line[1:]), nil
|
||||
}
|
||||
|
||||
func (r *StatusReq) Reply() (string, error) {
|
||||
if r.val == nil && r.err == nil {
|
||||
return "", errResultMissing
|
||||
} else if r.err != nil {
|
||||
return "", r.err
|
||||
func (r *StatusReq) Val() string {
|
||||
if r.val == nil {
|
||||
return ""
|
||||
}
|
||||
return r.val.(string), nil
|
||||
return r.val.(string)
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
@ -193,13 +197,11 @@ func (r *IntReq) ParseReply(rd *bufreader.Reader) (interface{}, error) {
|
|||
return strconv.ParseInt(string(line[1:]), 10, 64)
|
||||
}
|
||||
|
||||
func (r *IntReq) Reply() (int64, error) {
|
||||
if r.val == nil && r.err == nil {
|
||||
return 0, errResultMissing
|
||||
} else if r.err != nil {
|
||||
return 0, r.err
|
||||
func (r *IntReq) Val() int64 {
|
||||
if r.val == nil {
|
||||
return 0
|
||||
}
|
||||
return r.val.(int64), nil
|
||||
return r.val.(int64)
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
@ -231,13 +233,11 @@ func (r *IntNilReq) ParseReply(rd *bufreader.Reader) (interface{}, error) {
|
|||
return nil, fmt.Errorf("Expected ':', but got %q of %q.", line, rd.Bytes())
|
||||
}
|
||||
|
||||
func (r *IntNilReq) Reply() (int64, error) {
|
||||
if r.val == nil && r.err == nil {
|
||||
return 0, errResultMissing
|
||||
} else if r.err != nil {
|
||||
return 0, r.err
|
||||
func (r *IntNilReq) Val() int64 {
|
||||
if r.val == nil {
|
||||
return 0
|
||||
}
|
||||
return r.val.(int64), nil
|
||||
return r.val.(int64)
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
@ -267,13 +267,11 @@ func (r *BoolReq) ParseReply(rd *bufreader.Reader) (interface{}, error) {
|
|||
return line[1] == '1', nil
|
||||
}
|
||||
|
||||
func (r *BoolReq) Reply() (bool, error) {
|
||||
if r.val == nil && r.err == nil {
|
||||
return false, errResultMissing
|
||||
} else if r.err != nil {
|
||||
return false, r.err
|
||||
func (r *BoolReq) Val() bool {
|
||||
if r.val == nil {
|
||||
return false
|
||||
}
|
||||
return r.val.(bool), nil
|
||||
return r.val.(bool)
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
@ -312,13 +310,11 @@ func (r *BulkReq) ParseReply(rd *bufreader.Reader) (interface{}, error) {
|
|||
return string(line), nil
|
||||
}
|
||||
|
||||
func (r *BulkReq) Reply() (string, error) {
|
||||
if r.val == nil && r.err == nil {
|
||||
return "", errResultMissing
|
||||
} else if r.err != nil {
|
||||
return "", r.err
|
||||
func (r *BulkReq) Val() string {
|
||||
if r.val == nil {
|
||||
return ""
|
||||
}
|
||||
return r.val.(string), nil
|
||||
return r.val.(string)
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
@ -357,13 +353,11 @@ func (r *FloatReq) ParseReply(rd *bufreader.Reader) (interface{}, error) {
|
|||
return strconv.ParseFloat(string(line), 64)
|
||||
}
|
||||
|
||||
func (r *FloatReq) Reply() (float64, error) {
|
||||
if r.val == nil && r.err == nil {
|
||||
return 0, errResultMissing
|
||||
} else if r.err != nil {
|
||||
return 0, r.err
|
||||
func (r *FloatReq) Val() float64 {
|
||||
if r.val == nil {
|
||||
return 0
|
||||
}
|
||||
return r.val.(float64), nil
|
||||
return r.val.(float64)
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
@ -434,11 +428,9 @@ func (r *MultiBulkReq) ParseReply(rd *bufreader.Reader) (interface{}, error) {
|
|||
return val, nil
|
||||
}
|
||||
|
||||
func (r *MultiBulkReq) Reply() ([]interface{}, error) {
|
||||
if r.val == nil && r.err == nil {
|
||||
return nil, errResultMissing
|
||||
} else if r.err != nil {
|
||||
return nil, r.err
|
||||
func (r *MultiBulkReq) Val() []interface{} {
|
||||
if r.val == nil {
|
||||
return nil
|
||||
}
|
||||
return r.val.([]interface{}), nil
|
||||
return r.val.([]interface{})
|
||||
}
|
||||
|
|
|
@ -35,9 +35,8 @@ func (t *RequestTest) BenchmarkStatusReq(c *C) {
|
|||
c.Check(vI, Equals, "OK")
|
||||
|
||||
req.SetVal(vI)
|
||||
v, err := req.Reply()
|
||||
c.Check(err, IsNil)
|
||||
c.Check(v, Equals, "OK")
|
||||
c.Check(req.Err(), IsNil)
|
||||
c.Check(req.Val(), Equals, "OK")
|
||||
}
|
||||
|
||||
c.StartTimer()
|
||||
|
@ -46,6 +45,7 @@ func (t *RequestTest) BenchmarkStatusReq(c *C) {
|
|||
rd.ResetPos()
|
||||
v, _ := req.ParseReply(rd)
|
||||
req.SetVal(v)
|
||||
req.Reply()
|
||||
req.Err()
|
||||
req.Val()
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue