|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324 |
- package cache
-
- import (
- "errors"
- "log"
- "strings"
- "time"
-
- redigo "github.com/gomodule/redigo/redis"
- )
-
- type RedisPool struct {
- *redigo.Pool
- }
-
- func NewRedisPool(cfg *Config) *RedisPool {
- return &RedisPool{&redigo.Pool{
- MaxIdle: cfg.MaxIdle,
- IdleTimeout: cfg.IdleTimeout,
- MaxActive: cfg.MaxActive,
- Wait: cfg.Wait,
- Dial: func() (redigo.Conn, error) {
- c, err := redigo.Dial("tcp", cfg.Server)
- if err != nil {
- log.Println("Redis Dial failed: ", err)
- return nil, err
- }
- if cfg.Password != "" {
- if _, err := c.Do("AUTH", cfg.Password); err != nil {
- c.Close()
- log.Println("Redis AUTH failed: ", err)
- return nil, err
- }
- }
- return c, err
- },
- TestOnBorrow: func(c redigo.Conn, t time.Time) error {
- _, err := c.Do("PING")
- if err != nil {
- log.Println("Unable to ping to redis server:", err)
- }
- return err
- },
- }}
- }
-
- func (p *RedisPool) Do(cmd string, args ...interface{}) (reply interface{}, err error) {
- conn := pool.Get()
- defer conn.Close()
- return conn.Do(cmd, args...)
- }
-
- func (p *RedisPool) GetPool() *redigo.Pool {
- return pool
- }
-
- func (p *RedisPool) ParseKey(key string, vars []string) (string, error) {
- arr := strings.Split(key, conf.KeyPlaceholder)
- actualKey := ""
- if len(arr) != len(vars)+1 {
- return "", errors.New("redis/connection.go: Insufficient arguments to parse key")
- } else {
- for index, val := range arr {
- if index == 0 {
- actualKey = arr[index]
- } else {
- actualKey += vars[index-1] + val
- }
- }
- }
- return getPrefixedKey(actualKey), nil
- }
-
- func (p *RedisPool) getPrefixedKey(key string) string {
- return conf.KeyPrefix + conf.KeyDelimiter + key
- }
- func (p *RedisPool) StripEnvKey(key string) string {
- return strings.TrimLeft(key, conf.KeyPrefix+conf.KeyDelimiter)
- }
- func (p *RedisPool) SplitKey(key string) []string {
- return strings.Split(key, conf.KeyDelimiter)
- }
- func (p *RedisPool) Expire(key string, ttl int) (interface{}, error) {
- return Do("EXPIRE", key, ttl)
- }
- func (p *RedisPool) Persist(key string) (interface{}, error) {
- return Do("PERSIST", key)
- }
-
- func (p *RedisPool) Del(key string) (interface{}, error) {
- return Do("DEL", key)
- }
- func (p *RedisPool) Set(key string, data interface{}) (interface{}, error) {
- // set
- return Do("SET", key, data)
- }
- func (p *RedisPool) SetNX(key string, data interface{}) (interface{}, error) {
- return Do("SETNX", key, data)
- }
- func (p *RedisPool) SetEx(key string, data interface{}, ttl int) (interface{}, error) {
- return Do("SETEX", key, ttl, data)
- }
- func (p *RedisPool) Get(key string) (interface{}, error) {
- // get
- return Do("GET", key)
- }
- func (p *RedisPool) GetStringMap(key string) (map[string]string, error) {
- // get
- return redigo.StringMap(Do("GET", key))
- }
-
- func (p *RedisPool) GetTTL(key string) (time.Duration, error) {
- ttl, err := redigo.Int64(Do("TTL", key))
- return time.Duration(ttl) * time.Second, err
- }
- func (p *RedisPool) GetBytes(key string) ([]byte, error) {
- return redigo.Bytes(Do("GET", key))
- }
- func (p *RedisPool) GetString(key string) (string, error) {
- return redigo.String(Do("GET", key))
- }
- func (p *RedisPool) GetInt(key string) (int, error) {
- return redigo.Int(Do("GET", key))
- }
- func (p *RedisPool) GetStringLength(key string) (int, error) {
- return redigo.Int(Do("STRLEN", key))
- }
- func (p *RedisPool) ZAdd(key string, score float64, data interface{}) (interface{}, error) {
- return Do("ZADD", key, score, data)
- }
- func (p *RedisPool) ZRem(key string, data interface{}) (interface{}, error) {
- return Do("ZREM", key, data)
- }
- func (p *RedisPool) ZRange(key string, start int, end int, withScores bool) ([]interface{}, error) {
- if withScores {
- return redigo.Values(Do("ZRANGE", key, start, end, "WITHSCORES"))
- }
- return redigo.Values(Do("ZRANGE", key, start, end))
- }
- func (p *RedisPool) SAdd(setName string, data interface{}) (interface{}, error) {
- return Do("SADD", setName, data)
- }
- func (p *RedisPool) SCard(setName string) (int64, error) {
- return redigo.Int64(Do("SCARD", setName))
- }
- func (p *RedisPool) SIsMember(setName string, data interface{}) (bool, error) {
- return redigo.Bool(Do("SISMEMBER", setName, data))
- }
- func (p *RedisPool) SMembers(setName string) ([]string, error) {
- return redigo.Strings(Do("SMEMBERS", setName))
- }
- func (p *RedisPool) SRem(setName string, data interface{}) (interface{}, error) {
- return Do("SREM", setName, data)
- }
- func (p *RedisPool) HSet(key string, HKey string, data interface{}) (interface{}, error) {
- return Do("HSET", key, HKey, data)
- }
-
- func (p *RedisPool) HGet(key string, HKey string) (interface{}, error) {
- return Do("HGET", key, HKey)
- }
-
- func (p *RedisPool) HMGet(key string, hashKeys ...string) ([]interface{}, error) {
- ret, err := Do("HMGET", key, hashKeys)
- if err != nil {
- return nil, err
- }
- reta, ok := ret.([]interface{})
- if !ok {
- return nil, errors.New("result not an array")
- }
- return reta, nil
- }
-
- func (p *RedisPool) HMSet(key string, hashKeys []string, vals []interface{}) (interface{}, error) {
- if len(hashKeys) == 0 || len(hashKeys) != len(vals) {
- var ret interface{}
- return ret, errors.New("bad length")
- }
- input := []interface{}{key}
- for i, v := range hashKeys {
- input = append(input, v, vals[i])
- }
- return Do("HMSET", input...)
- }
-
- func (p *RedisPool) HGetString(key string, HKey string) (string, error) {
- return redigo.String(Do("HGET", key, HKey))
- }
- func (p *RedisPool) HGetFloat(key string, HKey string) (float64, error) {
- f, err := redigo.Float64(Do("HGET", key, HKey))
- return float64(f), err
- }
- func (p *RedisPool) HGetInt(key string, HKey string) (int, error) {
- return redigo.Int(Do("HGET", key, HKey))
- }
- func (p *RedisPool) HGetInt64(key string, HKey string) (int64, error) {
- return redigo.Int64(Do("HGET", key, HKey))
- }
- func (p *RedisPool) HGetBool(key string, HKey string) (bool, error) {
- return redigo.Bool(Do("HGET", key, HKey))
- }
- func (p *RedisPool) HDel(key string, HKey string) (interface{}, error) {
- return Do("HDEL", key, HKey)
- }
- func (p *RedisPool) HGetAll(key string) (map[string]interface{}, error) {
- vals, err := redigo.Values(Do("HGETALL", key))
- if err != nil {
- return nil, err
- }
- num := len(vals) / 2
- result := make(map[string]interface{}, num)
- for i := 0; i < num; i++ {
- key, _ := redigo.String(vals[2*i], nil)
- result[key] = vals[2*i+1]
- }
- return result, nil
- }
-
- // NOTE: Use this in production environment with extreme care.
- // Read more here:https://redigo.io/commands/keys
- func (p *RedisPool) Keys(pattern string) ([]string, error) {
- return redigo.Strings(Do("KEYS", pattern))
- }
-
- func (p *RedisPool) HKeys(key string) ([]string, error) {
- return redigo.Strings(Do("HKEYS", key))
- }
-
- func (p *RedisPool) Exists(key string) (bool, error) {
- count, err := redigo.Int(Do("EXISTS", key))
- if count == 0 {
- return false, err
- } else {
- return true, err
- }
- }
-
- func (p *RedisPool) Incr(key string) (int64, error) {
- return redigo.Int64(Do("INCR", key))
- }
-
- func (p *RedisPool) Decr(key string) (int64, error) {
- return redigo.Int64(Do("DECR", key))
- }
-
- func (p *RedisPool) IncrBy(key string, incBy int64) (int64, error) {
- return redigo.Int64(Do("INCRBY", key, incBy))
- }
-
- func (p *RedisPool) DecrBy(key string, decrBy int64) (int64, error) {
- return redigo.Int64(Do("DECRBY", key))
- }
-
- func (p *RedisPool) IncrByFloat(key string, incBy float64) (float64, error) {
- return redigo.Float64(Do("INCRBYFLOAT", key, incBy))
- }
-
- func (p *RedisPool) DecrByFloat(key string, decrBy float64) (float64, error) {
- return redigo.Float64(Do("DECRBYFLOAT", key, decrBy))
- }
-
- // use for message queue
- func (p *RedisPool) LPush(key string, data interface{}) (interface{}, error) {
- // set
- return Do("LPUSH", key, data)
- }
-
- func (p *RedisPool) LPop(key string) (interface{}, error) {
- return Do("LPOP", key)
- }
-
- func (p *RedisPool) LPopString(key string) (string, error) {
- return redigo.String(Do("LPOP", key))
- }
- func (p *RedisPool) LPopFloat(key string) (float64, error) {
- f, err := redigo.Float64(Do("LPOP", key))
- return float64(f), err
- }
- func (p *RedisPool) LPopInt(key string) (int, error) {
- return redigo.Int(Do("LPOP", key))
- }
- func (p *RedisPool) LPopInt64(key string) (int64, error) {
- return redigo.Int64(Do("LPOP", key))
- }
-
- func (p *RedisPool) RPush(key string, data interface{}) (interface{}, error) {
- // set
- return Do("RPUSH", key, data)
- }
-
- func (p *RedisPool) RPop(key string) (interface{}, error) {
- return Do("RPOP", key)
- }
-
- func (p *RedisPool) RPopString(key string) (string, error) {
- return redigo.String(Do("RPOP", key))
- }
- func (p *RedisPool) RPopFloat(key string) (float64, error) {
- f, err := redigo.Float64(Do("RPOP", key))
- return float64(f), err
- }
- func (p *RedisPool) RPopInt(key string) (int, error) {
- return redigo.Int(Do("RPOP", key))
- }
- func (p *RedisPool) RPopInt64(key string) (int64, error) {
- return redigo.Int64(Do("RPOP", key))
- }
-
- func (p *RedisPool) Scan(cursor int64, pattern string, count int64) (int64, []string, error) {
- var items []string
- var newCursor int64
-
- values, err := redigo.Values(Do("SCAN", cursor, "MATCH", pattern, "COUNT", count))
- if err != nil {
- return 0, nil, err
- }
- values, err = redigo.Scan(values, &newCursor, &items)
- if err != nil {
- return 0, nil, err
- }
-
- return newCursor, items, nil
- }
|