Fetch the repository succeeded.
package hc
import (
"strconv"
"time"
"github.com/gomodule/redigo/redis"
)
// ErrNil reids的ErrNil
var ErrNil = redis.ErrNil
// RedisPool redis连接池
type RedisPool struct {
Pool *redis.Pool
}
// RedisArgs redis.Args类型的别名
type RedisArgs = redis.Args
// Redis 存放redis连接池的变量
var Redis *RedisPool
// RedisConn Redis连接
func RedisConn(host, port, password string, maxIDle, maxActive int) error {
Redis = &RedisPool{}
return Redis.initPool(host, port, password, maxIDle, maxActive)
}
// InitPool 新建连接池
func (p *RedisPool) initPool(host, port, password string, maxIDle, maxActive int) error {
p.Pool = &redis.Pool{
MaxIdle: maxIDle, // 最大空闲链接
MaxActive: maxActive, // 最大链接
IdleTimeout: 240 * time.Second, // 空闲链接超时
Wait: true, // 当连接池耗尽时,是否阻塞等待
Dial: func() (redis.Conn, error) {
// password 没有密码时password使用空字符串
c, err := redis.Dial("tcp", host+":"+port, redis.DialPassword(password))
if err != nil {
return nil, err
}
return c, nil
},
TestOnBorrow: func(c redis.Conn, t time.Time) error { // 健康检查,如果ping出错了,就关闭这个redis连接
if time.Since(t) < time.Minute { // 每分钟定时检查
return nil
}
_, err := c.Do("PING")
return err
},
}
// 检查redis是否连接有误
_, err := p.Pool.Dial()
return err
}
// do 执行redis命令
func (p *RedisPool) do(command string, args ...interface{}) (interface{}, error) {
conn := p.Pool.Get()
defer conn.Close()
return conn.Do(command, args...)
}
// EXPIRE 设置key的有效期
func (p *RedisPool) EXPIRE(key string, seconds int) error {
_, err := p.do("EXPIRE", key, seconds)
return err
}
// DEL 删除一个key
func (p *RedisPool) DEL(key string) error {
_, err := p.do("DEL", key)
return err
}
// EXISTS 检查一个建是否存在
func (p *RedisPool) EXISTS(key string) (bool, error) {
exists, err := redis.Bool(p.do("EXISTS", key))
return exists, err
}
//-------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------- string ----------------------------------------------------//
// GET 返回与键 key 相关联的字符串值。
func (p *RedisPool) GET(key string) (value string, err error) {
value, err = redis.String(p.do("GET", key))
return
}
// SET 将字符串值 value 关联到 key 。
// 如果 key 已经持有其他值, SET 就覆写旧值, 无视类型。 特别注意:无视类型覆盖
// 当 SET 命令对一个带有生存时间(TTL)的键进行设置之后, 该键原有的 TTL 将被清除。
func (p *RedisPool) SET(key, value string) error {
_, err := p.do("SET", key, value)
return err
}
// INCR 为键 key 储存的数字值加上一。
// 如果键 key 不存在, 那么它的值会先被初始化为 0 , 然后再执行 INCR 命令。
// 如果键 key 储存的值不能被解释为数字, 那么 INCR 命令将返回一个错误。
// 本操作的值限制在 64 位(bit)有符号数字表示之内。
// 返回值: INCR 命令会返回键 key 在执行加一操作之后的值。
func (p *RedisPool) INCR(key string) (value int64, err error) {
value, err = redis.Int64(p.do("INCR", key))
return
}
// INCRBY 为键 key 储存的数字值加上增量 increment 。
// 如果键 key 不存在, 那么键 key 的值会先被初始化为 0 , 然后再执行 INCRBY 命令。
// 如果键 key 储存的值不能被解释为数字, 那么 INCRBY 命令将返回一个错误。
// 本操作的值限制在 64 位(bit)有符号数字表示之内。
// 返回值: 在加上增量 increment 之后, 键 key 的值。
func (p *RedisPool) INCRBY(key string, increment int64) (value int64, err error) {
value, err = redis.Int64(p.do("INCRBY", key, increment))
return
}
// INCRBYFLOAT 为键 key 储存的值加上浮点数增量 increment 。
// 如果键 key 不存在, 那么 INCRBYFLOAT 会先将键 key 的值设为 0 , 然后再执行加法操作。
// 如果命令执行成功, 那么键 key 的值会被更新为执行加法计算之后的新值, 并且新值会以字符串的形式返回给调用者。
// 无论加法计算所得的浮点数的实际精度有多长, INCRBYFLOAT 命令的计算结果最多只保留小数点的后十七位。
// 当以下任意一个条件发生时, 命令返回一个错误:
// 键 key 的值不是字符串类型(因为 Redis 中的数字和浮点数都以字符串的形式保存,所以它们都属于字符串类型);
// 1.键 key 当前的值或者给定的增量 increment 不能被解释(parse)为双精度浮点数。
//
// 本操作的值限制在 64 位(bit)有符号数字表示之内。
// 返回值: 在加上增量 increment 之后, 键 key 的值。
func (p *RedisPool) INCRBYFLOAT(key string, increment float64) (value float64, err error) {
value, err = redis.Float64(p.do("INCRBYFLOAT", key, increment))
return
}
//-------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------- hash ----------------------------------------------------//
// HSET 作同时将多个 field-value (域-值)对设置到哈希表 key 中
// 此命令会覆盖哈希表中已存在的域
func (p *RedisPool) HSET(key string, fieldValue interface{}) (err error) {
args := redis.Args{key}.AddFlat(fieldValue)
_, err = p.do("HSET", args...)
return
}
// HGET 返回哈希表中给定域的值。
func (p *RedisPool) HGET(key, field string) (value string, err error) {
value, err = redis.String(p.do("HGET", key, field))
return
}
// HGETALL 返回哈希表 key 中,所有的域和值,并赋值给out(out是一个结构体的指针)
// out 字段使用"redis" tag 作匹配
func (p *RedisPool) HGETALL(key string, out interface{}) (err error) {
res, err := redis.Values(p.do("HGETALL", key))
if err != nil {
return
}
if len(res) == 0 {
return
}
err = redis.ScanStruct(res, out)
return
}
// HMGET 返回哈希表 key 中,一个或多个给定域的值。
// 如果给定的域不存在于哈希表,那么返回一个 nil 值。
// 因为不存在的 key 被当作一个空哈希表来处理,所以对一个不存在的 key 进行 HMGET 操作将返回一个只带有 nil 值的表。
func (p *RedisPool) HMGET(key string, fields ...string) (value map[string]string, err error) {
args := redis.Args{key}
for _, field := range fields {
args = args.Add(field)
}
res, err := redis.Strings(p.do("HMGET", args...))
if err != nil {
return
}
value = make(map[string]string)
for index, field := range fields {
value[field] = res[index]
}
return
}
// HINCRBY 为哈希表 key 中的域 field 的值加上增量 increment 。
// 增量也可以为负数,相当于对给定域进行减法操作。
// 如果 key 不存在,一个新的哈希表被创建并执行 HINCRBY 命令。
// 如果域 field 不存在,那么在执行命令前,域的值被初始化为 0 。
// 对一个储存字符串值的域 field 执行 HINCRBY 命令将造成一个错误。
// 本操作的值被限制在 64 位(bit)有符号数字表示之内。
// 返回值: 执行 HINCRBY 命令之后,哈希表 key 中域 field 的值。
func (p *RedisPool) HINCRBY(key, field string, increment int64) (value int64, err error) {
value, err = redis.Int64(p.do("HINCRBY", key, field, increment))
return
}
// HINCRBYFLOAT 为哈希表 key 中的域 field 加上浮点数增量 increment 。
// 如果哈希表中没有域 field ,那么 HINCRBYFLOAT 会先将域 field 的值设为 0 ,然后再执行加法操作。
// 如果键 key 不存在,那么 HINCRBYFLOAT 会先创建一个哈希表,再创建域 field ,最后再执行加法操作。
// 无论加法计算所得的浮点数的实际精度有多长, INCRBYFLOAT 命令的计算结果最多只保留小数点的后十七位。
// 当以下任意一个条件发生时,返回一个错误:
// 1.域 field 的值不是字符串类型(因为 redis 中的数字和浮点数都以字符串的形式保存,所以它们都属于字符串类型)
// 2.域 field 当前的值或给定的增量 increment 不能解释(parse)为双精度浮点数
//
// 返回值: 执行加法操作之后 field 域的值。
func (p *RedisPool) HINCRBYFLOAT(key, field string, increment float64) (value float64, err error) {
value, err = redis.Float64(p.do("HINCRBYFLOAT", key, field, increment))
return
}
// HDEL 删除哈希表 key 中的一个或多个指定域,不存在的域将被忽略。
// 返回值: 被成功移除的域的数量,不包括被忽略的域。
func (p *RedisPool) HDEL(key string, fields ...string) (count int, err error) {
args := redis.Args{key}
for _, field := range fields {
args = args.Add(field)
}
count, err = redis.Int(p.do("HDEL", args...))
return
}
//-------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------- set ----------------------------------------------------//
// SADD 将一个或多个 member 元素加入到集合 key 当中,已经存在于集合的 member 元素将被忽略。
// 假如 key 不存在,则创建一个只包含 member 元素作成员的集合。
// 当 key 不是集合类型时,返回一个错误。
func (p *RedisPool) SADD(args ...interface{}) error {
_, err := p.do("SADD", args...)
return err
}
// SISMEMBER 判断 value 元素是否集合 key 的成员
// 如果 member 元素是集合的成员,返回 true 。 如果 member 元素不是集合的成员,或 key 不存在,返回 false 。
func (p *RedisPool) SISMEMBER(key string, value string) (bool, error) {
exists, err := redis.Bool(p.do("SISMEMBER", key, value))
return exists, err
}
// SREM 移除集合 key 中的一个或多个 member 元素,不存在的 member 元素会被忽略。
// 当 key 不是集合类型,返回一个错误。
func (p *RedisPool) SREM(key string, member ...interface{}) error {
_, err := p.do("SREM", key, member)
return err
}
// SCARD 返回集合 key 的基数(集合中元素的数量)。
// 集合的基数。 当 key 不存在时,返回 0 。
func (p *RedisPool) SCARD(key string) (score int, err error) {
score, err = redis.Int(p.do("SCARD", key))
return
}
// SMEMBERS 返回集合 key 中的所有成员。
// 不存在的 key 被视为空集合。
func (p *RedisPool) SMEMBERS(key string) ([]string, error) {
result, err := redis.Strings(p.do("SMEMBERS", key))
return result, err
}
//-------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------- zset ----------------------------------------------------//
// ZADD 将一个或多个 member 元素及其 score 值加入到有序集 key 当中。
// 如果某个 member 已经是有序集的成员,那么更新这个 member 的 score 值,并通过重新插入这个 member 元素,来保证该 member 在正确的位置上。
// score 值可以是整数值或双精度浮点数。
// 如果 key 不存在,则创建一个空的有序集并执行 ZADD 操作。
// 当 key 存在但不是有序集类型时,返回一个错误。
//
// 使用例子:
//
//
// scoreMember := map[int]string{111: "a", 101: "b"}
// if err := conn.ZADD("testZSET", scoreMember); err != nil {
// t.Error(err)
// }
//
func (p *RedisPool) ZADD(key string, scoreMember interface{}) error {
args := redis.Args{key}.AddFlat(scoreMember)
_, err := p.do("ZADD", args...)
return err
}
// ZSCORE 返回有序集 key 中,成员 member 的 score 值。
// 如果 member 元素不是有序集 key 的成员,或 key 不存在,返回 nil 。
func (p *RedisPool) ZSCORE(key string, member interface{}) (score string, err error) {
score, err = redis.String(p.do("ZSCORE", key, member))
return
}
// ZINCRBY 为有序集 key 的成员 member 的 score 值加上增量 increment 。
// 可以通过传递一个负数值 increment ,让 score 减去相应的值,比如 ZINCRBY key -5 member ,就是让 member 的 score 值减去 5
// 当 key 不存在,或 member 不是 key 的成员时, ZINCRBY key increment member 等同于 ZADD key increment member 。
// 当 key 不是有序集类型时,返回一个错误。
// score 值可以是整数值或双精度浮点数。
func (p *RedisPool) ZINCRBY(key string, increment, member interface{}) (score string, err error) {
score, err = redis.String(p.do("ZINCRBY", key, increment, member))
return
}
// ZCARD 返回有序集 key 的基数(集合中元素的数量)。
// 当 key 存在且是有序集类型时,返回有序集的基数。 当 key 不存在时,返回 0 。
func (p *RedisPool) ZCARD(key string) (score int, err error) {
score, err = redis.Int(p.do("ZCARD", key))
return
}
// ZCOUNT 返回有序集 key 中, score 值在 min 和 max 之间(默认包括 score 值等于 min 或 max )的成员的数量。
// 返回值: score 值在 min 和 max 之间的成员的数量。
func (p *RedisPool) ZCOUNT(key string, min, max float64) (count int64, err error) {
count, err = redis.Int64(p.do("ZCOUNT", key, min, max))
return
}
// ZRANGE 返回有序集 key 中,指定区间内的成员。
// 其中成员的位置按 score 值递增(从小到大)来排序。
// 具有相同 score 值的成员按字典序(lexicographical order )来排列。
// 下标参数 start 和 stop 都以 0 为底,也就是说,以 0 表示有序集第一个成员,以 1 表示有序集第二个成员,以此类推。
// 你也可以使用负数下标,以 -1 表示最后一个成员, -2 表示倒数第二个成员,以此类推。
// 超出范围的下标并不会引起错误。
// 比如说,当 start 的值比有序集的最大下标还要大,或是 start > stop 时, ZRANGE 命令只是简单地返回一个空列表。
// 另一方面,假如 stop 参数的值比有序集的最大下标还要大,那么 Redis 将 stop 当作最大下标来处理。
// 返回值: 指定区间内的有序集成员的列表。
func (p *RedisPool) ZRANGE(key string, start, stop int64) (result []string, err error) {
result, err = redis.Strings(p.do("ZRANGE", key, start, stop))
return
}
// ZRANGEWITHSCORES 使用WITHSCORES选项的ZRANGE
func (p *RedisPool) ZRANGEWITHSCORES(key string, start, stop int64) (result []map[string]float64, err error) {
values, err := redis.Values(p.do("ZRANGE", key, start, stop, "WITHSCORES"))
if err != nil {
return
}
if len(values) == 0 {
result = make([]map[string]float64, 0, 1)
return
}
length := len(values) / 2
result = make([]map[string]float64, length)
for i := 0; i < length; i++ {
member := values[i*2].([]byte)
m := string(member)
score := values[i*2+1].([]byte)
s, _ := strconv.ParseFloat(string(score), 64)
item := map[string]float64{m: s}
result[i] = item
}
return
}
// ZREVRANGE 返回有序集 key 中,指定区间内的成员。
// 其中成员的位置按 score 值递减(从大到小)来排序。
// 具有相同 score 值的成员按字典序的逆序(reverse lexicographical order)排列。
// 下标参数 start 和 stop 都以 0 为底,也就是说,以 0 表示有序集第一个成员,以 1 表示有序集第二个成员,以此类推。
// 你也可以使用负数下标,以 -1 表示最后一个成员, -2 表示倒数第二个成员,以此类推。
// 超出范围的下标并不会引起错误。
// 返回值: 指定区间内的有序集成员的列表。
func (p *RedisPool) ZREVRANGE(key string, start, stop int64) (result []string, err error) {
result, err = redis.Strings(p.do("ZREVRANGE", key, start, stop))
return
}
// ZREVRANGEWITHSCORES 使用WITHSCORES选项的ZREVRANGE
func (p *RedisPool) ZREVRANGEWITHSCORES(key string, start, stop int64) (result []map[string]float64, err error) {
values, err := redis.Values(p.do("ZREVRANGE", key, start, stop, "WITHSCORES"))
if err != nil {
return
}
if len(values) == 0 {
result = make([]map[string]float64, 0, 1)
return
}
length := len(values) / 2
result = make([]map[string]float64, length)
for i := 0; i < length; i++ {
member := values[i*2].([]byte)
m := string(member)
score := values[i*2+1].([]byte)
s, _ := strconv.ParseFloat(string(score), 64)
item := map[string]float64{m: s}
result[i] = item
}
return
}
// ZRANK 返回有序集 key 中成员 member 的排名。其中有序集成员按 score 值递增(从小到大)顺序排列。
// 排名以 0 为底,也就是说, score 值最小的成员排名为 0 。
// 使用 ZREVRANK key member 命令可以获得成员按 score 值递减(从大到小)排列的排名。
// 返回值:
// 如果 member 是有序集 key 的成员,返回 member 的排名。
// 如果 member 不是有序集 key 的成员,返回 -1。
func (p *RedisPool) ZRANK(key string, member interface{}) (rank int64, err error) {
rank, err = redis.Int64(p.do("ZRANK", key, member))
if err != nil && err == redis.ErrNil {
rank = -1
}
return
}
// ZREVRANK 返回有序集 key 中成员 member 的排名。其中有序集成员按 score 值递减(从大到小)顺序排列。
// 排名以 0 为底,也就是说, score 值最小的成员排名为 0 。
// 返回值:
//
// * 如果 member 是有序集 key 的成员,返回 member 的排名。
// * 如果 member 不是有序集 key 的成员,返回 -1。
//
func (p *RedisPool) ZREVRANK(key string, member interface{}) (rank int64, err error) {
rank, err = redis.Int64(p.do("ZREVRANK", key, member))
if err != nil && err == redis.ErrNil {
rank = -1
}
return
}
// ZREM 移除有序集 key 中的一个或多个成员,不存在的成员将被忽略。
func (p *RedisPool) ZREM(key string, member ...interface{}) (count int64, err error) {
args := redis.Args{key}
for _, field := range member {
args = args.Add(field)
}
count, err = redis.Int64(p.do("ZREM", args...))
return
}
// ZREMRANGEBYRANK 移除有序集key中,指定排名(rank)区间 start 和 stop 内的所有成员。
// 下标参数start和stop都是从0开始计数,0是分数最小的那个元素。
// 索引也可是负数,表示位移从最高分处开始数。
// 例如,-1是分数最高的元素,-2是分数第二高的,依次类推。
func (p *RedisPool) ZREMRANGEBYRANK(key string, start, stop int64) (count int64, err error) {
count, err = redis.Int64(p.do("ZREMRANGEBYRANK", key, start, stop))
return
}
// // Bool 执行redis操作返回布尔值
// func (p *RedisPool) Bool(command string, args ...interface{}) (bool, error) {
// return redis.Bool(p.do(command, args...))
// }
// // Float64 执行redis操作返回float64
// func (p *RedisPool) Float64(command string, args ...interface{}) (float64, error) {
// return redis.Float64(p.do(command, args...))
// }
// // Float64s 执行redis操作返回float64数组
// func (p *RedisPool) Float64s(command string, args ...interface{}) ([]float64, error) {
// return redis.Float64s(p.do(command, args...))
// }
// // String 执行redis命令string
// func (p *RedisPool) String(command string, args ...interface{}) (string, error) {
// return redis.String(p.do(command, args...))
// }
// // Strings 执行redis命令string数组
// func (p *RedisPool) Strings(command string, args ...interface{}) ([]string, error) {
// return redis.Strings(p.do(command, args...))
// }
// // Int 执行redis命令int
// func (p *RedisPool) Int(command string, args ...interface{}) (int, error) {
// return redis.Int(p.do(command, args...))
// }
// // Ints 执行redis命令int数组
// func (p *RedisPool) Ints(command string, args ...interface{}) ([]int, error) {
// return redis.Ints(p.do(command, args...))
// }
// // StringMap 执行redis命令StringMap
// func (p *RedisPool) StringMap(command string, args ...interface{}) (map[string]string, error) {
// return redis.StringMap(p.do(command, args...))
// }
// // ScanStruct 执行redis命令StringMap
// // 字段tag使用redis,当redis:"-"则忽略
// func (p *RedisPool) ScanStruct(command string, dest interface{}, args ...interface{}) error {
// values, err := redis.Values(p.do(command, args...))
// if err != nil {
// return err
// }
// err = redis.ScanStruct(values, dest)
// return err
// }
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。