1// Copyright 2012 Gary Burd 2// 3// Licensed under the Apache License, Version 2.0 (the "License"): you may 4// not use this file except in compliance with the License. You may obtain 5// a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12// License for the specific language governing permissions and limitations 13// under the License. 14 15// Package redis is a client for the Redis database. 16// 17// The Redigo FAQ (https://github.com/garyburd/redigo/wiki/FAQ) contains more 18// documentation about this package. 19// 20// Connections 21// 22// The Conn interface is the primary interface for working with Redis. 23// Applications create connections by calling the Dial, DialWithTimeout or 24// NewConn functions. In the future, functions will be added for creating 25// sharded and other types of connections. 26// 27// The application must call the connection Close method when the application 28// is done with the connection. 29// 30// Executing Commands 31// 32// The Conn interface has a generic method for executing Redis commands: 33// 34// Do(commandName string, args ...interface{}) (reply interface{}, err error) 35// 36// The Redis command reference (http://redis.io/commands) lists the available 37// commands. An example of using the Redis APPEND command is: 38// 39// n, err := conn.Do("APPEND", "key", "value") 40// 41// The Do method converts command arguments to binary strings for transmission 42// to the server as follows: 43// 44// Go Type Conversion 45// []byte Sent as is 46// string Sent as is 47// int, int64 strconv.FormatInt(v) 48// float64 strconv.FormatFloat(v, 'g', -1, 64) 49// bool true -> "1", false -> "0" 50// nil "" 51// all other types fmt.Print(v) 52// 53// Redis command reply types are represented using the following Go types: 54// 55// Redis type Go type 56// error redis.Error 57// integer int64 58// simple string string 59// bulk string []byte or nil if value not present. 60// array []interface{} or nil if value not present. 61// 62// Use type assertions or the reply helper functions to convert from 63// interface{} to the specific Go type for the command result. 64// 65// Pipelining 66// 67// Connections support pipelining using the Send, Flush and Receive methods. 68// 69// Send(commandName string, args ...interface{}) error 70// Flush() error 71// Receive() (reply interface{}, err error) 72// 73// Send writes the command to the connection's output buffer. Flush flushes the 74// connection's output buffer to the server. Receive reads a single reply from 75// the server. The following example shows a simple pipeline. 76// 77// c.Send("SET", "foo", "bar") 78// c.Send("GET", "foo") 79// c.Flush() 80// c.Receive() // reply from SET 81// v, err = c.Receive() // reply from GET 82// 83// The Do method combines the functionality of the Send, Flush and Receive 84// methods. The Do method starts by writing the command and flushing the output 85// buffer. Next, the Do method receives all pending replies including the reply 86// for the command just sent by Do. If any of the received replies is an error, 87// then Do returns the error. If there are no errors, then Do returns the last 88// reply. If the command argument to the Do method is "", then the Do method 89// will flush the output buffer and receive pending replies without sending a 90// command. 91// 92// Use the Send and Do methods to implement pipelined transactions. 93// 94// c.Send("MULTI") 95// c.Send("INCR", "foo") 96// c.Send("INCR", "bar") 97// r, err := c.Do("EXEC") 98// fmt.Println(r) // prints [1, 1] 99// 100// Concurrency 101// 102// Connections do not support concurrent calls to the write methods (Send, 103// Flush) or concurrent calls to the read method (Receive). Connections do 104// allow a concurrent reader and writer. 105// 106// Because the Do method combines the functionality of Send, Flush and Receive, 107// the Do method cannot be called concurrently with the other methods. 108// 109// For full concurrent access to Redis, use the thread-safe Pool to get and 110// release connections from within a goroutine. 111// 112// Publish and Subscribe 113// 114// Use the Send, Flush and Receive methods to implement Pub/Sub subscribers. 115// 116// c.Send("SUBSCRIBE", "example") 117// c.Flush() 118// for { 119// reply, err := c.Receive() 120// if err != nil { 121// return err 122// } 123// // process pushed message 124// } 125// 126// The PubSubConn type wraps a Conn with convenience methods for implementing 127// subscribers. The Subscribe, PSubscribe, Unsubscribe and PUnsubscribe methods 128// send and flush a subscription management command. The receive method 129// converts a pushed message to convenient types for use in a type switch. 130// 131// psc := redis.PubSubConn{c} 132// psc.Subscribe("example") 133// for { 134// switch v := psc.Receive().(type) { 135// case redis.Message: 136// fmt.Printf("%s: message: %s\n", v.Channel, v.Data) 137// case redis.Subscription: 138// fmt.Printf("%s: %s %d\n", v.Channel, v.Kind, v.Count) 139// case error: 140// return v 141// } 142// } 143// 144// Reply Helpers 145// 146// The Bool, Int, Bytes, String, Strings and Values functions convert a reply 147// to a value of a specific type. To allow convenient wrapping of calls to the 148// connection Do and Receive methods, the functions take a second argument of 149// type error. If the error is non-nil, then the helper function returns the 150// error. If the error is nil, the function converts the reply to the specified 151// type: 152// 153// exists, err := redis.Bool(c.Do("EXISTS", "foo")) 154// if err != nil { 155// // handle error return from c.Do or type conversion error. 156// } 157// 158// The Scan function converts elements of a array reply to Go types: 159// 160// var value1 int 161// var value2 string 162// reply, err := redis.Values(c.Do("MGET", "key1", "key2")) 163// if err != nil { 164// // handle error 165// } 166// if _, err := redis.Scan(reply, &value1, &value2); err != nil { 167// // handle error 168// } 169package redis // import "github.com/garyburd/redigo/redis" 170