Initial commit: web_hghl_server
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,95 @@
|
||||
package redis
|
||||
|
||||
import (
|
||||
"github.com/go-redis/redis"
|
||||
"time"
|
||||
)
|
||||
|
||||
// List represents a redis list.
|
||||
type List struct {
|
||||
key string
|
||||
client *redis.Client
|
||||
}
|
||||
|
||||
// NewList creates a new redis list instance.
|
||||
func NewList(client *redis.Client, key string) *List {
|
||||
return &List{
|
||||
key: key,
|
||||
client: client,
|
||||
}
|
||||
}
|
||||
|
||||
// Key returns the key of the list.
|
||||
func (l *List) Key() string {
|
||||
return l.key
|
||||
}
|
||||
|
||||
// Expire sets the expiration time of the list.
|
||||
func (l *List) Expire(expiration time.Duration) (bool, error) {
|
||||
return l.client.Expire(l.key, expiration).Result()
|
||||
}
|
||||
|
||||
// Delete deletes the list.
|
||||
func (l *List) Delete() (int64, error) {
|
||||
return l.client.Del(l.key).Result()
|
||||
}
|
||||
|
||||
// Len returns the length of the list.
|
||||
func (l *List) Len() (int64, error) {
|
||||
return l.client.LLen(l.key).Result()
|
||||
}
|
||||
|
||||
// Push adds a new element to the tail of the list.
|
||||
func (l *List) Push(value interface{}) error {
|
||||
return l.client.RPush(l.key, value).Err()
|
||||
}
|
||||
|
||||
// Pop removes and returns the first element of the list.
|
||||
func (l *List) Pop() (string, error) {
|
||||
return l.client.LPop(l.key).Result()
|
||||
}
|
||||
|
||||
// PushFront adds a new element to the head of the list.
|
||||
func (l *List) PushFront(value interface{}) error {
|
||||
return l.client.LPush(l.key, value).Err()
|
||||
}
|
||||
|
||||
// PopBack removes and returns the last element of the list.
|
||||
func (l *List) PopBack() (string, error) {
|
||||
return l.client.RPop(l.key).Result()
|
||||
}
|
||||
|
||||
// Index returns the element at the specified index.
|
||||
func (l *List) Index(index int64) (string, error) {
|
||||
return l.client.LIndex(l.key, index).Result()
|
||||
}
|
||||
|
||||
// Range returns a range of elements from the list.
|
||||
func (l *List) Range(start, stop int64) ([]string, error) {
|
||||
return l.client.LRange(l.key, start, stop).Result()
|
||||
}
|
||||
|
||||
// Trim removes elements from the list.
|
||||
func (l *List) Trim(start, stop int64) error {
|
||||
return l.client.LTrim(l.key, start, stop).Err()
|
||||
}
|
||||
|
||||
// Set sets the element at the specified index.
|
||||
func (l *List) Set(index int64, value interface{}) error {
|
||||
return l.client.LSet(l.key, index, value).Err()
|
||||
}
|
||||
|
||||
// InsertBefore inserts a new element before the specified element.
|
||||
func (l *List) InsertBefore(pivot, value interface{}) error {
|
||||
return l.client.LInsertBefore(l.key, pivot, value).Err()
|
||||
}
|
||||
|
||||
// InsertAfter inserts a new element after the specified element.
|
||||
func (l *List) InsertAfter(pivot, value interface{}) error {
|
||||
return l.client.LInsertAfter(l.key, pivot, value).Err()
|
||||
}
|
||||
|
||||
// Remove removes all occurrences of the specified element.
|
||||
func (l *List) Remove(count int64, value interface{}) (int64, error) {
|
||||
return l.client.LRem(l.key, count, value).Result()
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
package redis
|
||||
|
||||
import "time"
|
||||
|
||||
// RCType redis channel type
|
||||
type RCType string
|
||||
|
||||
const (
|
||||
// config
|
||||
RCT_cfg_all RCType = "config.*"
|
||||
// tabkind 配置改变
|
||||
RCT_cfg_tabkind_change RCType = "config.tabkindchange"
|
||||
// mediatag 配置改变
|
||||
RCT_cfg_mediatag_change RCType = "config.mediatagchange"
|
||||
// mediacat 配置改变
|
||||
RCT_cfg_mediacat_change RCType = "config.mediacatchange"
|
||||
// mediatopic 配置改变
|
||||
RCT_cfg_mediatopic_change RCType = "config.mediatopicchange"
|
||||
// mediacolumn 配置改变
|
||||
RCT_cfg_mediacolumn_change RCType = "config.mediacolumnchange"
|
||||
// syscfg 系统配置改变
|
||||
RCT_cfg_syscfg_change RCType = "config.syscfgchange"
|
||||
|
||||
// 广告
|
||||
RCT_ad_all RCType = "ad.*"
|
||||
// 广告配置改变
|
||||
RCT_ad_cfgchange RCType = "ad.cfgchange"
|
||||
|
||||
// 系统通知
|
||||
RCT_blt_all RCType = "blt.*"
|
||||
// 系统通知
|
||||
RCT_blt_cfgchange RCType = "blt.cfgchange"
|
||||
|
||||
//media
|
||||
RCT_media_all RCType = "media.*"
|
||||
//media 信息改变
|
||||
RCT_media_change RCType = "media.change"
|
||||
//media 信息添加
|
||||
RCT_media_add RCType = "media.add"
|
||||
//media 信息删除
|
||||
RCT_media_del RCType = "media.del"
|
||||
//media 相关排行榜改变
|
||||
RCT_media_topchange RCType = "media.topchange"
|
||||
|
||||
//user
|
||||
RCT_user_all RCType = "user.*"
|
||||
//user 信息改变
|
||||
RCT_user_change RCType = "user.change"
|
||||
//user 信息添加
|
||||
RCT_user_add RCType = "user.add"
|
||||
//user 信息删除
|
||||
RCT_user_del RCType = "user.del"
|
||||
//user 相关排行榜改变
|
||||
RCT_user_topchange RCType = "user.topchange"
|
||||
|
||||
//视频推荐
|
||||
RCT_recommend_all RCType = "recommend.*"
|
||||
//博主推荐
|
||||
RCT_recommend_blogger_all RCType = "recommend.bloggerALL"
|
||||
// 视频每日推荐
|
||||
RCT_recommend_media_all RCType = "recommend.mediaAll"
|
||||
|
||||
//tg消息
|
||||
RCT_tgmsg_all RCType = "tgmsg.*"
|
||||
RCT_tgmsg_send_msg RCType = "tgmsg.sendmsg"
|
||||
|
||||
//vipcard
|
||||
RCT_vipcard_all RCType = "vipcard.*"
|
||||
RCT_vipcard_change RCType = "vipcard.change"
|
||||
|
||||
NameSource = "name:source" //姓名池
|
||||
NameSourceExpire = 2 * 24 * time.Hour
|
||||
CommunicateServerChannel = "comm:lld#server"
|
||||
CommunicateClientChannel = "comm:lld#client"
|
||||
)
|
||||
@@ -0,0 +1,112 @@
|
||||
package redis
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/go-redis/redis"
|
||||
)
|
||||
|
||||
//key: {name:value, name:value, name:value}
|
||||
|
||||
type Hash struct {
|
||||
key string
|
||||
client *redis.Client
|
||||
}
|
||||
|
||||
func NewHash(client *redis.Client, key string) *Hash {
|
||||
return &Hash{
|
||||
key: key,
|
||||
client: client,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Hash) Key() string {
|
||||
return s.key
|
||||
}
|
||||
|
||||
// Expire 设置集合过期时间
|
||||
func (s *Hash) Expire(expiration time.Duration) (bool, error) {
|
||||
return s.client.Expire(s.key, expiration).Result()
|
||||
}
|
||||
|
||||
// Delete 删除一个或多个 Name
|
||||
func (s *Hash) Delete(names ...string) (int64, error) {
|
||||
return s.client.HDel(s.key, names...).Result()
|
||||
}
|
||||
|
||||
// Exists 检测Name是否在哈希表中
|
||||
func (s *Hash) Exists(name string) (bool, error) {
|
||||
return s.client.HExists(s.key, name).Result()
|
||||
}
|
||||
|
||||
// NameValues 获取所有哈希表数据
|
||||
func (s *Hash) NameValues() (map[string]string, error) {
|
||||
return s.client.HGetAll(s.key).Result()
|
||||
}
|
||||
|
||||
// Names 获取所有哈希表的 Name
|
||||
func (s *Hash) Names() ([]string, error) {
|
||||
return s.client.HKeys(s.key).Result()
|
||||
}
|
||||
|
||||
// Values 获取所有哈希表的 Total
|
||||
func (s *Hash) Values() ([]string, error) {
|
||||
return s.client.HVals(s.key).Result()
|
||||
}
|
||||
|
||||
// SetNX 当name不存在时才向哈希表中设置一对Name:Total
|
||||
func (s *Hash) SetNX(name string, value interface{}) (bool, error) {
|
||||
return s.client.HSetNX(s.key, name, value).Result()
|
||||
}
|
||||
|
||||
// Set 向哈希表中设置一对Name:Total
|
||||
func (s *Hash) Set(name string, value interface{}) (bool, error) {
|
||||
return s.client.HSet(s.key, name, value).Result()
|
||||
}
|
||||
|
||||
// Get 获取哈希表中Name对应的Value
|
||||
func (s *Hash) Get(name string) (string, error) {
|
||||
return s.client.HGet(s.key, name).Result()
|
||||
}
|
||||
|
||||
// GetResult 获取哈希表中Name对应的Value
|
||||
func (s *Hash) GetResult(name string) *redis.StringCmd {
|
||||
return s.client.HGet(s.key, name)
|
||||
}
|
||||
|
||||
// IncInt 返回累加之后的新值
|
||||
func (s *Hash) IncInt(name string, value int64) (int64, error) {
|
||||
return s.client.HIncrBy(s.key, name, value).Result()
|
||||
}
|
||||
|
||||
// IncFloat 返回累加之后的新值
|
||||
func (s *Hash) IncFloat(name string, value float64) (float64, error) {
|
||||
return s.client.HIncrByFloat(s.key, name, value).Result()
|
||||
}
|
||||
|
||||
// Len 返回哈希表的大小
|
||||
func (s *Hash) Len() (int64, error) {
|
||||
return s.client.HLen(s.key).Result()
|
||||
}
|
||||
|
||||
// Scan 扫描哈希表数据
|
||||
func (s *Hash) Scan(match string, piece int64, callback func(name, value string)) error {
|
||||
proc := func(l []string) {
|
||||
for i := 0; i+1 < len(l); i += 2 {
|
||||
callback(l[i], l[i+1])
|
||||
}
|
||||
}
|
||||
lst, cur, err := s.client.HScan(s.key, 0, match, piece).Result()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
proc(lst)
|
||||
for cur > 0 {
|
||||
lst, cur, err = s.client.HScan(s.key, cur, match, piece).Result()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
proc(lst)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,177 @@
|
||||
package redis
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
"sync"
|
||||
"videoweb/pub/common/log"
|
||||
"videoweb/pub/common/srvdef"
|
||||
|
||||
"github.com/go-redis/redis"
|
||||
)
|
||||
|
||||
type SubscribeCallback func(channel RCType, message string)
|
||||
|
||||
var (
|
||||
redisCli *redis.Client
|
||||
opts Options
|
||||
|
||||
//订阅参数
|
||||
pubsub *redis.PubSub
|
||||
subCBMap map[RCType]SubscribeCallback
|
||||
cbMapLock sync.RWMutex
|
||||
)
|
||||
|
||||
func Client() *redis.Client {
|
||||
return redisCli
|
||||
}
|
||||
|
||||
func Disconnect() {
|
||||
if redisCli != nil {
|
||||
if pubsub != nil {
|
||||
pubsub.Close()
|
||||
}
|
||||
redisCli.Close()
|
||||
redisCli = nil
|
||||
}
|
||||
}
|
||||
|
||||
func Init(opts Options) error {
|
||||
c := redis.NewClient(
|
||||
&redis.Options{
|
||||
Addr: opts.Addr,
|
||||
Password: opts.Psw,
|
||||
DB: opts.Db,
|
||||
},
|
||||
)
|
||||
|
||||
if err := c.Ping().Err(); err != nil {
|
||||
log.Error(fmt.Sprintf("[error] ping redis err %+v\n", err))
|
||||
return err
|
||||
}
|
||||
redisCli = c
|
||||
|
||||
pubsub = nil
|
||||
if opts.Subscribe {
|
||||
subCBMap = make(map[RCType]SubscribeCallback)
|
||||
pubsub = redisCli.Subscribe()
|
||||
//接受发布消息
|
||||
go ReceiveMessage()
|
||||
}
|
||||
|
||||
log.Info("redis:Init Ok!")
|
||||
return nil
|
||||
}
|
||||
|
||||
// OnMessage 订阅消息回调
|
||||
func OnMessage(channel RCType, message string) {
|
||||
cbMapLock.RLock()
|
||||
defer cbMapLock.RUnlock()
|
||||
flag := false
|
||||
for k, v := range subCBMap {
|
||||
reg := regexp.MustCompile(string(k))
|
||||
//log.Info("test", log.Any("k", k), log.Any("channelchannel", channel))
|
||||
if b := reg.MatchString(string(channel)); b {
|
||||
v(channel, message)
|
||||
flag = true
|
||||
}
|
||||
}
|
||||
if !flag {
|
||||
log.Warn("(redis:OnMessage) callback doesn't exist!", log.Any("channel", channel))
|
||||
}
|
||||
}
|
||||
|
||||
// ReceiveMessage 接受发布消息
|
||||
func ReceiveMessage() {
|
||||
for {
|
||||
msg, err := pubsub.Receive()
|
||||
if err != nil {
|
||||
fmt.Println("test1", err)
|
||||
return
|
||||
}
|
||||
|
||||
switch msg := msg.(type) {
|
||||
case *redis.Subscription:
|
||||
// Ignore.
|
||||
log.Info("(redis:ReceiveMessage) subscribe success!", log.Any("channel", msg.Channel))
|
||||
case *redis.Pong:
|
||||
// Ignore.
|
||||
fmt.Println("Pong")
|
||||
case *redis.Message:
|
||||
channel := msg.Channel
|
||||
message := msg.Payload
|
||||
OnMessage(RCType(channel), message)
|
||||
default:
|
||||
log.Error("(redis:ReceiveMessage) msg!", log.Any("msg", msg))
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Subscribe 订阅一个消息
|
||||
func Subscribe(channel RCType, cb SubscribeCallback) *srvdef.SrvErr {
|
||||
if pubsub == nil {
|
||||
log.Warn("(redis:Subscribe) subscribe is not enabled!")
|
||||
return srvdef.New(srvdef.ErrRdsOperError, "", "")
|
||||
}
|
||||
err := pubsub.Subscribe(string(channel))
|
||||
if err != nil {
|
||||
log.Warn("(redis:Subscribe) Subscribe failed!", log.Any("err", err))
|
||||
return srvdef.New(srvdef.ErrRdsOperError, "", "")
|
||||
}
|
||||
cbMapLock.Lock()
|
||||
defer cbMapLock.Unlock()
|
||||
subCBMap[channel] = cb
|
||||
return nil
|
||||
}
|
||||
|
||||
// UnSubscribe 取消订阅一个消息
|
||||
func UnSubscribe(channel RCType, cb SubscribeCallback) *srvdef.SrvErr {
|
||||
if pubsub == nil {
|
||||
log.Warn("(redis:UnSubscribe) subscribe is not enabled!")
|
||||
return srvdef.New(srvdef.ErrRdsOperError, "", "")
|
||||
}
|
||||
err := pubsub.Unsubscribe(string(channel))
|
||||
if err != nil {
|
||||
log.Warn("(redis:UnSubscribe) UnSubscribe failed!", log.Any("err", err))
|
||||
return srvdef.New(srvdef.ErrRdsOperError, "", "")
|
||||
}
|
||||
cbMapLock.Lock()
|
||||
defer cbMapLock.Unlock()
|
||||
delete(subCBMap, channel)
|
||||
return nil
|
||||
}
|
||||
|
||||
// PSubscribe 模式匹配消息
|
||||
func PSubscribe(channel RCType, cb SubscribeCallback) *srvdef.SrvErr {
|
||||
if pubsub == nil {
|
||||
log.Warn("(redis:PSubscribe) subscribe is not enabled!")
|
||||
return srvdef.New(srvdef.ErrRdsOperError, "", "")
|
||||
}
|
||||
err := pubsub.PSubscribe(string(channel))
|
||||
if err != nil {
|
||||
log.Warn("(redis:PSubscribe) PSubscribe failed!", log.Any("err", err))
|
||||
return srvdef.New(srvdef.ErrRdsOperError, "", "")
|
||||
}
|
||||
cbMapLock.Lock()
|
||||
defer cbMapLock.Unlock()
|
||||
subCBMap[channel] = cb
|
||||
return nil
|
||||
}
|
||||
|
||||
// PUnsubscribe 模式取消匹配消息
|
||||
func PUnsubscribe(channel RCType, cb SubscribeCallback) *srvdef.SrvErr {
|
||||
if pubsub == nil {
|
||||
log.Warn("(redis:PUnsubscribe) subscribe is not enabled!")
|
||||
return srvdef.New(srvdef.ErrRdsOperError, "", "")
|
||||
}
|
||||
err := pubsub.PUnsubscribe(string(channel))
|
||||
if err != nil {
|
||||
log.Warn("(redis:PUnsubscribe) PUnsubscribe failed!", log.Any("err", err))
|
||||
return srvdef.New(srvdef.ErrRdsOperError, "", "")
|
||||
}
|
||||
cbMapLock.Lock()
|
||||
defer cbMapLock.Unlock()
|
||||
delete(subCBMap, channel)
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package redis
|
||||
|
||||
// Redis 配置项
|
||||
type Options struct {
|
||||
Addr string `json:"addr"` // 地址
|
||||
Psw string `json:"psw"` // 密码
|
||||
Db int `json:"db"` // 库
|
||||
Subscribe bool `json:"subscribe"` // 是否有订阅功能
|
||||
}
|
||||
@@ -0,0 +1,275 @@
|
||||
package redis
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
sErr "videoweb/pub/common/errors"
|
||||
"videoweb/pub/common/log"
|
||||
|
||||
goredis "github.com/go-redis/redis"
|
||||
)
|
||||
|
||||
type ZMember = goredis.Z
|
||||
|
||||
// Set 设置键值对
|
||||
func Set(key string, value interface{}, expireTime time.Duration) (err error) {
|
||||
if err = redisCli.Set(key, value, expireTime).Err(); err != nil {
|
||||
return sErr.MakeWithErr(sErr.RedisSet, err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Incr 增加1
|
||||
func Incr(key string, expireTime time.Duration) (val int64, err error) {
|
||||
val, err = redisCli.Incr(key).Result()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
duration := redisCli.TTL(key).Val()
|
||||
//log.Info("Incr Test", log.Any("duration", duration))
|
||||
if duration.Seconds() == -1 {
|
||||
redisCli.Expire(key, expireTime)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func SAdd(key string, members ...interface{}) (err error) {
|
||||
_, err = redisCli.SAdd(key, members...).Result()
|
||||
return
|
||||
}
|
||||
|
||||
// 无序集合操作 随机删除集合中某一元素
|
||||
func SPop(key string, members ...interface{}) (string, error) {
|
||||
val, err := redisCli.SPop(key).Result()
|
||||
if err != nil {
|
||||
log.Error(fmt.Sprintf("SPop failed %+v:", err))
|
||||
}
|
||||
return val, err
|
||||
}
|
||||
|
||||
func SRem(key string, members ...interface{}) (err error) {
|
||||
if err = redisCli.SRem(key, members...).Err(); err != nil {
|
||||
err = sErr.MakeWithErr(sErr.RedisSet, err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// ScanSlice 返回集合成员
|
||||
func SScanSlice(key string, container interface{}) (err error) {
|
||||
err = redisCli.SMembers(key).ScanSlice(container)
|
||||
return err
|
||||
}
|
||||
|
||||
// SMembers
|
||||
func SMembers(key string) (list []string, err error) {
|
||||
result := redisCli.SMembers(key)
|
||||
if result.Err() != nil {
|
||||
err = sErr.MakeWithErr(sErr.RedisGet, result.Err())
|
||||
return
|
||||
}
|
||||
list = result.Val()
|
||||
return
|
||||
}
|
||||
|
||||
// RPush
|
||||
func RPush(key string, value string) error {
|
||||
if key == "" {
|
||||
return errors.New("key should not empty")
|
||||
}
|
||||
if err := redisCli.RPush(key, value).Err(); err != nil {
|
||||
return sErr.MakeWithErr(sErr.RedisRPush, err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// RPush
|
||||
func RPushValues(key string, value ...interface{}) error {
|
||||
if key == "" {
|
||||
return errors.New("key should not empty")
|
||||
}
|
||||
if err := redisCli.RPush(key, value...).Err(); err != nil {
|
||||
return sErr.MakeWithErr(sErr.RedisRPush, err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// LPop
|
||||
func LPop(key string) (*string, error) {
|
||||
if key == "" {
|
||||
return nil, errors.New("key should not empty")
|
||||
}
|
||||
|
||||
cmd := redisCli.LPop(key)
|
||||
if cmd.Err() != nil {
|
||||
return nil, sErr.MakeWithErr(sErr.RedisLPop, cmd.Err())
|
||||
}
|
||||
|
||||
data, err := cmd.Result()
|
||||
if err != nil {
|
||||
if err == goredis.Nil {
|
||||
return nil, nil
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &data, nil
|
||||
}
|
||||
|
||||
// Get 根据键 获取值
|
||||
func Get(key string) (*string, error) {
|
||||
if key == "" {
|
||||
return nil, errors.New("key should not empty")
|
||||
}
|
||||
data, err := redisCli.Get(key).Result()
|
||||
if err != nil {
|
||||
if err == goredis.Nil {
|
||||
return nil, nil
|
||||
}
|
||||
return nil, err
|
||||
} else {
|
||||
return &data, nil
|
||||
}
|
||||
}
|
||||
|
||||
// Get 根据键 获取值
|
||||
func GetBytes(key string) (bytes []byte, err error) {
|
||||
bytes, err = redisCli.Get(key).Bytes()
|
||||
if err != nil {
|
||||
return nil, sErr.MakeWithErr(sErr.RedisGet, err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Del 删除
|
||||
func Del(keys ...string) (err error) {
|
||||
if err = redisCli.Del(keys...).Err(); err != nil {
|
||||
return sErr.MakeWithErr(sErr.RedisDel, err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Exists keys exists?
|
||||
func Exists(keys ...string) (has bool, err error) {
|
||||
intcmd := redisCli.Exists(keys...)
|
||||
if err = intcmd.Err(); err != nil {
|
||||
return
|
||||
}
|
||||
has = intcmd.Val() > 0
|
||||
return
|
||||
}
|
||||
|
||||
func Keys(pattern string) (keys []string, err error) {
|
||||
list := redisCli.Keys(pattern)
|
||||
keys = list.Val()
|
||||
err = list.Err()
|
||||
return
|
||||
}
|
||||
|
||||
// Setnx 设置键值对
|
||||
func Setnx(key string, value interface{}, expirTime time.Duration) (err error) {
|
||||
if err = redisCli.SetNX(key, value, expirTime).Err(); err != nil {
|
||||
err = sErr.MakeWithErr(sErr.RedisSet, err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Setnx 设置键值对 正确的封装
|
||||
func Setnx_NewOK(key string, value interface{}, expirTime time.Duration) (v bool, err error) {
|
||||
cmd := redisCli.SetNX(key, value, expirTime)
|
||||
return cmd.Val(), cmd.Err()
|
||||
}
|
||||
|
||||
func Expire(key string, expirTime time.Duration) (err error) {
|
||||
if err = redisCli.Expire(key, expirTime).Err(); err != nil {
|
||||
err = sErr.MakeWithErr(sErr.RedisSet, err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Redis `SRANDMEMBER key count` command.
|
||||
func SRandMemberN(key string, count int64) (list []string, err error) {
|
||||
result := redisCli.SRandMemberN(key, count)
|
||||
if result.Err() != nil {
|
||||
return
|
||||
}
|
||||
list = result.Val()
|
||||
return
|
||||
}
|
||||
|
||||
// 有序集合操作 添加多个有序集合
|
||||
func ZAdd(key string, z ...ZMember) (int64, error) {
|
||||
count, err := redisCli.ZAdd(key, z...).Result()
|
||||
if err != nil {
|
||||
log.Error(fmt.Sprintf("ZAdd failed %+v:", err))
|
||||
}
|
||||
return count, err
|
||||
}
|
||||
|
||||
// 有序集合 数量
|
||||
func ZCard(key string) (int64, error) {
|
||||
count, err := redisCli.ZCard(key).Result()
|
||||
if err != nil {
|
||||
log.Error(fmt.Sprintf("ZCard failed %+v:", err))
|
||||
}
|
||||
return count, err
|
||||
}
|
||||
|
||||
// 返回区间成员
|
||||
func ZRange(key string, start, end int64) ([]string, error) {
|
||||
data, err := redisCli.ZRange(key, start, end).Result()
|
||||
if err != nil {
|
||||
log.Error(fmt.Sprintf("ZRange failed %+v:", err))
|
||||
}
|
||||
return data, err
|
||||
}
|
||||
|
||||
// 按照元素排序 删除指定排名的元素
|
||||
func ZRemRangeByRank(key string, start, end int64) (int64, error) {
|
||||
count, err := redisCli.ZRemRangeByRank(key, start, end).Result()
|
||||
if err != nil {
|
||||
log.Error(fmt.Sprintf("ZRemRangeByRank failed %+v:", err))
|
||||
}
|
||||
return count, err
|
||||
}
|
||||
|
||||
// 按照元素排序 删除按指定的分数区间的的元素
|
||||
func ZRemRangeByScore(key, start, end string) (int64, error) {
|
||||
count, err := redisCli.ZRemRangeByScore(key, start, end).Result()
|
||||
if err != nil {
|
||||
log.Error(fmt.Sprintf("ZRemRangeByScore failed %+v:", err))
|
||||
}
|
||||
return count, err
|
||||
}
|
||||
|
||||
// Publish 发布消息
|
||||
func Publish(channel RCType, message string) error {
|
||||
if err := redisCli.Publish(string(channel), message).Err(); err != nil {
|
||||
log.Error(fmt.Sprintf("Publish failed %+v:", err))
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func SendMsgToTg(message string) error {
|
||||
return Publish(RCT_tgmsg_send_msg, message)
|
||||
}
|
||||
|
||||
// SCard 发布消息
|
||||
func SCard(key string) (int64, error) {
|
||||
count, err := redisCli.SCard(key).Result()
|
||||
if err != nil {
|
||||
log.Error(fmt.Sprintf("SCard failed %+v:", err))
|
||||
}
|
||||
|
||||
return count, err
|
||||
}
|
||||
|
||||
// 获取key的剩余生存时间
|
||||
func TTL(key string) time.Duration {
|
||||
durCmd := redisCli.TTL(key)
|
||||
if durCmd != nil {
|
||||
return durCmd.Val()
|
||||
}
|
||||
return 0
|
||||
}
|
||||
@@ -0,0 +1,136 @@
|
||||
package redis
|
||||
|
||||
import (
|
||||
"github.com/go-redis/redis"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Z = redis.Z
|
||||
|
||||
type ZSet struct {
|
||||
key string
|
||||
client *redis.Client
|
||||
}
|
||||
|
||||
func NewZSet(client *redis.Client, key string) *ZSet {
|
||||
return &ZSet{
|
||||
key: key,
|
||||
client: client,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *ZSet) Key() string {
|
||||
return s.key
|
||||
}
|
||||
|
||||
// Expire 设置集合过期时间
|
||||
func (s *ZSet) Expire(expiration time.Duration) (bool, error) {
|
||||
return s.client.Expire(s.key, expiration).Result()
|
||||
}
|
||||
|
||||
// Add 添加一个或多个成员到有序集合
|
||||
func (s *ZSet) Add(members ...Z) (int64, error) {
|
||||
return s.client.ZAdd(s.key, members...).Result()
|
||||
}
|
||||
|
||||
// Count 返回有序集合在指定分数范围内的成员数量
|
||||
func (s *ZSet) Count(min, max float64) (int64, error) {
|
||||
return s.client.ZCount(s.key, strconv.FormatFloat(min, 'f', -1, 64), strconv.FormatFloat(max, 'f', -1, 64)).Result()
|
||||
}
|
||||
|
||||
// Score 获取成员的分数
|
||||
func (s *ZSet) Score(member string) (float64, error) {
|
||||
return s.client.ZScore(s.key, member).Result()
|
||||
}
|
||||
|
||||
// Rank 获取成员的排名(从小到大,0开始)
|
||||
func (s *ZSet) Rank(member string) (int64, error) {
|
||||
return s.client.ZRank(s.key, member).Result()
|
||||
}
|
||||
|
||||
// RevRank 获取成员的排名(从大到小,0开始)
|
||||
func (s *ZSet) RevRank(member string) (int64, error) {
|
||||
return s.client.ZRevRank(s.key, member).Result()
|
||||
}
|
||||
|
||||
// Range 返回指定排名范围的成员
|
||||
func (s *ZSet) Range(start, stop int64) ([]string, error) {
|
||||
return s.client.ZRange(s.key, start, stop).Result()
|
||||
}
|
||||
|
||||
// RangeWithScores 返回指定排名范围的成员和分数
|
||||
func (s *ZSet) RangeWithScores(start, stop int64) ([]Z, error) {
|
||||
return s.client.ZRangeWithScores(s.key, start, stop).Result()
|
||||
}
|
||||
|
||||
// RangeByScore 返回指定分数范围的成员
|
||||
func (s *ZSet) RangeByScore(min, max float64) ([]string, error) {
|
||||
opt := redis.ZRangeBy{
|
||||
Min: strconv.FormatFloat(min, 'f', -1, 64),
|
||||
Max: strconv.FormatFloat(max, 'f', -1, 64),
|
||||
}
|
||||
return s.client.ZRangeByScore(s.key, opt).Result()
|
||||
}
|
||||
|
||||
// RangeByScoreWithScores 返回指定分数范围的成员和分数
|
||||
func (s *ZSet) RangeByScoreWithScores(min, max float64) ([]Z, error) {
|
||||
opt := redis.ZRangeBy{
|
||||
Min: strconv.FormatFloat(min, 'f', -1, 64),
|
||||
Max: strconv.FormatFloat(max, 'f', -1, 64),
|
||||
}
|
||||
return s.client.ZRangeByScoreWithScores(s.key, opt).Result()
|
||||
}
|
||||
|
||||
// Remove 删除一个或多个成员
|
||||
func (s *ZSet) Remove(members ...string) (int64, error) {
|
||||
return s.client.ZRem(s.key, members).Result()
|
||||
}
|
||||
|
||||
// RemoveRangeByRank 删除指定排名范围的成员
|
||||
func (s *ZSet) RemoveRangeByRank(start, stop int64) (int64, error) {
|
||||
return s.client.ZRemRangeByRank(s.key, start, stop).Result()
|
||||
}
|
||||
|
||||
// RemoveRangeByScore 删除指定分数范围的成员
|
||||
func (s *ZSet) RemoveRangeByScore(min, max float64) (int64, error) {
|
||||
return s.client.ZRemRangeByScore(s.key, strconv.FormatFloat(min, 'f', -1, 64), strconv.FormatFloat(max, 'f', -1, 64)).Result()
|
||||
}
|
||||
|
||||
// Len 返回有序集合的成员数
|
||||
func (s *ZSet) Len() (int64, error) {
|
||||
return s.client.ZCard(s.key).Result()
|
||||
}
|
||||
|
||||
// IncScore 为成员的分数加上增量
|
||||
func (s *ZSet) IncScore(member string, increment float64) (float64, error) {
|
||||
return s.client.ZIncrBy(s.key, increment, member).Result()
|
||||
}
|
||||
|
||||
// Scan 扫描有序集合
|
||||
func (s *ZSet) Scan(match string, count int64, callback func(member string, score float64) error) error {
|
||||
cursor := uint64(0)
|
||||
for {
|
||||
keys, newCursor, err := s.client.ZScan(s.key, cursor, match, count).Result()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for i := 0; i < len(keys); i += 2 {
|
||||
score, err := strconv.ParseFloat(keys[i+1], 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = callback(keys[i], score)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if newCursor == 0 {
|
||||
break
|
||||
}
|
||||
cursor = newCursor
|
||||
}
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user