forked from server-nado/orm
/
cache_driver_redis.go
174 lines (160 loc) · 4.18 KB
/
cache_driver_redis.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
package orm
import (
"errors"
"reflect"
"time"
"github.com/garyburd/redigo/redis"
)
var Pool *redis.Pool = nil
func NewRedisCacheWithRedisPool(pool *redis.Pool) *RedisCache {
return &RedisCache{pool}
}
func SetCacheWithPool(pool *redis.Pool) {
cacheconn = &RedisCache{pool}
}
func GetCachePool() Cache {
return cacheconn
}
// 新建 Redis 连接
func NewRedisCache(REDIS_HOST, PASSWD string) *RedisCache {
Pool = &redis.Pool{
MaxIdle: 30, //最大的空闲连接数,表示即使没有redis连接时依然可以保持N个空闲的连接,而不被清除,随时处于待命状态。
MaxActive: 300, //最大的激活连接数,表示同时最多有N个连接
IdleTimeout: 30 * time.Second, //最大的空闲连接等待时间,超过此时间后,空闲连接将被关闭
Dial: func() (redis.Conn, error) {
c, err := redis.Dial("tcp", REDIS_HOST)
if err != nil {
return nil, err
}
if PASSWD != "" && len(PASSWD) > 0 {
if _, err := c.Do("AUTH", PASSWD); err != nil {
c.Close()
return nil, err
}
}
// 选择db
c.Do("SELECT", cache_db)
return c, nil
},
TestOnBorrow: func(c redis.Conn, t time.Time) error {
_, err := c.Do("PING")
return err
},
}
return &RedisCache{Pool}
}
type RedisCache struct {
*redis.Pool
}
func (c *RedisCache) ConnGet() redis.Conn {
return c.Pool.Get()
}
func (c *RedisCache) Set(key string, b []byte) (err error) {
conn := c.ConnGet()
defer conn.Close()
_, err = conn.Do("SET", key, b)
return
}
func (c *RedisCache) Get(key string) ([]byte, error) {
conn := c.ConnGet()
defer conn.Close()
return redis.Bytes(conn.Do("GET", key))
}
func (c *RedisCache) Keys(key string) (keys []string, err error) {
conn := c.ConnGet()
defer conn.Close()
keys, err = redis.Strings(conn.Do("KEYS", key))
return
}
func (c *RedisCache) Incrby(key string, n int64) (int64, error) {
conn := c.ConnGet()
defer conn.Close()
if n == 0 {
return redis.Int64(conn.Do("GET", key))
}
return redis.Int64(conn.Do("INCRBY", key, n))
}
func (c *RedisCache) Hset(key, field string, b []byte) (bool, error) {
conn := c.ConnGet()
defer conn.Close()
_, err := conn.Do("HSET", key, field, b)
if err != nil {
return false, err
} else {
return true, nil
}
}
func (c *RedisCache) Hmset(key string, maping interface{}) (err error) {
switch maping.(type) {
case map[string]interface{}:
conn := c.ConnGet()
defer conn.Close()
conn.Do("MULTI")
for k, v := range maping.(map[string]interface{}) {
//setings = append(setings, k, v)
conn.Do("HSET", key, k, v)
//Debug.Println(key, k, v)
}
_, err = conn.Do("EXEC")
default:
Error.Println(err)
err = errors.New("Hmset maping type error ")
}
return
}
func (c *RedisCache) Hget(key, field string) ([]byte, error) {
conn := c.ConnGet()
defer conn.Close()
return redis.Bytes(conn.Do("HGET", key, field))
}
func (c *RedisCache) Hincrby(key, field string, n int64) (int64, error) {
conn := c.ConnGet()
defer conn.Close()
if n == 0 {
return redis.Int64(conn.Do("HGET", key, field))
}
return redis.Int64(conn.Do("HINCRBY", key, field, n))
}
func (c *RedisCache) Exists(key string) (bool, error) {
conn := c.ConnGet()
defer conn.Close()
return redis.Bool(conn.Do("EXISTS", key))
}
func (c *RedisCache) Del(key string) (bool, error) {
conn := c.ConnGet()
defer conn.Close()
return redis.Bool(conn.Do("DEL", key))
}
func (c *RedisCache) key2Mode(key string, typ reflect.Type, val reflect.Value) error {
conn := c.ConnGet()
defer conn.Close()
conn.Send("MULTI")
vals := []interface{}{}
timeField := []int{}
for i := 0; i < typ.NumField(); i++ {
conn.Send("HGET", key, typ.Field(i).Name)
switch val.Field(i).Interface().(type) {
case time.Time:
timeField = append(timeField, i)
var str string
vals = append(vals, &str)
default:
vals = append(vals, val.Field(i).Addr().Interface())
}
}
reply, err := redis.Values(conn.Do("EXEC"))
if err != nil {
return err
}
if _, err := redis.Scan(reply, vals...); err == nil {
var n int
for _, n = range timeField {
if time, e := time.Parse(time.RFC1123Z, string(reply[n].([]byte))); e == nil {
val.Field(n).Set(reflect.ValueOf(time))
}
}
return nil
} else {
return err
}
}