ソースを参照

Add Bool helper, improve comments and examples.

Gary Burd 13 年 前
コミット
a0a17c9037
4 ファイル変更108 行追加35 行削除
  1. 25 18
      redis/conn_test.go
  2. 34 13
      redis/result.go
  3. 47 2
      redis/result_test.go
  4. 2 2
      redis/script_test.go

+ 25 - 18
redis/conn_test.go

@@ -136,36 +136,43 @@ func TestReceive(t *testing.T) {
 	}
 }
 
-func connect() (redis.Conn, error) {
+type testConn struct {
+	redis.Conn
+}
+
+func (t testConn) Close() error {
+	_, err := t.Conn.Do("SELECT", "9")
+	if err != nil {
+		return nil
+	}
+	_, err = t.Conn.Do("FLUSHDB")
+	if err != nil {
+		return err
+	}
+	return t.Conn.Close()
+}
+
+func dial() (redis.Conn, error) {
 	c, err := redis.Dial("tcp", ":6379")
 	if err != nil {
 		return nil, err
 	}
 
-	reply, err := c.Do("SELECT", "9")
+	_, err = c.Do("SELECT", "9")
 	if err != nil {
 		return nil, err
 	}
 
-	reply, err = c.Do("DBSIZE")
+	n, err := redis.Int(c.Do("DBSIZE"))
 	if err != nil {
 		return nil, err
 	}
 
-	if reply, ok := reply.(int); !ok && reply != 0 {
+	if n != 0 {
 		return nil, errors.New("Database #9 is not empty, test can not continue")
 	}
 
-	return c, nil
-}
-
-func disconnect(c redis.Conn) error {
-	_, err := c.Do("SELECT", "9")
-	if err != nil {
-		return nil
-	}
-	_, err = c.Do("FLUSHDB")
-	return err
+	return testConn{c}, nil
 }
 
 var testCommands = []struct {
@@ -230,11 +237,11 @@ var testCommands = []struct {
 }
 
 func TestDoCommands(t *testing.T) {
-	c, err := connect()
+	c, err := dial()
 	if err != nil {
 		t.Fatalf("Error connection to database, %v", err)
 	}
-	defer disconnect(c)
+	defer c.Close()
 
 	for _, cmd := range testCommands {
 		actual, err := c.Do(cmd.args[0].(string), cmd.args[1:]...)
@@ -249,11 +256,11 @@ func TestDoCommands(t *testing.T) {
 }
 
 func TestPipelineCommands(t *testing.T) {
-	c, err := connect()
+	c, err := dial()
 	if err != nil {
 		t.Fatalf("Error connection to database, %v", err)
 	}
-	defer disconnect(c)
+	defer c.Close()
 
 	for _, cmd := range testCommands {
 		err := c.Send(cmd.args[0].(string), cmd.args[1:]...)

+ 34 - 13
redis/result.go

@@ -23,10 +23,10 @@ var (
 	errUnexpectedResultType = errors.New("redigo: unexpected result type")
 )
 
-// Int is a helper that wraps a call to the Conn Do and Receive methods and
-// returns the result as an integer. If the result is an integer, then Int
-// returns the integer. If the result is a bulk response, then Int parses the
-// result as a signed decimal value.  Otherwise, Int returns an error.
+// Int is a helper that converts a Redis result to an int. Integer results are
+// returned directly. Bulk responses are interpreted as signed decimal strings.
+// If err is not equal to nil or the result type is not integer or bulk, then
+// Int returns an error.
 func Int(v interface{}, err error) (int, error) {
 	if err != nil {
 		return 0, err
@@ -43,11 +43,10 @@ func Int(v interface{}, err error) (int, error) {
 	return 0, errUnexpectedResultType
 }
 
-// String is a helper that wraps a call to the Conn Do and Receive methods and
-// returns the result as a string. If the result is a bulk response, then
-// String returns the bytes converted to a string. If the result is an integer,
-// then String formats the result as a decimal string. Otherwise, String returns
-// an error.
+// String is a helper that converts a Redis result to a string. Redis bulk
+// responses are returned as a string. Redis integer responses are formatted as
+// as a signed decimal string. If err is not equal to nil or the result type is
+// not bulk or integer, then String returns an error.
 func String(v interface{}, err error) (string, error) {
 	if err != nil {
 		return "", err
@@ -63,10 +62,10 @@ func String(v interface{}, err error) (string, error) {
 	return "", errUnexpectedResultType
 }
 
-// Bytes is a helper that wraps a call to the Conn Do or Receive methods and
-// returns the result as a []byte. If the result is a bulk response, then Bytes
-// returns the result as is.  If the result is an integer, then Bytes formats
-// the result as a decimal string. Otherwise, Bytes returns an error.
+// Bytes is a helper that converts a Redis result to slice of bytes. Redis bulk
+// responses are returned as is. Redis integer responses are formatted as as a
+// signed decimal string. If err is not equal to nil or the result type is not
+// bulk or integer, then Bytes returns an error.
 func Bytes(v interface{}, err error) ([]byte, error) {
 	if err != nil {
 		return nil, err
@@ -82,6 +81,28 @@ func Bytes(v interface{}, err error) ([]byte, error) {
 	return nil, errUnexpectedResultType
 }
 
+// Bool is a helper that converts a Redis result to a bool. Bool returns true
+// if the result is the integer 1, false if the result is the integer 0.  If
+// err is not equal to nil or the result is not the integer 0 or 1, then Bool
+// returns an error.
+func Bool(v interface{}, err error) (bool, error) {
+	if err != nil {
+		return false, err
+	}
+	switch v := v.(type) {
+	case int64:
+		switch v {
+		case 0:
+			return false, nil
+		case 1:
+			return true, nil
+		}
+	case Error:
+		return false, v
+	}
+	return false, errUnexpectedResultType
+}
+
 // Subscribe represents a subscribe or unsubscribe notification.
 type Subscription struct {
 

+ 47 - 2
redis/result_test.go

@@ -23,6 +23,51 @@ import (
 	"time"
 )
 
+func ExampleBool() {
+	c, err := dial()
+	if err != nil {
+		return
+	}
+	defer c.Close()
+
+	c.Do("SET", "foo", 1)
+	exists, _ := redis.Bool(c.Do("EXISTS", "foo"))
+	fmt.Printf("%#v\n", exists)
+	// Output:
+	// true
+}
+
+func ExampleInt() {
+	c, err := dial()
+	if err != nil {
+		return
+	}
+	defer c.Close()
+
+	c.Do("SET", "k1", 1)
+	n, _ := redis.Int(c.Do("GET", "k1"))
+	fmt.Printf("%#v\n", n)
+	n, _ = redis.Int(c.Do("INCR", "k1"))
+	fmt.Printf("%#v\n", n)
+	// Output:
+	// 1
+	// 2
+}
+
+func ExampleString() {
+	c, err := dial()
+	if err != nil {
+		return
+	}
+	defer c.Close()
+
+	c.Do("SET", "hello", "world")
+	s, err := redis.String(c.Do("GET", "hello"))
+	fmt.Printf("%#v\n", s)
+	// Output:
+	// "world"
+}
+
 func ExampleNotification(c redis.Conn) {
 	c.Send("SUBSCRIBE", "mychannel")
 	for {
@@ -53,11 +98,11 @@ func expectNotification(t *testing.T, c redis.Conn, message string, expected int
 }
 
 func TestNotification(t *testing.T) {
-	pc, err := connect()
+	pc, err := dial()
 	if err != nil {
 		t.Fatal(err)
 	}
-	defer disconnect(pc)
+	defer pc.Close()
 
 	nc, err := net.Dial("tcp", ":6379")
 	if err != nil {

+ 2 - 2
redis/script_test.go

@@ -23,11 +23,11 @@ import (
 )
 
 func TestScript(t *testing.T) {
-	c, err := connect()
+	c, err := dial()
 	if err != nil {
 		t.Fatal(err)
 	}
-	defer disconnect(c)
+	defer c.Close()
 
 	// To test fallback in Do, we make script unique by adding comment with current time.
 	script := fmt.Sprintf("--%d\nreturn {KEYS[1],KEYS[2],ARGV[1],ARGV[2]}", time.Now().UnixNano())