Browse Source

feat: 更新redis客户端包

lijian 2 năm trước cách đây
mục cha
commit
62b3107fa1

+ 24 - 48
pkg/online/online.go

@@ -1,15 +1,13 @@
-// package online manage device online state and store it in redis.
 package online
 
 import (
 	"errors"
-	"github.com/garyburd/redigo/redis"
-	"sparrow/pkg/redispool"
-	"sparrow/pkg/serializer"
+	"github.com/gogf/gf/database/gredis"
+	"github.com/gogf/gf/util/gconv"
 )
 
 const (
-	OnlineStatusKeyPrefix = "device:onlinestatus:"
+	KeyPrefix = "device:onlinestatus:"
 )
 
 type Status struct {
@@ -19,55 +17,44 @@ type Status struct {
 }
 
 type Manager struct {
-	redishost string
+	redisClient *gredis.Redis
 }
 
-func NewManager(host string) *Manager {
+func NewManager(host string, port, db int) *Manager {
+	gredis.SetConfig(gredis.Config{
+		Host: host,
+		Port: port,
+		Db:   db,
+	})
 	mgr := &Manager{
-		redishost: host,
+		redisClient: gredis.Instance(),
 	}
 	return mgr
 }
 
 func (mgr *Manager) GetStatus(id string) (*Status, error) {
-	key := OnlineStatusKeyPrefix + id
-	conn, err := redispool.GetClient(mgr.redishost)
-	if err != nil {
-		return nil, err
-	}
-	defer conn.Close()
-
-	status := &Status{}
+	key := KeyPrefix + id
+	var status *Status
 	// get status from redis
-	bufferStr, err := redis.String(conn.Do("GET", key))
+	result, err := mgr.redisClient.DoVar("GET", key)
 	if err != nil {
 		return nil, err
 	}
-	err = serializer.String2Struct(bufferStr, status)
+	err = result.Struct(&status)
 	if err != nil {
 		return nil, err
 	}
-
 	return status, nil
 }
 
 func (mgr *Manager) GetOnline(id string, status Status) error {
-	key := OnlineStatusKeyPrefix + id
-	conn, err := redispool.GetClient(mgr.redishost)
+	key := KeyPrefix + id
+	buffStr := gconv.String(&status)
+	_, err := mgr.redisClient.Do("SET", key, buffStr)
 	if err != nil {
 		return err
 	}
-	defer conn.Close()
-	// serialize and store the device's online status info in redis
-	bufferStr, err := serializer.Struct2String(status)
-	if err != nil {
-		return err
-	}
-	_, err = conn.Do("SET", key, bufferStr)
-	if err != nil {
-		return err
-	}
-	_, err = conn.Do("EXPIRE", key, status.HeartbeatInterval+status.HeartbeatInterval/2)
+	_, err = mgr.redisClient.Do("EXPIRE", key, status.HeartbeatInterval+status.HeartbeatInterval/2)
 	if err != nil {
 		return err
 	}
@@ -77,21 +64,15 @@ func (mgr *Manager) GetOnline(id string, status Status) error {
 
 func (mgr *Manager) SetHeartbeat(id string) error {
 	status, err := mgr.GetStatus(id)
-	if err != nil && err != redis.ErrNil {
+	if err != nil {
 		return err
 	}
-
 	if status == nil {
 		return errors.New("device offline")
 	}
 
-	key := OnlineStatusKeyPrefix + id
-	conn, err := redispool.GetClient(mgr.redishost)
-	if err != nil {
-		return err
-	}
-	defer conn.Close()
-	_, err = conn.Do("EXPIRE", key, status.HeartbeatInterval+status.HeartbeatInterval/2)
+	key := KeyPrefix + id
+	_, err = mgr.redisClient.Do("EXPIRE", key, status.HeartbeatInterval+status.HeartbeatInterval/2)
 	if err != nil {
 		return err
 	}
@@ -100,13 +81,8 @@ func (mgr *Manager) SetHeartbeat(id string) error {
 }
 
 func (mgr *Manager) GetOffline(id string) error {
-	key := OnlineStatusKeyPrefix + id
-	conn, err := redispool.GetClient(mgr.redishost)
-	if err != nil {
-		return err
-	}
-	defer conn.Close()
-	_, err = conn.Do("DEL", key)
+	key := KeyPrefix + id
+	_, err := mgr.redisClient.Do("DEL", key)
 	if err != nil {
 		return err
 	}

+ 9 - 7
pkg/online/online_test.go

@@ -1,17 +1,17 @@
 package online
 
 import (
-	"github.com/garyburd/redigo/redis"
+	"github.com/gogf/gf/database/gredis"
 	"reflect"
 	"testing"
 	"time"
 )
 
-var testid = uint64(100)
+var testid = "test"
 
 func checkOnlineStatus(t *testing.T, mgr *Manager, status Status) {
 	readstatus, err := mgr.GetStatus(testid)
-	if err != nil && err != redis.ErrNil {
+	if err != nil {
 		t.Error(err)
 	}
 
@@ -26,7 +26,7 @@ func checkOnlineStatus(t *testing.T, mgr *Manager, status Status) {
 
 func checkOfflineStatus(t *testing.T, mgr *Manager) {
 	readstatus, err := mgr.GetStatus(testid)
-	if err != nil && err != redis.ErrNil {
+	if err != nil {
 		t.Error(err)
 	}
 
@@ -37,7 +37,11 @@ func checkOfflineStatus(t *testing.T, mgr *Manager) {
 }
 
 func TestManager(t *testing.T) {
-	mgr := NewManager("localhost:6379")
+	mgr := NewManager(gredis.Config{
+		Host: "127.0.0.1",
+		Port: 6379,
+		Db:   1,
+	})
 
 	status := Status{
 		ClientIP:          "3.3.3.3",
@@ -71,7 +75,5 @@ func TestManager(t *testing.T) {
 	if err != nil {
 		t.Error(err)
 	}
-
 	checkOfflineStatus(t, mgr)
-
 }

+ 0 - 36
pkg/redispool/redispool.go

@@ -1,36 +0,0 @@
-package redispool
-
-import (
-	"github.com/garyburd/redigo/redis"
-	"time"
-)
-
-var mapRedisPool map[string]*redis.Pool
-
-// GetClient get a redis connection by host
-func GetClient(host string) (redis.Conn, error) {
-
-	pool, exist := mapRedisPool[host]
-	if !exist {
-		pool = &redis.Pool{
-			MaxIdle: 10,
-			Dial: func() (redis.Conn, error) {
-				c, err := redis.Dial("tcp", host)
-				if err != nil {
-					return nil, err
-				}
-				return c, err
-			},
-			TestOnBorrow: func(c redis.Conn, t time.Time) error {
-				_, err := c.Do("PING")
-				return err
-			},
-		}
-		mapRedisPool[host] = pool
-	}
-	return pool.Get(), nil
-}
-
-func init() {
-	mapRedisPool = make(map[string]*redis.Pool)
-}

+ 0 - 18
pkg/redispool/redispool_test.go

@@ -1,18 +0,0 @@
-package redispool
-
-import (
-	"github.com/garyburd/redigo/redis"
-	"testing"
-)
-
-func TestRedisCli(t *testing.T) {
-	cli, err := GetClient("localhost:6379")
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	_, err = redis.String(cli.Do("GET", "testkey"))
-	if err != nil && err != redis.ErrNil {
-		t.Error(err)
-	}
-}

+ 19 - 43
pkg/token/token.go

@@ -2,9 +2,9 @@ package token
 
 import (
 	"errors"
+	"github.com/gogf/gf/database/gredis"
 	"reflect"
 	"sparrow/pkg/generator"
-	"sparrow/pkg/redispool"
 )
 
 const (
@@ -15,12 +15,17 @@ const (
 )
 
 type Helper struct {
-	redishost string
+	redisClient *gredis.Redis
 }
 
-func NewHelper(host string) *Helper {
+func NewHelper(host string, port, db int) *Helper {
+	gredis.SetConfig(gredis.Config{
+		Host: host,
+		Port: port,
+		Db:   db,
+	})
 	helper := &Helper{
-		redishost: host,
+		redisClient: gredis.Instance(),
 	}
 	return helper
 }
@@ -31,18 +36,13 @@ func (helper *Helper) GenerateToken(recordId string) ([]byte, error) {
 		return nil, err
 	}
 
-	conn, err := redispool.GetClient(helper.redishost)
-	if err != nil {
-		return nil, err
-	}
-	defer conn.Close()
 	key := DeviceTokenKeyPrefix + recordId
 
-	_, err = conn.Do("SET", key, token)
+	_, err = helper.redisClient.Do("SET", key, token)
 	if err != nil {
 		return nil, err
 	}
-	_, err = conn.Do("EXPIRE", key, DeviceTokenExpires)
+	_, err = helper.redisClient.Do("EXPIRE", key, DeviceTokenExpires)
 	if err != nil {
 		return nil, err
 	}
@@ -53,22 +53,16 @@ func (helper *Helper) GenerateToken(recordId string) ([]byte, error) {
 
 func (helper *Helper) ValidateToken(id string, token []byte) error {
 	key := DeviceTokenKeyPrefix + id
-
-	conn, err := redispool.GetClient(helper.redishost)
-	if err != nil {
-		return err
-	}
-	defer conn.Close()
-	readToken, err := conn.Do("GET", key)
+	readToken, err := helper.redisClient.Do("GET", key)
 	if err != nil {
 		return err
 	}
 
 	if !reflect.DeepEqual(readToken, token) {
-		return errors.New("token not match.")
+		return errors.New("token not match")
 	}
 
-	_, err = conn.Do("EXPIRE", key, DeviceTokenExpires)
+	_, err = helper.redisClient.Do("EXPIRE", key, DeviceTokenExpires)
 	if err != nil {
 		return err
 	}
@@ -78,13 +72,7 @@ func (helper *Helper) ValidateToken(id string, token []byte) error {
 
 func (helper *Helper) ClearToken(id string) error {
 	key := DeviceTokenKeyPrefix + id
-
-	conn, err := redispool.GetClient(helper.redishost)
-	if err != nil {
-		return err
-	}
-	defer conn.Close()
-	_, err = conn.Do("DEL", key)
+	_, err := helper.redisClient.Do("DEL", key)
 	if err != nil {
 		return err
 	}
@@ -98,18 +86,11 @@ func (helper *Helper) GenerateAppToken(id string, key string) ([]byte, error) {
 		return nil, err
 	}
 
-	conn, err := redispool.GetClient(helper.redishost)
+	_, err = helper.redisClient.Do("SET", key, token)
 	if err != nil {
 		return nil, err
 	}
-	defer conn.Close()
-	//key := ApplicationTokenKeyPrefix + strconv.FormatUint(id, 10)
-
-	_, err = conn.Do("SET", key, token)
-	if err != nil {
-		return nil, err
-	}
-	_, err = conn.Do("EXPIRE", key, DeviceTokenExpires)
+	_, err = helper.redisClient.Do("EXPIRE", key, DeviceTokenExpires)
 	if err != nil {
 		return nil, err
 	}
@@ -119,12 +100,7 @@ func (helper *Helper) GenerateAppToken(id string, key string) ([]byte, error) {
 }
 
 func (helper *Helper) ValidateAppToken(key string, token []byte) error {
-	conn, err := redispool.GetClient(helper.redishost)
-	if err != nil {
-		return err
-	}
-	defer conn.Close()
-	readToken, err := conn.Do("GET", key)
+	readToken, err := helper.redisClient.Do("GET", key)
 	if err != nil {
 		return err
 	}
@@ -133,7 +109,7 @@ func (helper *Helper) ValidateAppToken(key string, token []byte) error {
 		return errors.New("token not match.")
 	}
 
-	_, err = conn.Do("EXPIRE", key, DeviceTokenExpires)
+	_, err = helper.redisClient.Do("EXPIRE", key, DeviceTokenExpires)
 	if err != nil {
 		return err
 	}

+ 6 - 3
services/devicemanager/flags.go

@@ -5,11 +5,14 @@ import (
 )
 
 const (
-	flagRedisHost = "redishost"
-
+	flagRedisHost    = "redis_host"
+	flagRedisPort    = "redis_port"
+	flagRedisDb      = "redis_db"
 	defaultRedisHost = "127.0.0.1:6379"
 )
 
 var (
-	confRedisHost = flag.String(flagRedisHost, defaultRedisHost, "redis host address, ip:port")
+	confRedisHost = flag.String(flagRedisHost, defaultRedisHost, "redis host address")
+	confRedisPort = flag.Int(flagRedisPort, 6379, "redis host port")
+	confRedisDb   = flag.Int(flagRedisDb, 1, "redis host db")
 )

+ 1 - 1
services/devicemanager/main.go

@@ -14,7 +14,7 @@ func main() {
 	}
 
 	// register a rpc service
-	dm := NewDeviceManager(*confRedisHost)
+	dm := NewDeviceManager(*confRedisHost, *confRedisPort, *confRedisDb)
 	err = server.RegisterRPCHandler(dm)
 	if err != nil {
 		server.Log.Errorf("Register RPC service Error: %s", err)

+ 4 - 7
services/devicemanager/manager.go

@@ -1,7 +1,6 @@
 package main
 
 import (
-	"github.com/garyburd/redigo/redis"
 	"sparrow/pkg/online"
 	"sparrow/pkg/rpcs"
 	"sparrow/pkg/token"
@@ -12,11 +11,9 @@ type DeviceManager struct {
 	tokenHelper   *token.Helper
 }
 
-func NewDeviceManager(redishost string) *DeviceManager {
-	mgr := online.NewManager(redishost)
-
-	helper := token.NewHelper(redishost)
-
+func NewDeviceManager(redishost string, port, db int) *DeviceManager {
+	mgr := online.NewManager(redishost, port, db)
+	helper := token.NewHelper(redishost, port, db)
 	return &DeviceManager{
 		onlineManager: mgr,
 		tokenHelper:   helper,
@@ -56,7 +53,7 @@ func (dm *DeviceManager) GetOffline(args rpcs.ArgsGetOffline, reply *rpcs.ReplyG
 
 func (dm *DeviceManager) GetDeviceOnlineStatus(args rpcs.ArgsGetDeviceOnlineStatus, reply *rpcs.ReplyGetDeviceOnlineStatus) error {
 	status, err := dm.onlineManager.GetStatus(args.Id)
-	if err != nil && err != redis.ErrNil {
+	if err != nil {
 		return err
 	}
 

+ 0 - 71
services/fileaccess/file.go

@@ -1,71 +0,0 @@
-package main
-
-import (
-	"fmt"
-	"io"
-	"os"
-	"path"
-	"regexp"
-	"sparrow/pkg/server"
-	"sparrow/pkg/utils"
-	"strconv"
-
-	"github.com/kataras/iris"
-)
-
-func registerRouter(app *iris.Application, fc *FileAccess) {
-	app.Post("/upload_file", iris.LimitRequestBodySize(int64(*conMaxSize)),
-		func(ctx iris.Context) {
-			file, info, err := ctx.FormFile("file")
-			if err != nil {
-				server.Log.Error(err)
-				ctx.JSON(map[string]interface{}{
-					"code":    -1,
-					"message": "无法找到文件或文件大小超过限制(" + strconv.Itoa(*conMaxSize) + "字节)",
-				})
-				return
-			}
-			defer file.Close()
-			fname := info.Filename
-			fileSuffix := path.Ext(fname)
-			re := regexp.MustCompile(*conAllowExt)
-			if !re.MatchString(fileSuffix) {
-				server.Log.Errorf("%s", "非法的文件格式"+fileSuffix)
-				ctx.JSON(map[string]interface{}{
-					"code":    -2,
-					"message": "非法的文件格式",
-				})
-				return
-			}
-			newname := fmt.Sprintf("%s%s", utils.UUID(), fileSuffix)
-			newfile := fmt.Sprintf("%s/%s/%s", *conStaticPath, "tmp", newname)
-			utils.CreateIfNotExist(newfile)
-			out, err := os.OpenFile(newfile,
-				os.O_WRONLY|os.O_CREATE, 0666)
-
-			if err != nil {
-				ctx.JSON(map[string]interface{}{
-					"code":    -3,
-					"message": "文件上传失败:" + err.Error(),
-				})
-				return
-			}
-			defer out.Close()
-			io.Copy(out, file)
-			var fileURL string
-			if *conDomain == "" {
-				//fileURL = "http://" + server.GetHTTPHost() + "/upload/tmp/" + newname
-				fileURL = fmt.Sprintf("http://%s/%s/%s/%s", server.GetHTTPHost(), *conStaticPath, "tmp", newname)
-			} else {
-				fileURL = fmt.Sprintf("%s/%s/%s/%s", *conDomain, *conStaticPath, "tmp", newname)
-			}
-			// save
-			fc.addTempFile(newfile)
-			ctx.JSON(map[string]interface{}{
-				"code":    0,
-				"message": "success",
-				"file":    fileURL,
-			})
-			return
-		})
-}

+ 0 - 204
services/fileaccess/fileaccess.go

@@ -1,204 +0,0 @@
-package main
-
-import (
-	"encoding/json"
-	"fmt"
-	"io"
-	"os"
-	"path/filepath"
-	"regexp"
-	"sparrow/pkg/redispool"
-	"sparrow/pkg/rpcs"
-	"sparrow/pkg/server"
-	"sparrow/pkg/utils"
-	"sync"
-	"time"
-
-	"github.com/garyburd/redigo/redis"
-)
-
-const checkTimeOut = 30 * time.Minute
-const tempFilesKey = "tempfilelist"
-
-// FileAccess RPC服务
-type FileAccess struct {
-	mu sync.RWMutex
-	// store tmp file list
-	tempFiles map[string]*tempFile
-	redisHost string
-}
-
-// 临时文件
-type tempFile struct {
-	//文件路径
-	FileName string
-	//创建时间
-	CreateTime time.Time
-}
-
-// NewFileAccess create a FileAccessor instance
-func NewFileAccess(redis string) *FileAccess {
-	return &FileAccess{
-		tempFiles: make(map[string]*tempFile),
-		redisHost: redis,
-	}
-}
-
-// 增加一个tempfile
-func (f *FileAccess) addTempFile(fileName string) {
-	obj := &tempFile{
-		FileName:   fileName,
-		CreateTime: time.Now(),
-	}
-	f.mu.Lock()
-	f.tempFiles[fileName] = obj
-	f.mu.Unlock()
-	// store redis
-	err := f.saveToRedis(obj)
-	if err != nil {
-		server.Log.Error(err)
-	}
-}
-
-func (f *FileAccess) delTempFile(fileName string) {
-	f.mu.Lock()
-	if obj, ok := f.tempFiles[fileName]; ok {
-		conn, err := redispool.GetClient(f.redisHost)
-		if err != nil {
-			server.Log.Errorf("conn redis error :%v", err)
-			f.mu.Unlock()
-			return
-		}
-		bytes, err := json.Marshal(obj)
-		if err != nil {
-			server.Log.Errorf("json marshal error :%v", err)
-		}
-		conn.Do("SREM", tempFilesKey, string(bytes))
-	}
-	f.mu.Unlock()
-}
-
-//
-func (f *FileAccess) saveToRedis(obj *tempFile) error {
-	conn, err := redispool.GetClient(f.redisHost)
-	if err != nil {
-		server.Log.Errorf("saveToRedis error :%v", err)
-		return err
-	}
-	bytes, err := json.Marshal(obj)
-	if err != nil {
-		server.Log.Errorf("json marshal error :%v", err)
-		return err
-	}
-	_, err = conn.Do("SADD", tempFilesKey, string(bytes))
-	if err != nil {
-		server.Log.Errorf("store to redis error :%v", err)
-		return err
-	}
-	return nil
-}
-
-func (f *FileAccess) getTempFileFromRedis() error {
-	conn, err := redispool.GetClient(f.redisHost)
-	if err != nil {
-		server.Log.Errorf("conn to redis error :%v", err)
-	} else {
-		// fill tempFile
-		lists, err := redis.Strings(conn.Do("SMEMBERS", tempFilesKey))
-		if err != nil {
-			server.Log.Error(err)
-			return err
-		}
-		for _, str := range lists {
-			var obj tempFile
-			json.Unmarshal([]byte(str), &obj)
-			server.Log.Debugf("%v", obj)
-			f.mu.Lock()
-			f.tempFiles[obj.FileName] = &obj
-			f.mu.Unlock()
-		}
-	}
-	conn.Close()
-	return nil
-
-}
-
-// TODO:  临时解决文案,下个版本把文件信息写到redis中,利用redis的pub/sub机制,自动清理文件
-func (f *FileAccess) checker() {
-	server.Log.Info("start temp file checker")
-	f.getTempFileFromRedis()
-	for {
-		for k, v := range f.tempFiles {
-			if time.Now().Sub(v.CreateTime) > checkTimeOut {
-				//delete file
-				f.delTempFile(v.FileName)
-				f.mu.Lock()
-				delete(f.tempFiles, k)
-				f.mu.Unlock()
-				err := os.Remove(v.FileName)
-				if err != nil {
-					server.Log.Errorf("error while delete file:%v", err)
-				}
-			}
-		}
-		time.Sleep(15 * time.Minute)
-	}
-}
-
-// DeleteFile 删除文件
-func (f *FileAccess) DeleteFile(args *rpcs.ArgsDeleteFile, reply *rpcs.ReplyEmptyResult) error {
-	reg := regexp.MustCompile(`upload/\$*.*`)
-	src := reg.FindString(args.FileName)
-	err := os.Remove(src)
-	return err
-}
-
-// MoveFile move a file to new path
-// source:http://192.168.175.60:9000/upload/tmp/2c9d7d85-2266-450a-9d47-28e67703d818.jpeg
-func (f *FileAccess) MoveFile(args *rpcs.ArgsMoveFile, reply *rpcs.ReplyMoveFile) error {
-	// check source file
-	reg := regexp.MustCompile(`tmp/\$*.*`)
-	src := reg.FindString(args.Source)
-	fileName := filepath.Base(src)
-	src = *conStaticPath + "/" + src
-	b, err := utils.Exists(src)
-	if err != nil {
-		server.Log.Error(err)
-		return err
-	}
-	if b {
-		// copy file
-		sourceFileStat, err := os.Stat(src)
-		if err != nil {
-			return err
-		}
-
-		if !sourceFileStat.Mode().IsRegular() {
-			return fmt.Errorf("%s is not a regular file", src)
-		}
-
-		source, err := os.Open(src)
-		if err != nil {
-			return err
-		}
-		defer source.Close()
-
-		dst := *conStaticPath + "/" + args.Target + "/" + fileName
-		utils.CreateIfNotExist(dst)
-		destination, err := os.Create(dst)
-		if err != nil {
-			return err
-		}
-		defer destination.Close()
-		io.Copy(destination, source)
-		fpath := fmt.Sprintf("http://%s/%s/%s/%s", server.GetHTTPHost(), *conStaticPath, args.Target, fileName)
-		if *conDomain != "" {
-			fpath = fmt.Sprintf("%s/%s/%s/%s", *conDomain, *conStaticPath, args.Target, fileName)
-		}
-		reply.FilePath = fpath
-		//delete src
-		os.Remove(src)
-		return nil
-	}
-	return nil
-}

+ 0 - 24
services/fileaccess/flags.go

@@ -1,24 +0,0 @@
-package main
-
-import "flag"
-
-const (
-	flagStaticPath = "static"   //静态文件参数
-	flagMaxSize    = "maxsize"  //最大允许上传的文件大小
-	flagAllowExt   = "allowext" //允许上传的文件格式
-	flagDomain     = "domain"   // 文件服务域名
-	flagRedis      = "redis"    //redis服务
-
-	defaultStaticPath = "upload"
-	defaultMaxSize    = 300 << 10         //默认300K
-	defaultAllowExt   = ".jpeg|.jpg|.png" //注意.号
-	defaultRedisHost  = "127.0.0.1:6379"
-)
-
-var (
-	conStaticPath = flag.String(flagStaticPath, defaultStaticPath, "static file path")
-	conMaxSize    = flag.Int(flagMaxSize, defaultMaxSize, "允许上传的最大文件尺寸")
-	conAllowExt   = flag.String(flagAllowExt, defaultAllowExt, "允许上传的文件格式")
-	conDomain     = flag.String(flagDomain, "", "文件服务器域名 http://dfsdf.com")
-	conRedisHost  = flag.String(flagRedis, defaultRedisHost, "redis 服务器地址 ip:host")
-)

+ 0 - 51
services/fileaccess/main.go

@@ -1,51 +0,0 @@
-package main
-
-import (
-	"sparrow/pkg/server"
-
-	"github.com/iris-contrib/middleware/cors"
-	"github.com/kataras/iris"
-)
-
-func main() {
-	err := server.Init("fileaccess")
-	if err != nil {
-		server.Log.Fatal(err)
-		return
-	}
-
-	fileaccess := NewFileAccess(*conRedisHost)
-	err = server.RegisterRPCHandler(fileaccess)
-	if err != nil {
-		server.Log.Errorf("RegisterRPCHandler Error: %s", err)
-		return
-	}
-
-	app := iris.New()
-	app.Use(iris.Gzip)
-	iris.WithPostMaxMemory(int64(*conMaxSize))
-	opts := cors.Options{
-		AllowedOrigins: []string{"*"},
-		AllowedHeaders: []string{"Content-Type"},
-		AllowedMethods: []string{"POST"},
-		ExposedHeaders: []string{"X-Header"},
-	}
-	app.Use(cors.New(opts))
-	app.AllowMethods(iris.MethodOptions)
-	app.StaticWeb("/upload", *conStaticPath)
-	registerRouter(app, fileaccess)
-	app.Build()
-	// register a http handler
-	err = server.RegisterHTTPHandler(app)
-	if err != nil {
-		server.Log.Errorf("RegisterHTTPHandler Error: %s", err)
-		return
-	}
-
-	//
-	go fileaccess.checker()
-	err = server.Run()
-	if err != nil {
-		server.Log.Fatal(err)
-	}
-}

+ 0 - 39
services/fileaccess/readme.markdown

@@ -1,39 +0,0 @@
-## 实现一个简单文件服务器
-* 支持GZip
-* 上传的文件全部放到upload/tmp临时目录中
-* 执行保存操作后,把文件拷贝到正式的文件目录,并生成文件路径
-* 定时清理tmp目录中的文件(如24小时清理一次)
-
-### 接口说明:
-
-#### 1.上传文件
-
-* url: `/upload_file`
-* Method: `POST`
-* Response:
-
-```json
-{
-    "file":"http://file.xxx.com/upload/tmp/xxx.jpeg"
-}
-```
-
-#### 2.移动文件(把文件转移到正式目录)
-RPC调用
-* 方法名:MoveFile
-* 参数结构体:
-
-```
-type MoveFileArgs struct {
-    Source string
-    Target string
-}
-```
-
-* 返回结构体
-
-```
-type MoveFileReply struct {
-    FileName string
-}
-```

+ 1 - 1
services/httpaccess/actions.go

@@ -104,7 +104,7 @@ func AuthDevice(args DeviceAuthArgs, r render.Render) {
 		return
 	}
 
-	hepler := token.NewHelper(*confRedisHost)
+	hepler := token.NewHelper(*confRedisHost, *confRedisPort, *confRedisDb)
 	token, err := hepler.GenerateToken(device.RecordId)
 	if err != nil {
 		r.JSON(http.StatusOK, renderError(ErrSystemFault, err))

+ 7 - 4
services/httpaccess/flags.go

@@ -5,11 +5,14 @@ import (
 )
 
 const (
-	flagRedisHost = "redishost"
-
-	defaultRedisHost = "localhost:6379"
+	flagRedisHost    = "redis_host"
+	flagRedisPort    = "redis_port"
+	flagRedisDb      = "redis_db"
+	defaultRedisHost = "127.0.0.1:6379"
 )
 
 var (
-	confRedisHost = flag.String(flagRedisHost, defaultRedisHost, "redis host address, ip:port")
+	confRedisHost = flag.String(flagRedisHost, defaultRedisHost, "redis host address")
+	confRedisPort = flag.Int(flagRedisPort, 6379, "redis host port")
+	confRedisDb   = flag.Int(flagRedisDb, 1, "redis host db")
 )

+ 0 - 567
vendor/github.com/garyburd/redigo/redis/conn.go

@@ -1,567 +0,0 @@
-// Copyright 2012 Gary Burd
-//
-// Licensed under the Apache License, Version 2.0 (the "License"): you may
-// not use this file except in compliance with the License. You may obtain
-// a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations
-// under the License.
-
-package redis
-
-import (
-	"bufio"
-	"bytes"
-	"errors"
-	"fmt"
-	"io"
-	"net"
-	"net/url"
-	"regexp"
-	"strconv"
-	"sync"
-	"time"
-)
-
-// conn is the low-level implementation of Conn
-type conn struct {
-
-	// Shared
-	mu      sync.Mutex
-	pending int
-	err     error
-	conn    net.Conn
-
-	// Read
-	readTimeout time.Duration
-	br          *bufio.Reader
-
-	// Write
-	writeTimeout time.Duration
-	bw           *bufio.Writer
-
-	// Scratch space for formatting argument length.
-	// '*' or '$', length, "\r\n"
-	lenScratch [32]byte
-
-	// Scratch space for formatting integers and floats.
-	numScratch [40]byte
-}
-
-// DialTimeout acts like Dial but takes timeouts for establishing the
-// connection to the server, writing a command and reading a reply.
-//
-// Deprecated: Use Dial with options instead.
-func DialTimeout(network, address string, connectTimeout, readTimeout, writeTimeout time.Duration) (Conn, error) {
-	return Dial(network, address,
-		DialConnectTimeout(connectTimeout),
-		DialReadTimeout(readTimeout),
-		DialWriteTimeout(writeTimeout))
-}
-
-// DialOption specifies an option for dialing a Redis server.
-type DialOption struct {
-	f func(*dialOptions)
-}
-
-type dialOptions struct {
-	readTimeout  time.Duration
-	writeTimeout time.Duration
-	dial         func(network, addr string) (net.Conn, error)
-	db           int
-	password     string
-}
-
-// DialReadTimeout specifies the timeout for reading a single command reply.
-func DialReadTimeout(d time.Duration) DialOption {
-	return DialOption{func(do *dialOptions) {
-		do.readTimeout = d
-	}}
-}
-
-// DialWriteTimeout specifies the timeout for writing a single command.
-func DialWriteTimeout(d time.Duration) DialOption {
-	return DialOption{func(do *dialOptions) {
-		do.writeTimeout = d
-	}}
-}
-
-// DialConnectTimeout specifies the timeout for connecting to the Redis server.
-func DialConnectTimeout(d time.Duration) DialOption {
-	return DialOption{func(do *dialOptions) {
-		dialer := net.Dialer{Timeout: d}
-		do.dial = dialer.Dial
-	}}
-}
-
-// DialNetDial specifies a custom dial function for creating TCP
-// connections. If this option is left out, then net.Dial is
-// used. DialNetDial overrides DialConnectTimeout.
-func DialNetDial(dial func(network, addr string) (net.Conn, error)) DialOption {
-	return DialOption{func(do *dialOptions) {
-		do.dial = dial
-	}}
-}
-
-// DialDatabase specifies the database to select when dialing a connection.
-func DialDatabase(db int) DialOption {
-	return DialOption{func(do *dialOptions) {
-		do.db = db
-	}}
-}
-
-// DialPassword specifies the password to use when connecting to
-// the Redis server.
-func DialPassword(password string) DialOption {
-	return DialOption{func(do *dialOptions) {
-		do.password = password
-	}}
-}
-
-// Dial connects to the Redis server at the given network and
-// address using the specified options.
-func Dial(network, address string, options ...DialOption) (Conn, error) {
-	do := dialOptions{
-		dial: net.Dial,
-	}
-	for _, option := range options {
-		option.f(&do)
-	}
-
-	netConn, err := do.dial(network, address)
-	if err != nil {
-		return nil, err
-	}
-	c := &conn{
-		conn:         netConn,
-		bw:           bufio.NewWriter(netConn),
-		br:           bufio.NewReader(netConn),
-		readTimeout:  do.readTimeout,
-		writeTimeout: do.writeTimeout,
-	}
-
-	if do.password != "" {
-		if _, err := c.Do("AUTH", do.password); err != nil {
-			netConn.Close()
-			return nil, err
-		}
-	}
-
-	if do.db != 0 {
-		if _, err := c.Do("SELECT", do.db); err != nil {
-			netConn.Close()
-			return nil, err
-		}
-	}
-
-	return c, nil
-}
-
-var pathDBRegexp = regexp.MustCompile(`/(\d+)\z`)
-
-// DialURL connects to a Redis server at the given URL using the Redis
-// URI scheme. URLs should follow the draft IANA specification for the
-// scheme (https://www.iana.org/assignments/uri-schemes/prov/redis).
-func DialURL(rawurl string, options ...DialOption) (Conn, error) {
-	u, err := url.Parse(rawurl)
-	if err != nil {
-		return nil, err
-	}
-
-	if u.Scheme != "redis" {
-		return nil, fmt.Errorf("invalid redis URL scheme: %s", u.Scheme)
-	}
-
-	// As per the IANA draft spec, the host defaults to localhost and
-	// the port defaults to 6379.
-	host, port, err := net.SplitHostPort(u.Host)
-	if err != nil {
-		// assume port is missing
-		host = u.Host
-		port = "6379"
-	}
-	if host == "" {
-		host = "localhost"
-	}
-	address := net.JoinHostPort(host, port)
-
-	if u.User != nil {
-		password, isSet := u.User.Password()
-		if isSet {
-			options = append(options, DialPassword(password))
-		}
-	}
-
-	match := pathDBRegexp.FindStringSubmatch(u.Path)
-	if len(match) == 2 {
-		db, err := strconv.Atoi(match[1])
-		if err != nil {
-			return nil, fmt.Errorf("invalid database: %s", u.Path[1:])
-		}
-		if db != 0 {
-			options = append(options, DialDatabase(db))
-		}
-	} else if u.Path != "" {
-		return nil, fmt.Errorf("invalid database: %s", u.Path[1:])
-	}
-
-	return Dial("tcp", address, options...)
-}
-
-// NewConn returns a new Redigo connection for the given net connection.
-func NewConn(netConn net.Conn, readTimeout, writeTimeout time.Duration) Conn {
-	return &conn{
-		conn:         netConn,
-		bw:           bufio.NewWriter(netConn),
-		br:           bufio.NewReader(netConn),
-		readTimeout:  readTimeout,
-		writeTimeout: writeTimeout,
-	}
-}
-
-func (c *conn) Close() error {
-	c.mu.Lock()
-	err := c.err
-	if c.err == nil {
-		c.err = errors.New("redigo: closed")
-		err = c.conn.Close()
-	}
-	c.mu.Unlock()
-	return err
-}
-
-func (c *conn) fatal(err error) error {
-	c.mu.Lock()
-	if c.err == nil {
-		c.err = err
-		// Close connection to force errors on subsequent calls and to unblock
-		// other reader or writer.
-		c.conn.Close()
-	}
-	c.mu.Unlock()
-	return err
-}
-
-func (c *conn) Err() error {
-	c.mu.Lock()
-	err := c.err
-	c.mu.Unlock()
-	return err
-}
-
-func (c *conn) writeLen(prefix byte, n int) error {
-	c.lenScratch[len(c.lenScratch)-1] = '\n'
-	c.lenScratch[len(c.lenScratch)-2] = '\r'
-	i := len(c.lenScratch) - 3
-	for {
-		c.lenScratch[i] = byte('0' + n%10)
-		i -= 1
-		n = n / 10
-		if n == 0 {
-			break
-		}
-	}
-	c.lenScratch[i] = prefix
-	_, err := c.bw.Write(c.lenScratch[i:])
-	return err
-}
-
-func (c *conn) writeString(s string) error {
-	c.writeLen('$', len(s))
-	c.bw.WriteString(s)
-	_, err := c.bw.WriteString("\r\n")
-	return err
-}
-
-func (c *conn) writeBytes(p []byte) error {
-	c.writeLen('$', len(p))
-	c.bw.Write(p)
-	_, err := c.bw.WriteString("\r\n")
-	return err
-}
-
-func (c *conn) writeInt64(n int64) error {
-	return c.writeBytes(strconv.AppendInt(c.numScratch[:0], n, 10))
-}
-
-func (c *conn) writeFloat64(n float64) error {
-	return c.writeBytes(strconv.AppendFloat(c.numScratch[:0], n, 'g', -1, 64))
-}
-
-func (c *conn) writeCommand(cmd string, args []interface{}) (err error) {
-	c.writeLen('*', 1+len(args))
-	err = c.writeString(cmd)
-	for _, arg := range args {
-		if err != nil {
-			break
-		}
-		switch arg := arg.(type) {
-		case string:
-			err = c.writeString(arg)
-		case []byte:
-			err = c.writeBytes(arg)
-		case int:
-			err = c.writeInt64(int64(arg))
-		case int64:
-			err = c.writeInt64(arg)
-		case float64:
-			err = c.writeFloat64(arg)
-		case bool:
-			if arg {
-				err = c.writeString("1")
-			} else {
-				err = c.writeString("0")
-			}
-		case nil:
-			err = c.writeString("")
-		default:
-			var buf bytes.Buffer
-			fmt.Fprint(&buf, arg)
-			err = c.writeBytes(buf.Bytes())
-		}
-	}
-	return err
-}
-
-type protocolError string
-
-func (pe protocolError) Error() string {
-	return fmt.Sprintf("redigo: %s (possible server error or unsupported concurrent read by application)", string(pe))
-}
-
-func (c *conn) readLine() ([]byte, error) {
-	p, err := c.br.ReadSlice('\n')
-	if err == bufio.ErrBufferFull {
-		return nil, protocolError("long response line")
-	}
-	if err != nil {
-		return nil, err
-	}
-	i := len(p) - 2
-	if i < 0 || p[i] != '\r' {
-		return nil, protocolError("bad response line terminator")
-	}
-	return p[:i], nil
-}
-
-// parseLen parses bulk string and array lengths.
-func parseLen(p []byte) (int, error) {
-	if len(p) == 0 {
-		return -1, protocolError("malformed length")
-	}
-
-	if p[0] == '-' && len(p) == 2 && p[1] == '1' {
-		// handle $-1 and $-1 null replies.
-		return -1, nil
-	}
-
-	var n int
-	for _, b := range p {
-		n *= 10
-		if b < '0' || b > '9' {
-			return -1, protocolError("illegal bytes in length")
-		}
-		n += int(b - '0')
-	}
-
-	return n, nil
-}
-
-// parseInt parses an integer reply.
-func parseInt(p []byte) (interface{}, error) {
-	if len(p) == 0 {
-		return 0, protocolError("malformed integer")
-	}
-
-	var negate bool
-	if p[0] == '-' {
-		negate = true
-		p = p[1:]
-		if len(p) == 0 {
-			return 0, protocolError("malformed integer")
-		}
-	}
-
-	var n int64
-	for _, b := range p {
-		n *= 10
-		if b < '0' || b > '9' {
-			return 0, protocolError("illegal bytes in length")
-		}
-		n += int64(b - '0')
-	}
-
-	if negate {
-		n = -n
-	}
-	return n, nil
-}
-
-var (
-	okReply   interface{} = "OK"
-	pongReply interface{} = "PONG"
-)
-
-func (c *conn) readReply() (interface{}, error) {
-	line, err := c.readLine()
-	if err != nil {
-		return nil, err
-	}
-	if len(line) == 0 {
-		return nil, protocolError("short response line")
-	}
-	switch line[0] {
-	case '+':
-		switch {
-		case len(line) == 3 && line[1] == 'O' && line[2] == 'K':
-			// Avoid allocation for frequent "+OK" response.
-			return okReply, nil
-		case len(line) == 5 && line[1] == 'P' && line[2] == 'O' && line[3] == 'N' && line[4] == 'G':
-			// Avoid allocation in PING command benchmarks :)
-			return pongReply, nil
-		default:
-			return string(line[1:]), nil
-		}
-	case '-':
-		return Error(string(line[1:])), nil
-	case ':':
-		return parseInt(line[1:])
-	case '$':
-		n, err := parseLen(line[1:])
-		if n < 0 || err != nil {
-			return nil, err
-		}
-		p := make([]byte, n)
-		_, err = io.ReadFull(c.br, p)
-		if err != nil {
-			return nil, err
-		}
-		if line, err := c.readLine(); err != nil {
-			return nil, err
-		} else if len(line) != 0 {
-			return nil, protocolError("bad bulk string format")
-		}
-		return p, nil
-	case '*':
-		n, err := parseLen(line[1:])
-		if n < 0 || err != nil {
-			return nil, err
-		}
-		r := make([]interface{}, n)
-		for i := range r {
-			r[i], err = c.readReply()
-			if err != nil {
-				return nil, err
-			}
-		}
-		return r, nil
-	}
-	return nil, protocolError("unexpected response line")
-}
-
-func (c *conn) Send(cmd string, args ...interface{}) error {
-	c.mu.Lock()
-	c.pending += 1
-	c.mu.Unlock()
-	if c.writeTimeout != 0 {
-		c.conn.SetWriteDeadline(time.Now().Add(c.writeTimeout))
-	}
-	if err := c.writeCommand(cmd, args); err != nil {
-		return c.fatal(err)
-	}
-	return nil
-}
-
-func (c *conn) Flush() error {
-	if c.writeTimeout != 0 {
-		c.conn.SetWriteDeadline(time.Now().Add(c.writeTimeout))
-	}
-	if err := c.bw.Flush(); err != nil {
-		return c.fatal(err)
-	}
-	return nil
-}
-
-func (c *conn) Receive() (reply interface{}, err error) {
-	if c.readTimeout != 0 {
-		c.conn.SetReadDeadline(time.Now().Add(c.readTimeout))
-	}
-	if reply, err = c.readReply(); err != nil {
-		return nil, c.fatal(err)
-	}
-	// When using pub/sub, the number of receives can be greater than the
-	// number of sends. To enable normal use of the connection after
-	// unsubscribing from all channels, we do not decrement pending to a
-	// negative value.
-	//
-	// The pending field is decremented after the reply is read to handle the
-	// case where Receive is called before Send.
-	c.mu.Lock()
-	if c.pending > 0 {
-		c.pending -= 1
-	}
-	c.mu.Unlock()
-	if err, ok := reply.(Error); ok {
-		return nil, err
-	}
-	return
-}
-
-func (c *conn) Do(cmd string, args ...interface{}) (interface{}, error) {
-	c.mu.Lock()
-	pending := c.pending
-	c.pending = 0
-	c.mu.Unlock()
-
-	if cmd == "" && pending == 0 {
-		return nil, nil
-	}
-
-	if c.writeTimeout != 0 {
-		c.conn.SetWriteDeadline(time.Now().Add(c.writeTimeout))
-	}
-
-	if cmd != "" {
-		if err := c.writeCommand(cmd, args); err != nil {
-			return nil, c.fatal(err)
-		}
-	}
-
-	if err := c.bw.Flush(); err != nil {
-		return nil, c.fatal(err)
-	}
-
-	if c.readTimeout != 0 {
-		c.conn.SetReadDeadline(time.Now().Add(c.readTimeout))
-	}
-
-	if cmd == "" {
-		reply := make([]interface{}, pending)
-		for i := range reply {
-			r, e := c.readReply()
-			if e != nil {
-				return nil, c.fatal(e)
-			}
-			reply[i] = r
-		}
-		return reply, nil
-	}
-
-	var err error
-	var reply interface{}
-	for i := 0; i <= pending; i++ {
-		var e error
-		if reply, e = c.readReply(); e != nil {
-			return nil, c.fatal(e)
-		}
-		if e, ok := reply.(Error); ok && err == nil {
-			err = e
-		}
-	}
-	return reply, err
-}

+ 0 - 169
vendor/github.com/garyburd/redigo/redis/doc.go

@@ -1,169 +0,0 @@
-// Copyright 2012 Gary Burd
-//
-// Licensed under the Apache License, Version 2.0 (the "License"): you may
-// not use this file except in compliance with the License. You may obtain
-// a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations
-// under the License.
-
-// Package redis is a client for the Redis database.
-//
-// The Redigo FAQ (https://github.com/garyburd/redigo/wiki/FAQ) contains more
-// documentation about this package.
-//
-// Connections
-//
-// The Conn interface is the primary interface for working with Redis.
-// Applications create connections by calling the Dial, DialWithTimeout or
-// NewConn functions. In the future, functions will be added for creating
-// sharded and other types of connections.
-//
-// The application must call the connection Close method when the application
-// is done with the connection.
-//
-// Executing Commands
-//
-// The Conn interface has a generic method for executing Redis commands:
-//
-//  Do(commandName string, args ...interface{}) (reply interface{}, err error)
-//
-// The Redis command reference (http://redis.io/commands) lists the available
-// commands. An example of using the Redis APPEND command is:
-//
-//  n, err := conn.Do("APPEND", "key", "value")
-//
-// The Do method converts command arguments to binary strings for transmission
-// to the server as follows:
-//
-//  Go Type                 Conversion
-//  []byte                  Sent as is
-//  string                  Sent as is
-//  int, int64              strconv.FormatInt(v)
-//  float64                 strconv.FormatFloat(v, 'g', -1, 64)
-//  bool                    true -> "1", false -> "0"
-//  nil                     ""
-//  all other types         fmt.Print(v)
-//
-// Redis command reply types are represented using the following Go types:
-//
-//  Redis type              Go type
-//  error                   redis.Error
-//  integer                 int64
-//  simple string           string
-//  bulk string             []byte or nil if value not present.
-//  array                   []interface{} or nil if value not present.
-//
-// Use type assertions or the reply helper functions to convert from
-// interface{} to the specific Go type for the command result.
-//
-// Pipelining
-//
-// Connections support pipelining using the Send, Flush and Receive methods.
-//
-//  Send(commandName string, args ...interface{}) error
-//  Flush() error
-//  Receive() (reply interface{}, err error)
-//
-// Send writes the command to the connection's output buffer. Flush flushes the
-// connection's output buffer to the server. Receive reads a single reply from
-// the server. The following example shows a simple pipeline.
-//
-//  c.Send("SET", "foo", "bar")
-//  c.Send("GET", "foo")
-//  c.Flush()
-//  c.Receive() // reply from SET
-//  v, err = c.Receive() // reply from GET
-//
-// The Do method combines the functionality of the Send, Flush and Receive
-// methods. The Do method starts by writing the command and flushing the output
-// buffer. Next, the Do method receives all pending replies including the reply
-// for the command just sent by Do. If any of the received replies is an error,
-// then Do returns the error. If there are no errors, then Do returns the last
-// reply. If the command argument to the Do method is "", then the Do method
-// will flush the output buffer and receive pending replies without sending a
-// command.
-//
-// Use the Send and Do methods to implement pipelined transactions.
-//
-//  c.Send("MULTI")
-//  c.Send("INCR", "foo")
-//  c.Send("INCR", "bar")
-//  r, err := c.Do("EXEC")
-//  fmt.Println(r) // prints [1, 1]
-//
-// Concurrency
-//
-// Connections do not support concurrent calls to the write methods (Send,
-// Flush) or concurrent calls to the read method (Receive). Connections do
-// allow a concurrent reader and writer.
-//
-// Because the Do method combines the functionality of Send, Flush and Receive,
-// the Do method cannot be called concurrently with the other methods.
-//
-// For full concurrent access to Redis, use the thread-safe Pool to get and
-// release connections from within a goroutine.
-//
-// Publish and Subscribe
-//
-// Use the Send, Flush and Receive methods to implement Pub/Sub subscribers.
-//
-//  c.Send("SUBSCRIBE", "example")
-//  c.Flush()
-//  for {
-//      reply, err := c.Receive()
-//      if err != nil {
-//          return err
-//      }
-//      // process pushed message
-//  }
-//
-// The PubSubConn type wraps a Conn with convenience methods for implementing
-// subscribers. The Subscribe, PSubscribe, Unsubscribe and PUnsubscribe methods
-// send and flush a subscription management command. The receive method
-// converts a pushed message to convenient types for use in a type switch.
-//
-//  psc := redis.PubSubConn{c}
-//  psc.Subscribe("example")
-//  for {
-//      switch v := psc.Receive().(type) {
-//      case redis.Message:
-//          fmt.Printf("%s: message: %s\n", v.Channel, v.Data)
-//      case redis.Subscription:
-//          fmt.Printf("%s: %s %d\n", v.Channel, v.Kind, v.Count)
-//      case error:
-//          return v
-//      }
-//  }
-//
-// Reply Helpers
-//
-// The Bool, Int, Bytes, String, Strings and Values functions convert a reply
-// to a value of a specific type. To allow convenient wrapping of calls to the
-// connection Do and Receive methods, the functions take a second argument of
-// type error.  If the error is non-nil, then the helper function returns the
-// error. If the error is nil, the function converts the reply to the specified
-// type:
-//
-//  exists, err := redis.Bool(c.Do("EXISTS", "foo"))
-//  if err != nil {
-//      // handle error return from c.Do or type conversion error.
-//  }
-//
-// The Scan function converts elements of a array reply to Go types:
-//
-//  var value1 int
-//  var value2 string
-//  reply, err := redis.Values(c.Do("MGET", "key1", "key2"))
-//  if err != nil {
-//      // handle error
-//  }
-//   if _, err := redis.Scan(reply, &value1, &value2); err != nil {
-//      // handle error
-//  }
-package redis

+ 0 - 117
vendor/github.com/garyburd/redigo/redis/log.go

@@ -1,117 +0,0 @@
-// Copyright 2012 Gary Burd
-//
-// Licensed under the Apache License, Version 2.0 (the "License"): you may
-// not use this file except in compliance with the License. You may obtain
-// a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations
-// under the License.
-
-package redis
-
-import (
-	"bytes"
-	"fmt"
-	"log"
-)
-
-// NewLoggingConn returns a logging wrapper around a connection.
-func NewLoggingConn(conn Conn, logger *log.Logger, prefix string) Conn {
-	if prefix != "" {
-		prefix = prefix + "."
-	}
-	return &loggingConn{conn, logger, prefix}
-}
-
-type loggingConn struct {
-	Conn
-	logger *log.Logger
-	prefix string
-}
-
-func (c *loggingConn) Close() error {
-	err := c.Conn.Close()
-	var buf bytes.Buffer
-	fmt.Fprintf(&buf, "%sClose() -> (%v)", c.prefix, err)
-	c.logger.Output(2, buf.String())
-	return err
-}
-
-func (c *loggingConn) printValue(buf *bytes.Buffer, v interface{}) {
-	const chop = 32
-	switch v := v.(type) {
-	case []byte:
-		if len(v) > chop {
-			fmt.Fprintf(buf, "%q...", v[:chop])
-		} else {
-			fmt.Fprintf(buf, "%q", v)
-		}
-	case string:
-		if len(v) > chop {
-			fmt.Fprintf(buf, "%q...", v[:chop])
-		} else {
-			fmt.Fprintf(buf, "%q", v)
-		}
-	case []interface{}:
-		if len(v) == 0 {
-			buf.WriteString("[]")
-		} else {
-			sep := "["
-			fin := "]"
-			if len(v) > chop {
-				v = v[:chop]
-				fin = "...]"
-			}
-			for _, vv := range v {
-				buf.WriteString(sep)
-				c.printValue(buf, vv)
-				sep = ", "
-			}
-			buf.WriteString(fin)
-		}
-	default:
-		fmt.Fprint(buf, v)
-	}
-}
-
-func (c *loggingConn) print(method, commandName string, args []interface{}, reply interface{}, err error) {
-	var buf bytes.Buffer
-	fmt.Fprintf(&buf, "%s%s(", c.prefix, method)
-	if method != "Receive" {
-		buf.WriteString(commandName)
-		for _, arg := range args {
-			buf.WriteString(", ")
-			c.printValue(&buf, arg)
-		}
-	}
-	buf.WriteString(") -> (")
-	if method != "Send" {
-		c.printValue(&buf, reply)
-		buf.WriteString(", ")
-	}
-	fmt.Fprintf(&buf, "%v)", err)
-	c.logger.Output(3, buf.String())
-}
-
-func (c *loggingConn) Do(commandName string, args ...interface{}) (interface{}, error) {
-	reply, err := c.Conn.Do(commandName, args...)
-	c.print("Do", commandName, args, reply, err)
-	return reply, err
-}
-
-func (c *loggingConn) Send(commandName string, args ...interface{}) error {
-	err := c.Conn.Send(commandName, args...)
-	c.print("Send", commandName, args, nil, err)
-	return err
-}
-
-func (c *loggingConn) Receive() (interface{}, error) {
-	reply, err := c.Conn.Receive()
-	c.print("Receive", "", nil, reply, err)
-	return reply, err
-}

+ 0 - 393
vendor/github.com/garyburd/redigo/redis/pool.go

@@ -1,393 +0,0 @@
-// Copyright 2012 Gary Burd
-//
-// Licensed under the Apache License, Version 2.0 (the "License"): you may
-// not use this file except in compliance with the License. You may obtain
-// a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations
-// under the License.
-
-package redis
-
-import (
-	"bytes"
-	"container/list"
-	"crypto/rand"
-	"crypto/sha1"
-	"errors"
-	"io"
-	"strconv"
-	"sync"
-	"time"
-
-	"github.com/garyburd/redigo/internal"
-)
-
-var nowFunc = time.Now // for testing
-
-// ErrPoolExhausted is returned from a pool connection method (Do, Send,
-// Receive, Flush, Err) when the maximum number of database connections in the
-// pool has been reached.
-var ErrPoolExhausted = errors.New("redigo: connection pool exhausted")
-
-var (
-	errPoolClosed = errors.New("redigo: connection pool closed")
-	errConnClosed = errors.New("redigo: connection closed")
-)
-
-// Pool maintains a pool of connections. The application calls the Get method
-// to get a connection from the pool and the connection's Close method to
-// return the connection's resources to the pool.
-//
-// The following example shows how to use a pool in a web application. The
-// application creates a pool at application startup and makes it available to
-// request handlers using a global variable.
-//
-//  func newPool(server, password string) *redis.Pool {
-//      return &redis.Pool{
-//          MaxIdle: 3,
-//          IdleTimeout: 240 * time.Second,
-//          Dial: func () (redis.Conn, error) {
-//              c, err := redis.Dial("tcp", server)
-//              if err != nil {
-//                  return nil, err
-//              }
-//              if _, err := c.Do("AUTH", password); err != nil {
-//                  c.Close()
-//                  return nil, err
-//              }
-//              return c, err
-//          },
-//          TestOnBorrow: func(c redis.Conn, t time.Time) error {
-//              _, err := c.Do("PING")
-//              return err
-//          },
-//      }
-//  }
-//
-//  var (
-//      pool *redis.Pool
-//      redisServer = flag.String("redisServer", ":6379", "")
-//      redisPassword = flag.String("redisPassword", "", "")
-//  )
-//
-//  func main() {
-//      flag.Parse()
-//      pool = newPool(*redisServer, *redisPassword)
-//      ...
-//  }
-//
-// A request handler gets a connection from the pool and closes the connection
-// when the handler is done:
-//
-//  func serveHome(w http.ResponseWriter, r *http.Request) {
-//      conn := pool.Get()
-//      defer conn.Close()
-//      ....
-//  }
-//
-type Pool struct {
-
-	// Dial is an application supplied function for creating and configuring a
-	// connection.
-	//
-	// The connection returned from Dial must not be in a special state
-	// (subscribed to pubsub channel, transaction started, ...).
-	Dial func() (Conn, error)
-
-	// TestOnBorrow is an optional application supplied function for checking
-	// the health of an idle connection before the connection is used again by
-	// the application. Argument t is the time that the connection was returned
-	// to the pool. If the function returns an error, then the connection is
-	// closed.
-	TestOnBorrow func(c Conn, t time.Time) error
-
-	// Maximum number of idle connections in the pool.
-	MaxIdle int
-
-	// Maximum number of connections allocated by the pool at a given time.
-	// When zero, there is no limit on the number of connections in the pool.
-	MaxActive int
-
-	// Close connections after remaining idle for this duration. If the value
-	// is zero, then idle connections are not closed. Applications should set
-	// the timeout to a value less than the server's timeout.
-	IdleTimeout time.Duration
-
-	// If Wait is true and the pool is at the MaxActive limit, then Get() waits
-	// for a connection to be returned to the pool before returning.
-	Wait bool
-
-	// mu protects fields defined below.
-	mu     sync.Mutex
-	cond   *sync.Cond
-	closed bool
-	active int
-
-	// Stack of idleConn with most recently used at the front.
-	idle list.List
-}
-
-type idleConn struct {
-	c Conn
-	t time.Time
-}
-
-// NewPool creates a new pool.
-//
-// Deprecated: Initialize the Pool directory as shown in the example.
-func NewPool(newFn func() (Conn, error), maxIdle int) *Pool {
-	return &Pool{Dial: newFn, MaxIdle: maxIdle}
-}
-
-// Get gets a connection. The application must close the returned connection.
-// This method always returns a valid connection so that applications can defer
-// error handling to the first use of the connection. If there is an error
-// getting an underlying connection, then the connection Err, Do, Send, Flush
-// and Receive methods return that error.
-func (p *Pool) Get() Conn {
-	c, err := p.get()
-	if err != nil {
-		return errorConnection{err}
-	}
-	return &pooledConnection{p: p, c: c}
-}
-
-// ActiveCount returns the number of active connections in the pool.
-func (p *Pool) ActiveCount() int {
-	p.mu.Lock()
-	active := p.active
-	p.mu.Unlock()
-	return active
-}
-
-// Close releases the resources used by the pool.
-func (p *Pool) Close() error {
-	p.mu.Lock()
-	idle := p.idle
-	p.idle.Init()
-	p.closed = true
-	p.active -= idle.Len()
-	if p.cond != nil {
-		p.cond.Broadcast()
-	}
-	p.mu.Unlock()
-	for e := idle.Front(); e != nil; e = e.Next() {
-		e.Value.(idleConn).c.Close()
-	}
-	return nil
-}
-
-// release decrements the active count and signals waiters. The caller must
-// hold p.mu during the call.
-func (p *Pool) release() {
-	p.active -= 1
-	if p.cond != nil {
-		p.cond.Signal()
-	}
-}
-
-// get prunes stale connections and returns a connection from the idle list or
-// creates a new connection.
-func (p *Pool) get() (Conn, error) {
-	p.mu.Lock()
-
-	// Prune stale connections.
-
-	if timeout := p.IdleTimeout; timeout > 0 {
-		for i, n := 0, p.idle.Len(); i < n; i++ {
-			e := p.idle.Back()
-			if e == nil {
-				break
-			}
-			ic := e.Value.(idleConn)
-			if ic.t.Add(timeout).After(nowFunc()) {
-				break
-			}
-			p.idle.Remove(e)
-			p.release()
-			p.mu.Unlock()
-			ic.c.Close()
-			p.mu.Lock()
-		}
-	}
-
-	for {
-
-		// Get idle connection.
-
-		for i, n := 0, p.idle.Len(); i < n; i++ {
-			e := p.idle.Front()
-			if e == nil {
-				break
-			}
-			ic := e.Value.(idleConn)
-			p.idle.Remove(e)
-			test := p.TestOnBorrow
-			p.mu.Unlock()
-			if test == nil || test(ic.c, ic.t) == nil {
-				return ic.c, nil
-			}
-			ic.c.Close()
-			p.mu.Lock()
-			p.release()
-		}
-
-		// Check for pool closed before dialing a new connection.
-
-		if p.closed {
-			p.mu.Unlock()
-			return nil, errors.New("redigo: get on closed pool")
-		}
-
-		// Dial new connection if under limit.
-
-		if p.MaxActive == 0 || p.active < p.MaxActive {
-			dial := p.Dial
-			p.active += 1
-			p.mu.Unlock()
-			c, err := dial()
-			if err != nil {
-				p.mu.Lock()
-				p.release()
-				p.mu.Unlock()
-				c = nil
-			}
-			return c, err
-		}
-
-		if !p.Wait {
-			p.mu.Unlock()
-			return nil, ErrPoolExhausted
-		}
-
-		if p.cond == nil {
-			p.cond = sync.NewCond(&p.mu)
-		}
-		p.cond.Wait()
-	}
-}
-
-func (p *Pool) put(c Conn, forceClose bool) error {
-	err := c.Err()
-	p.mu.Lock()
-	if !p.closed && err == nil && !forceClose {
-		p.idle.PushFront(idleConn{t: nowFunc(), c: c})
-		if p.idle.Len() > p.MaxIdle {
-			c = p.idle.Remove(p.idle.Back()).(idleConn).c
-		} else {
-			c = nil
-		}
-	}
-
-	if c == nil {
-		if p.cond != nil {
-			p.cond.Signal()
-		}
-		p.mu.Unlock()
-		return nil
-	}
-
-	p.release()
-	p.mu.Unlock()
-	return c.Close()
-}
-
-type pooledConnection struct {
-	p     *Pool
-	c     Conn
-	state int
-}
-
-var (
-	sentinel     []byte
-	sentinelOnce sync.Once
-)
-
-func initSentinel() {
-	p := make([]byte, 64)
-	if _, err := rand.Read(p); err == nil {
-		sentinel = p
-	} else {
-		h := sha1.New()
-		io.WriteString(h, "Oops, rand failed. Use time instead.")
-		io.WriteString(h, strconv.FormatInt(time.Now().UnixNano(), 10))
-		sentinel = h.Sum(nil)
-	}
-}
-
-func (pc *pooledConnection) Close() error {
-	c := pc.c
-	if _, ok := c.(errorConnection); ok {
-		return nil
-	}
-	pc.c = errorConnection{errConnClosed}
-
-	if pc.state&internal.MultiState != 0 {
-		c.Send("DISCARD")
-		pc.state &^= (internal.MultiState | internal.WatchState)
-	} else if pc.state&internal.WatchState != 0 {
-		c.Send("UNWATCH")
-		pc.state &^= internal.WatchState
-	}
-	if pc.state&internal.SubscribeState != 0 {
-		c.Send("UNSUBSCRIBE")
-		c.Send("PUNSUBSCRIBE")
-		// To detect the end of the message stream, ask the server to echo
-		// a sentinel value and read until we see that value.
-		sentinelOnce.Do(initSentinel)
-		c.Send("ECHO", sentinel)
-		c.Flush()
-		for {
-			p, err := c.Receive()
-			if err != nil {
-				break
-			}
-			if p, ok := p.([]byte); ok && bytes.Equal(p, sentinel) {
-				pc.state &^= internal.SubscribeState
-				break
-			}
-		}
-	}
-	c.Do("")
-	pc.p.put(c, pc.state != 0)
-	return nil
-}
-
-func (pc *pooledConnection) Err() error {
-	return pc.c.Err()
-}
-
-func (pc *pooledConnection) Do(commandName string, args ...interface{}) (reply interface{}, err error) {
-	ci := internal.LookupCommandInfo(commandName)
-	pc.state = (pc.state | ci.Set) &^ ci.Clear
-	return pc.c.Do(commandName, args...)
-}
-
-func (pc *pooledConnection) Send(commandName string, args ...interface{}) error {
-	ci := internal.LookupCommandInfo(commandName)
-	pc.state = (pc.state | ci.Set) &^ ci.Clear
-	return pc.c.Send(commandName, args...)
-}
-
-func (pc *pooledConnection) Flush() error {
-	return pc.c.Flush()
-}
-
-func (pc *pooledConnection) Receive() (reply interface{}, err error) {
-	return pc.c.Receive()
-}
-
-type errorConnection struct{ err error }
-
-func (ec errorConnection) Do(string, ...interface{}) (interface{}, error) { return nil, ec.err }
-func (ec errorConnection) Send(string, ...interface{}) error              { return ec.err }
-func (ec errorConnection) Err() error                                     { return ec.err }
-func (ec errorConnection) Close() error                                   { return ec.err }
-func (ec errorConnection) Flush() error                                   { return ec.err }
-func (ec errorConnection) Receive() (interface{}, error)                  { return nil, ec.err }

+ 0 - 144
vendor/github.com/garyburd/redigo/redis/pubsub.go

@@ -1,144 +0,0 @@
-// Copyright 2012 Gary Burd
-//
-// Licensed under the Apache License, Version 2.0 (the "License"): you may
-// not use this file except in compliance with the License. You may obtain
-// a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations
-// under the License.
-
-package redis
-
-import "errors"
-
-// Subscription represents a subscribe or unsubscribe notification.
-type Subscription struct {
-
-	// Kind is "subscribe", "unsubscribe", "psubscribe" or "punsubscribe"
-	Kind string
-
-	// The channel that was changed.
-	Channel string
-
-	// The current number of subscriptions for connection.
-	Count int
-}
-
-// Message represents a message notification.
-type Message struct {
-
-	// The originating channel.
-	Channel string
-
-	// The message data.
-	Data []byte
-}
-
-// PMessage represents a pmessage notification.
-type PMessage struct {
-
-	// The matched pattern.
-	Pattern string
-
-	// The originating channel.
-	Channel string
-
-	// The message data.
-	Data []byte
-}
-
-// Pong represents a pubsub pong notification.
-type Pong struct {
-	Data string
-}
-
-// PubSubConn wraps a Conn with convenience methods for subscribers.
-type PubSubConn struct {
-	Conn Conn
-}
-
-// Close closes the connection.
-func (c PubSubConn) Close() error {
-	return c.Conn.Close()
-}
-
-// Subscribe subscribes the connection to the specified channels.
-func (c PubSubConn) Subscribe(channel ...interface{}) error {
-	c.Conn.Send("SUBSCRIBE", channel...)
-	return c.Conn.Flush()
-}
-
-// PSubscribe subscribes the connection to the given patterns.
-func (c PubSubConn) PSubscribe(channel ...interface{}) error {
-	c.Conn.Send("PSUBSCRIBE", channel...)
-	return c.Conn.Flush()
-}
-
-// Unsubscribe unsubscribes the connection from the given channels, or from all
-// of them if none is given.
-func (c PubSubConn) Unsubscribe(channel ...interface{}) error {
-	c.Conn.Send("UNSUBSCRIBE", channel...)
-	return c.Conn.Flush()
-}
-
-// PUnsubscribe unsubscribes the connection from the given patterns, or from all
-// of them if none is given.
-func (c PubSubConn) PUnsubscribe(channel ...interface{}) error {
-	c.Conn.Send("PUNSUBSCRIBE", channel...)
-	return c.Conn.Flush()
-}
-
-// Ping sends a PING to the server with the specified data.
-func (c PubSubConn) Ping(data string) error {
-	c.Conn.Send("PING", data)
-	return c.Conn.Flush()
-}
-
-// Receive returns a pushed message as a Subscription, Message, PMessage, Pong
-// or error. The return value is intended to be used directly in a type switch
-// as illustrated in the PubSubConn example.
-func (c PubSubConn) Receive() interface{} {
-	reply, err := Values(c.Conn.Receive())
-	if err != nil {
-		return err
-	}
-
-	var kind string
-	reply, err = Scan(reply, &kind)
-	if err != nil {
-		return err
-	}
-
-	switch kind {
-	case "message":
-		var m Message
-		if _, err := Scan(reply, &m.Channel, &m.Data); err != nil {
-			return err
-		}
-		return m
-	case "pmessage":
-		var pm PMessage
-		if _, err := Scan(reply, &pm.Pattern, &pm.Channel, &pm.Data); err != nil {
-			return err
-		}
-		return pm
-	case "subscribe", "psubscribe", "unsubscribe", "punsubscribe":
-		s := Subscription{Kind: kind}
-		if _, err := Scan(reply, &s.Channel, &s.Count); err != nil {
-			return err
-		}
-		return s
-	case "pong":
-		var p Pong
-		if _, err := Scan(reply, &p.Data); err != nil {
-			return err
-		}
-		return p
-	}
-	return errors.New("redigo: unknown pubsub notification")
-}

+ 0 - 44
vendor/github.com/garyburd/redigo/redis/redis.go

@@ -1,44 +0,0 @@
-// Copyright 2012 Gary Burd
-//
-// Licensed under the Apache License, Version 2.0 (the "License"): you may
-// not use this file except in compliance with the License. You may obtain
-// a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations
-// under the License.
-
-package redis
-
-// Error represents an error returned in a command reply.
-type Error string
-
-func (err Error) Error() string { return string(err) }
-
-// Conn represents a connection to a Redis server.
-type Conn interface {
-	// Close closes the connection.
-	Close() error
-
-	// Err returns a non-nil value if the connection is broken. The returned
-	// value is either the first non-nil value returned from the underlying
-	// network connection or a protocol parsing error. Applications should
-	// close broken connections.
-	Err() error
-
-	// Do sends a command to the server and returns the received reply.
-	Do(commandName string, args ...interface{}) (reply interface{}, err error)
-
-	// Send writes the command to the client's output buffer.
-	Send(commandName string, args ...interface{}) error
-
-	// Flush flushes the output buffer to the Redis server.
-	Flush() error
-
-	// Receive receives a single reply from the Redis server
-	Receive() (reply interface{}, err error)
-}

+ 0 - 393
vendor/github.com/garyburd/redigo/redis/reply.go

@@ -1,393 +0,0 @@
-// Copyright 2012 Gary Burd
-//
-// Licensed under the Apache License, Version 2.0 (the "License"): you may
-// not use this file except in compliance with the License. You may obtain
-// a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations
-// under the License.
-
-package redis
-
-import (
-	"errors"
-	"fmt"
-	"strconv"
-)
-
-// ErrNil indicates that a reply value is nil.
-var ErrNil = errors.New("redigo: nil returned")
-
-// Int is a helper that converts a command reply to an integer. If err is not
-// equal to nil, then Int returns 0, err. Otherwise, Int converts the
-// reply to an int as follows:
-//
-//  Reply type    Result
-//  integer       int(reply), nil
-//  bulk string   parsed reply, nil
-//  nil           0, ErrNil
-//  other         0, error
-func Int(reply interface{}, err error) (int, error) {
-	if err != nil {
-		return 0, err
-	}
-	switch reply := reply.(type) {
-	case int64:
-		x := int(reply)
-		if int64(x) != reply {
-			return 0, strconv.ErrRange
-		}
-		return x, nil
-	case []byte:
-		n, err := strconv.ParseInt(string(reply), 10, 0)
-		return int(n), err
-	case nil:
-		return 0, ErrNil
-	case Error:
-		return 0, reply
-	}
-	return 0, fmt.Errorf("redigo: unexpected type for Int, got type %T", reply)
-}
-
-// Int64 is a helper that converts a command reply to 64 bit integer. If err is
-// not equal to nil, then Int returns 0, err. Otherwise, Int64 converts the
-// reply to an int64 as follows:
-//
-//  Reply type    Result
-//  integer       reply, nil
-//  bulk string   parsed reply, nil
-//  nil           0, ErrNil
-//  other         0, error
-func Int64(reply interface{}, err error) (int64, error) {
-	if err != nil {
-		return 0, err
-	}
-	switch reply := reply.(type) {
-	case int64:
-		return reply, nil
-	case []byte:
-		n, err := strconv.ParseInt(string(reply), 10, 64)
-		return n, err
-	case nil:
-		return 0, ErrNil
-	case Error:
-		return 0, reply
-	}
-	return 0, fmt.Errorf("redigo: unexpected type for Int64, got type %T", reply)
-}
-
-var errNegativeInt = errors.New("redigo: unexpected value for Uint64")
-
-// Uint64 is a helper that converts a command reply to 64 bit integer. If err is
-// not equal to nil, then Int returns 0, err. Otherwise, Int64 converts the
-// reply to an int64 as follows:
-//
-//  Reply type    Result
-//  integer       reply, nil
-//  bulk string   parsed reply, nil
-//  nil           0, ErrNil
-//  other         0, error
-func Uint64(reply interface{}, err error) (uint64, error) {
-	if err != nil {
-		return 0, err
-	}
-	switch reply := reply.(type) {
-	case int64:
-		if reply < 0 {
-			return 0, errNegativeInt
-		}
-		return uint64(reply), nil
-	case []byte:
-		n, err := strconv.ParseUint(string(reply), 10, 64)
-		return n, err
-	case nil:
-		return 0, ErrNil
-	case Error:
-		return 0, reply
-	}
-	return 0, fmt.Errorf("redigo: unexpected type for Uint64, got type %T", reply)
-}
-
-// Float64 is a helper that converts a command reply to 64 bit float. If err is
-// not equal to nil, then Float64 returns 0, err. Otherwise, Float64 converts
-// the reply to an int as follows:
-//
-//  Reply type    Result
-//  bulk string   parsed reply, nil
-//  nil           0, ErrNil
-//  other         0, error
-func Float64(reply interface{}, err error) (float64, error) {
-	if err != nil {
-		return 0, err
-	}
-	switch reply := reply.(type) {
-	case []byte:
-		n, err := strconv.ParseFloat(string(reply), 64)
-		return n, err
-	case nil:
-		return 0, ErrNil
-	case Error:
-		return 0, reply
-	}
-	return 0, fmt.Errorf("redigo: unexpected type for Float64, got type %T", reply)
-}
-
-// String is a helper that converts a command reply to a string. If err is not
-// equal to nil, then String returns "", err. Otherwise String converts the
-// reply to a string as follows:
-//
-//  Reply type      Result
-//  bulk string     string(reply), nil
-//  simple string   reply, nil
-//  nil             "",  ErrNil
-//  other           "",  error
-func String(reply interface{}, err error) (string, error) {
-	if err != nil {
-		return "", err
-	}
-	switch reply := reply.(type) {
-	case []byte:
-		return string(reply), nil
-	case string:
-		return reply, nil
-	case nil:
-		return "", ErrNil
-	case Error:
-		return "", reply
-	}
-	return "", fmt.Errorf("redigo: unexpected type for String, got type %T", reply)
-}
-
-// Bytes is a helper that converts a command reply to a slice of bytes. If err
-// is not equal to nil, then Bytes returns nil, err. Otherwise Bytes converts
-// the reply to a slice of bytes as follows:
-//
-//  Reply type      Result
-//  bulk string     reply, nil
-//  simple string   []byte(reply), nil
-//  nil             nil, ErrNil
-//  other           nil, error
-func Bytes(reply interface{}, err error) ([]byte, error) {
-	if err != nil {
-		return nil, err
-	}
-	switch reply := reply.(type) {
-	case []byte:
-		return reply, nil
-	case string:
-		return []byte(reply), nil
-	case nil:
-		return nil, ErrNil
-	case Error:
-		return nil, reply
-	}
-	return nil, fmt.Errorf("redigo: unexpected type for Bytes, got type %T", reply)
-}
-
-// Bool is a helper that converts a command reply to a boolean. If err is not
-// equal to nil, then Bool returns false, err. Otherwise Bool converts the
-// reply to boolean as follows:
-//
-//  Reply type      Result
-//  integer         value != 0, nil
-//  bulk string     strconv.ParseBool(reply)
-//  nil             false, ErrNil
-//  other           false, error
-func Bool(reply interface{}, err error) (bool, error) {
-	if err != nil {
-		return false, err
-	}
-	switch reply := reply.(type) {
-	case int64:
-		return reply != 0, nil
-	case []byte:
-		return strconv.ParseBool(string(reply))
-	case nil:
-		return false, ErrNil
-	case Error:
-		return false, reply
-	}
-	return false, fmt.Errorf("redigo: unexpected type for Bool, got type %T", reply)
-}
-
-// MultiBulk is a helper that converts an array command reply to a []interface{}.
-//
-// Deprecated: Use Values instead.
-func MultiBulk(reply interface{}, err error) ([]interface{}, error) { return Values(reply, err) }
-
-// Values is a helper that converts an array command reply to a []interface{}.
-// If err is not equal to nil, then Values returns nil, err. Otherwise, Values
-// converts the reply as follows:
-//
-//  Reply type      Result
-//  array           reply, nil
-//  nil             nil, ErrNil
-//  other           nil, error
-func Values(reply interface{}, err error) ([]interface{}, error) {
-	if err != nil {
-		return nil, err
-	}
-	switch reply := reply.(type) {
-	case []interface{}:
-		return reply, nil
-	case nil:
-		return nil, ErrNil
-	case Error:
-		return nil, reply
-	}
-	return nil, fmt.Errorf("redigo: unexpected type for Values, got type %T", reply)
-}
-
-// Strings is a helper that converts an array command reply to a []string. If
-// err is not equal to nil, then Strings returns nil, err. Nil array items are
-// converted to "" in the output slice. Strings returns an error if an array
-// item is not a bulk string or nil.
-func Strings(reply interface{}, err error) ([]string, error) {
-	if err != nil {
-		return nil, err
-	}
-	switch reply := reply.(type) {
-	case []interface{}:
-		result := make([]string, len(reply))
-		for i := range reply {
-			if reply[i] == nil {
-				continue
-			}
-			p, ok := reply[i].([]byte)
-			if !ok {
-				return nil, fmt.Errorf("redigo: unexpected element type for Strings, got type %T", reply[i])
-			}
-			result[i] = string(p)
-		}
-		return result, nil
-	case nil:
-		return nil, ErrNil
-	case Error:
-		return nil, reply
-	}
-	return nil, fmt.Errorf("redigo: unexpected type for Strings, got type %T", reply)
-}
-
-// ByteSlices is a helper that converts an array command reply to a [][]byte.
-// If err is not equal to nil, then ByteSlices returns nil, err. Nil array
-// items are stay nil. ByteSlices returns an error if an array item is not a
-// bulk string or nil.
-func ByteSlices(reply interface{}, err error) ([][]byte, error) {
-	if err != nil {
-		return nil, err
-	}
-	switch reply := reply.(type) {
-	case []interface{}:
-		result := make([][]byte, len(reply))
-		for i := range reply {
-			if reply[i] == nil {
-				continue
-			}
-			p, ok := reply[i].([]byte)
-			if !ok {
-				return nil, fmt.Errorf("redigo: unexpected element type for ByteSlices, got type %T", reply[i])
-			}
-			result[i] = p
-		}
-		return result, nil
-	case nil:
-		return nil, ErrNil
-	case Error:
-		return nil, reply
-	}
-	return nil, fmt.Errorf("redigo: unexpected type for ByteSlices, got type %T", reply)
-}
-
-// Ints is a helper that converts an array command reply to a []int. If
-// err is not equal to nil, then Ints returns nil, err.
-func Ints(reply interface{}, err error) ([]int, error) {
-	var ints []int
-	values, err := Values(reply, err)
-	if err != nil {
-		return ints, err
-	}
-	if err := ScanSlice(values, &ints); err != nil {
-		return ints, err
-	}
-	return ints, nil
-}
-
-// StringMap is a helper that converts an array of strings (alternating key, value)
-// into a map[string]string. The HGETALL and CONFIG GET commands return replies in this format.
-// Requires an even number of values in result.
-func StringMap(result interface{}, err error) (map[string]string, error) {
-	values, err := Values(result, err)
-	if err != nil {
-		return nil, err
-	}
-	if len(values)%2 != 0 {
-		return nil, errors.New("redigo: StringMap expects even number of values result")
-	}
-	m := make(map[string]string, len(values)/2)
-	for i := 0; i < len(values); i += 2 {
-		key, okKey := values[i].([]byte)
-		value, okValue := values[i+1].([]byte)
-		if !okKey || !okValue {
-			return nil, errors.New("redigo: ScanMap key not a bulk string value")
-		}
-		m[string(key)] = string(value)
-	}
-	return m, nil
-}
-
-// IntMap is a helper that converts an array of strings (alternating key, value)
-// into a map[string]int. The HGETALL commands return replies in this format.
-// Requires an even number of values in result.
-func IntMap(result interface{}, err error) (map[string]int, error) {
-	values, err := Values(result, err)
-	if err != nil {
-		return nil, err
-	}
-	if len(values)%2 != 0 {
-		return nil, errors.New("redigo: IntMap expects even number of values result")
-	}
-	m := make(map[string]int, len(values)/2)
-	for i := 0; i < len(values); i += 2 {
-		key, ok := values[i].([]byte)
-		if !ok {
-			return nil, errors.New("redigo: ScanMap key not a bulk string value")
-		}
-		value, err := Int(values[i+1], nil)
-		if err != nil {
-			return nil, err
-		}
-		m[string(key)] = value
-	}
-	return m, nil
-}
-
-// Int64Map is a helper that converts an array of strings (alternating key, value)
-// into a map[string]int64. The HGETALL commands return replies in this format.
-// Requires an even number of values in result.
-func Int64Map(result interface{}, err error) (map[string]int64, error) {
-	values, err := Values(result, err)
-	if err != nil {
-		return nil, err
-	}
-	if len(values)%2 != 0 {
-		return nil, errors.New("redigo: Int64Map expects even number of values result")
-	}
-	m := make(map[string]int64, len(values)/2)
-	for i := 0; i < len(values); i += 2 {
-		key, ok := values[i].([]byte)
-		if !ok {
-			return nil, errors.New("redigo: ScanMap key not a bulk string value")
-		}
-		value, err := Int64(values[i+1], nil)
-		if err != nil {
-			return nil, err
-		}
-		m[string(key)] = value
-	}
-	return m, nil
-}

+ 0 - 555
vendor/github.com/garyburd/redigo/redis/scan.go

@@ -1,555 +0,0 @@
-// Copyright 2012 Gary Burd
-//
-// Licensed under the Apache License, Version 2.0 (the "License"): you may
-// not use this file except in compliance with the License. You may obtain
-// a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations
-// under the License.
-
-package redis
-
-import (
-	"errors"
-	"fmt"
-	"reflect"
-	"strconv"
-	"strings"
-	"sync"
-)
-
-func ensureLen(d reflect.Value, n int) {
-	if n > d.Cap() {
-		d.Set(reflect.MakeSlice(d.Type(), n, n))
-	} else {
-		d.SetLen(n)
-	}
-}
-
-func cannotConvert(d reflect.Value, s interface{}) error {
-	var sname string
-	switch s.(type) {
-	case string:
-		sname = "Redis simple string"
-	case Error:
-		sname = "Redis error"
-	case int64:
-		sname = "Redis integer"
-	case []byte:
-		sname = "Redis bulk string"
-	case []interface{}:
-		sname = "Redis array"
-	default:
-		sname = reflect.TypeOf(s).String()
-	}
-	return fmt.Errorf("cannot convert from %s to %s", sname, d.Type())
-}
-
-func convertAssignBulkString(d reflect.Value, s []byte) (err error) {
-	switch d.Type().Kind() {
-	case reflect.Float32, reflect.Float64:
-		var x float64
-		x, err = strconv.ParseFloat(string(s), d.Type().Bits())
-		d.SetFloat(x)
-	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
-		var x int64
-		x, err = strconv.ParseInt(string(s), 10, d.Type().Bits())
-		d.SetInt(x)
-	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
-		var x uint64
-		x, err = strconv.ParseUint(string(s), 10, d.Type().Bits())
-		d.SetUint(x)
-	case reflect.Bool:
-		var x bool
-		x, err = strconv.ParseBool(string(s))
-		d.SetBool(x)
-	case reflect.String:
-		d.SetString(string(s))
-	case reflect.Slice:
-		if d.Type().Elem().Kind() != reflect.Uint8 {
-			err = cannotConvert(d, s)
-		} else {
-			d.SetBytes(s)
-		}
-	default:
-		err = cannotConvert(d, s)
-	}
-	return
-}
-
-func convertAssignInt(d reflect.Value, s int64) (err error) {
-	switch d.Type().Kind() {
-	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
-		d.SetInt(s)
-		if d.Int() != s {
-			err = strconv.ErrRange
-			d.SetInt(0)
-		}
-	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
-		if s < 0 {
-			err = strconv.ErrRange
-		} else {
-			x := uint64(s)
-			d.SetUint(x)
-			if d.Uint() != x {
-				err = strconv.ErrRange
-				d.SetUint(0)
-			}
-		}
-	case reflect.Bool:
-		d.SetBool(s != 0)
-	default:
-		err = cannotConvert(d, s)
-	}
-	return
-}
-
-func convertAssignValue(d reflect.Value, s interface{}) (err error) {
-	switch s := s.(type) {
-	case []byte:
-		err = convertAssignBulkString(d, s)
-	case int64:
-		err = convertAssignInt(d, s)
-	default:
-		err = cannotConvert(d, s)
-	}
-	return err
-}
-
-func convertAssignArray(d reflect.Value, s []interface{}) error {
-	if d.Type().Kind() != reflect.Slice {
-		return cannotConvert(d, s)
-	}
-	ensureLen(d, len(s))
-	for i := 0; i < len(s); i++ {
-		if err := convertAssignValue(d.Index(i), s[i]); err != nil {
-			return err
-		}
-	}
-	return nil
-}
-
-func convertAssign(d interface{}, s interface{}) (err error) {
-	// Handle the most common destination types using type switches and
-	// fall back to reflection for all other types.
-	switch s := s.(type) {
-	case nil:
-		// ingore
-	case []byte:
-		switch d := d.(type) {
-		case *string:
-			*d = string(s)
-		case *int:
-			*d, err = strconv.Atoi(string(s))
-		case *bool:
-			*d, err = strconv.ParseBool(string(s))
-		case *[]byte:
-			*d = s
-		case *interface{}:
-			*d = s
-		case nil:
-			// skip value
-		default:
-			if d := reflect.ValueOf(d); d.Type().Kind() != reflect.Ptr {
-				err = cannotConvert(d, s)
-			} else {
-				err = convertAssignBulkString(d.Elem(), s)
-			}
-		}
-	case int64:
-		switch d := d.(type) {
-		case *int:
-			x := int(s)
-			if int64(x) != s {
-				err = strconv.ErrRange
-				x = 0
-			}
-			*d = x
-		case *bool:
-			*d = s != 0
-		case *interface{}:
-			*d = s
-		case nil:
-			// skip value
-		default:
-			if d := reflect.ValueOf(d); d.Type().Kind() != reflect.Ptr {
-				err = cannotConvert(d, s)
-			} else {
-				err = convertAssignInt(d.Elem(), s)
-			}
-		}
-	case string:
-		switch d := d.(type) {
-		case *string:
-			*d = string(s)
-		default:
-			err = cannotConvert(reflect.ValueOf(d), s)
-		}
-	case []interface{}:
-		switch d := d.(type) {
-		case *[]interface{}:
-			*d = s
-		case *interface{}:
-			*d = s
-		case nil:
-			// skip value
-		default:
-			if d := reflect.ValueOf(d); d.Type().Kind() != reflect.Ptr {
-				err = cannotConvert(d, s)
-			} else {
-				err = convertAssignArray(d.Elem(), s)
-			}
-		}
-	case Error:
-		err = s
-	default:
-		err = cannotConvert(reflect.ValueOf(d), s)
-	}
-	return
-}
-
-// Scan copies from src to the values pointed at by dest.
-//
-// The values pointed at by dest must be an integer, float, boolean, string,
-// []byte, interface{} or slices of these types. Scan uses the standard strconv
-// package to convert bulk strings to numeric and boolean types.
-//
-// If a dest value is nil, then the corresponding src value is skipped.
-//
-// If a src element is nil, then the corresponding dest value is not modified.
-//
-// To enable easy use of Scan in a loop, Scan returns the slice of src
-// following the copied values.
-func Scan(src []interface{}, dest ...interface{}) ([]interface{}, error) {
-	if len(src) < len(dest) {
-		return nil, errors.New("redigo.Scan: array short")
-	}
-	var err error
-	for i, d := range dest {
-		err = convertAssign(d, src[i])
-		if err != nil {
-			err = fmt.Errorf("redigo.Scan: cannot assign to dest %d: %v", i, err)
-			break
-		}
-	}
-	return src[len(dest):], err
-}
-
-type fieldSpec struct {
-	name      string
-	index     []int
-	omitEmpty bool
-}
-
-type structSpec struct {
-	m map[string]*fieldSpec
-	l []*fieldSpec
-}
-
-func (ss *structSpec) fieldSpec(name []byte) *fieldSpec {
-	return ss.m[string(name)]
-}
-
-func compileStructSpec(t reflect.Type, depth map[string]int, index []int, ss *structSpec) {
-	for i := 0; i < t.NumField(); i++ {
-		f := t.Field(i)
-		switch {
-		case f.PkgPath != "" && !f.Anonymous:
-			// Ignore unexported fields.
-		case f.Anonymous:
-			// TODO: Handle pointers. Requires change to decoder and
-			// protection against infinite recursion.
-			if f.Type.Kind() == reflect.Struct {
-				compileStructSpec(f.Type, depth, append(index, i), ss)
-			}
-		default:
-			fs := &fieldSpec{name: f.Name}
-			tag := f.Tag.Get("redis")
-			p := strings.Split(tag, ",")
-			if len(p) > 0 {
-				if p[0] == "-" {
-					continue
-				}
-				if len(p[0]) > 0 {
-					fs.name = p[0]
-				}
-				for _, s := range p[1:] {
-					switch s {
-					case "omitempty":
-						fs.omitEmpty = true
-					default:
-						panic(fmt.Errorf("redigo: unknown field tag %s for type %s", s, t.Name()))
-					}
-				}
-			}
-			d, found := depth[fs.name]
-			if !found {
-				d = 1 << 30
-			}
-			switch {
-			case len(index) == d:
-				// At same depth, remove from result.
-				delete(ss.m, fs.name)
-				j := 0
-				for i := 0; i < len(ss.l); i++ {
-					if fs.name != ss.l[i].name {
-						ss.l[j] = ss.l[i]
-						j += 1
-					}
-				}
-				ss.l = ss.l[:j]
-			case len(index) < d:
-				fs.index = make([]int, len(index)+1)
-				copy(fs.index, index)
-				fs.index[len(index)] = i
-				depth[fs.name] = len(index)
-				ss.m[fs.name] = fs
-				ss.l = append(ss.l, fs)
-			}
-		}
-	}
-}
-
-var (
-	structSpecMutex  sync.RWMutex
-	structSpecCache  = make(map[reflect.Type]*structSpec)
-	defaultFieldSpec = &fieldSpec{}
-)
-
-func structSpecForType(t reflect.Type) *structSpec {
-
-	structSpecMutex.RLock()
-	ss, found := structSpecCache[t]
-	structSpecMutex.RUnlock()
-	if found {
-		return ss
-	}
-
-	structSpecMutex.Lock()
-	defer structSpecMutex.Unlock()
-	ss, found = structSpecCache[t]
-	if found {
-		return ss
-	}
-
-	ss = &structSpec{m: make(map[string]*fieldSpec)}
-	compileStructSpec(t, make(map[string]int), nil, ss)
-	structSpecCache[t] = ss
-	return ss
-}
-
-var errScanStructValue = errors.New("redigo.ScanStruct: value must be non-nil pointer to a struct")
-
-// ScanStruct scans alternating names and values from src to a struct. The
-// HGETALL and CONFIG GET commands return replies in this format.
-//
-// ScanStruct uses exported field names to match values in the response. Use
-// 'redis' field tag to override the name:
-//
-//      Field int `redis:"myName"`
-//
-// Fields with the tag redis:"-" are ignored.
-//
-// Integer, float, boolean, string and []byte fields are supported. Scan uses the
-// standard strconv package to convert bulk string values to numeric and
-// boolean types.
-//
-// If a src element is nil, then the corresponding field is not modified.
-func ScanStruct(src []interface{}, dest interface{}) error {
-	d := reflect.ValueOf(dest)
-	if d.Kind() != reflect.Ptr || d.IsNil() {
-		return errScanStructValue
-	}
-	d = d.Elem()
-	if d.Kind() != reflect.Struct {
-		return errScanStructValue
-	}
-	ss := structSpecForType(d.Type())
-
-	if len(src)%2 != 0 {
-		return errors.New("redigo.ScanStruct: number of values not a multiple of 2")
-	}
-
-	for i := 0; i < len(src); i += 2 {
-		s := src[i+1]
-		if s == nil {
-			continue
-		}
-		name, ok := src[i].([]byte)
-		if !ok {
-			return fmt.Errorf("redigo.ScanStruct: key %d not a bulk string value", i)
-		}
-		fs := ss.fieldSpec(name)
-		if fs == nil {
-			continue
-		}
-		if err := convertAssignValue(d.FieldByIndex(fs.index), s); err != nil {
-			return fmt.Errorf("redigo.ScanStruct: cannot assign field %s: %v", fs.name, err)
-		}
-	}
-	return nil
-}
-
-var (
-	errScanSliceValue = errors.New("redigo.ScanSlice: dest must be non-nil pointer to a struct")
-)
-
-// ScanSlice scans src to the slice pointed to by dest. The elements the dest
-// slice must be integer, float, boolean, string, struct or pointer to struct
-// values.
-//
-// Struct fields must be integer, float, boolean or string values. All struct
-// fields are used unless a subset is specified using fieldNames.
-func ScanSlice(src []interface{}, dest interface{}, fieldNames ...string) error {
-	d := reflect.ValueOf(dest)
-	if d.Kind() != reflect.Ptr || d.IsNil() {
-		return errScanSliceValue
-	}
-	d = d.Elem()
-	if d.Kind() != reflect.Slice {
-		return errScanSliceValue
-	}
-
-	isPtr := false
-	t := d.Type().Elem()
-	if t.Kind() == reflect.Ptr && t.Elem().Kind() == reflect.Struct {
-		isPtr = true
-		t = t.Elem()
-	}
-
-	if t.Kind() != reflect.Struct {
-		ensureLen(d, len(src))
-		for i, s := range src {
-			if s == nil {
-				continue
-			}
-			if err := convertAssignValue(d.Index(i), s); err != nil {
-				return fmt.Errorf("redigo.ScanSlice: cannot assign element %d: %v", i, err)
-			}
-		}
-		return nil
-	}
-
-	ss := structSpecForType(t)
-	fss := ss.l
-	if len(fieldNames) > 0 {
-		fss = make([]*fieldSpec, len(fieldNames))
-		for i, name := range fieldNames {
-			fss[i] = ss.m[name]
-			if fss[i] == nil {
-				return fmt.Errorf("redigo.ScanSlice: ScanSlice bad field name %s", name)
-			}
-		}
-	}
-
-	if len(fss) == 0 {
-		return errors.New("redigo.ScanSlice: no struct fields")
-	}
-
-	n := len(src) / len(fss)
-	if n*len(fss) != len(src) {
-		return errors.New("redigo.ScanSlice: length not a multiple of struct field count")
-	}
-
-	ensureLen(d, n)
-	for i := 0; i < n; i++ {
-		d := d.Index(i)
-		if isPtr {
-			if d.IsNil() {
-				d.Set(reflect.New(t))
-			}
-			d = d.Elem()
-		}
-		for j, fs := range fss {
-			s := src[i*len(fss)+j]
-			if s == nil {
-				continue
-			}
-			if err := convertAssignValue(d.FieldByIndex(fs.index), s); err != nil {
-				return fmt.Errorf("redigo.ScanSlice: cannot assign element %d to field %s: %v", i*len(fss)+j, fs.name, err)
-			}
-		}
-	}
-	return nil
-}
-
-// Args is a helper for constructing command arguments from structured values.
-type Args []interface{}
-
-// Add returns the result of appending value to args.
-func (args Args) Add(value ...interface{}) Args {
-	return append(args, value...)
-}
-
-// AddFlat returns the result of appending the flattened value of v to args.
-//
-// Maps are flattened by appending the alternating keys and map values to args.
-//
-// Slices are flattened by appending the slice elements to args.
-//
-// Structs are flattened by appending the alternating names and values of
-// exported fields to args. If v is a nil struct pointer, then nothing is
-// appended. The 'redis' field tag overrides struct field names. See ScanStruct
-// for more information on the use of the 'redis' field tag.
-//
-// Other types are appended to args as is.
-func (args Args) AddFlat(v interface{}) Args {
-	rv := reflect.ValueOf(v)
-	switch rv.Kind() {
-	case reflect.Struct:
-		args = flattenStruct(args, rv)
-	case reflect.Slice:
-		for i := 0; i < rv.Len(); i++ {
-			args = append(args, rv.Index(i).Interface())
-		}
-	case reflect.Map:
-		for _, k := range rv.MapKeys() {
-			args = append(args, k.Interface(), rv.MapIndex(k).Interface())
-		}
-	case reflect.Ptr:
-		if rv.Type().Elem().Kind() == reflect.Struct {
-			if !rv.IsNil() {
-				args = flattenStruct(args, rv.Elem())
-			}
-		} else {
-			args = append(args, v)
-		}
-	default:
-		args = append(args, v)
-	}
-	return args
-}
-
-func flattenStruct(args Args, v reflect.Value) Args {
-	ss := structSpecForType(v.Type())
-	for _, fs := range ss.l {
-		fv := v.FieldByIndex(fs.index)
-		if fs.omitEmpty {
-			var empty = false
-			switch fv.Kind() {
-			case reflect.Array, reflect.Map, reflect.Slice, reflect.String:
-				empty = fv.Len() == 0
-			case reflect.Bool:
-				empty = !fv.Bool()
-			case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
-				empty = fv.Int() == 0
-			case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
-				empty = fv.Uint() == 0
-			case reflect.Float32, reflect.Float64:
-				empty = fv.Float() == 0
-			case reflect.Interface, reflect.Ptr:
-				empty = fv.IsNil()
-			}
-			if empty {
-				continue
-			}
-		}
-		args = append(args, fs.name, fv.Interface())
-	}
-	return args
-}

+ 0 - 86
vendor/github.com/garyburd/redigo/redis/script.go

@@ -1,86 +0,0 @@
-// Copyright 2012 Gary Burd
-//
-// Licensed under the Apache License, Version 2.0 (the "License"): you may
-// not use this file except in compliance with the License. You may obtain
-// a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations
-// under the License.
-
-package redis
-
-import (
-	"crypto/sha1"
-	"encoding/hex"
-	"io"
-	"strings"
-)
-
-// Script encapsulates the source, hash and key count for a Lua script. See
-// http://redis.io/commands/eval for information on scripts in Redis.
-type Script struct {
-	keyCount int
-	src      string
-	hash     string
-}
-
-// NewScript returns a new script object. If keyCount is greater than or equal
-// to zero, then the count is automatically inserted in the EVAL command
-// argument list. If keyCount is less than zero, then the application supplies
-// the count as the first value in the keysAndArgs argument to the Do, Send and
-// SendHash methods.
-func NewScript(keyCount int, src string) *Script {
-	h := sha1.New()
-	io.WriteString(h, src)
-	return &Script{keyCount, src, hex.EncodeToString(h.Sum(nil))}
-}
-
-func (s *Script) args(spec string, keysAndArgs []interface{}) []interface{} {
-	var args []interface{}
-	if s.keyCount < 0 {
-		args = make([]interface{}, 1+len(keysAndArgs))
-		args[0] = spec
-		copy(args[1:], keysAndArgs)
-	} else {
-		args = make([]interface{}, 2+len(keysAndArgs))
-		args[0] = spec
-		args[1] = s.keyCount
-		copy(args[2:], keysAndArgs)
-	}
-	return args
-}
-
-// Do evaluates the script. Under the covers, Do optimistically evaluates the
-// script using the EVALSHA command. If the command fails because the script is
-// not loaded, then Do evaluates the script using the EVAL command (thus
-// causing the script to load).
-func (s *Script) Do(c Conn, keysAndArgs ...interface{}) (interface{}, error) {
-	v, err := c.Do("EVALSHA", s.args(s.hash, keysAndArgs)...)
-	if e, ok := err.(Error); ok && strings.HasPrefix(string(e), "NOSCRIPT ") {
-		v, err = c.Do("EVAL", s.args(s.src, keysAndArgs)...)
-	}
-	return v, err
-}
-
-// SendHash evaluates the script without waiting for the reply. The script is
-// evaluated with the EVALSHA command. The application must ensure that the
-// script is loaded by a previous call to Send, Do or Load methods.
-func (s *Script) SendHash(c Conn, keysAndArgs ...interface{}) error {
-	return c.Send("EVALSHA", s.args(s.hash, keysAndArgs)...)
-}
-
-// Send evaluates the script without waiting for the reply.
-func (s *Script) Send(c Conn, keysAndArgs ...interface{}) error {
-	return c.Send("EVAL", s.args(s.src, keysAndArgs)...)
-}
-
-// Load loads the script without evaluating it.
-func (s *Script) Load(c Conn) error {
-	_, err := c.Do("SCRIPT", "LOAD", s.src)
-	return err
-}

+ 0 - 5
vendor/vendor.json

@@ -167,11 +167,6 @@
 			"path": "github.com/garyburd/redigo/internal",
 			"revision": ""
 		},
-		{
-			"checksumSHA1": "KE392Hc4MV45QsKzzXKNIFlZK6M=",
-			"path": "github.com/garyburd/redigo/redis",
-			"revision": ""
-		},
 		{
 			"checksumSHA1": "q/AaJa/6c+YxodimOaMK7AMAWNo=",
 			"origin": "github.com/iris-contrib/httpexpect/vendor/github.com/gavv/monotime",