上传数据层代码优化

This commit is contained in:
liwei1dao 2022-08-09 18:39:21 +08:00
parent 5e2a9fdf45
commit 81f0247969
45 changed files with 2137 additions and 749 deletions

View File

@ -47,6 +47,48 @@ const (
ModuleGM core.M_Modules = "gm" //gm模块 ModuleGM core.M_Modules = "gm" //gm模块
) )
//数据表名定义处
const (
///数据日志表
TableModellog = "model_log"
///用户会话数据表
TableSession = "session"
///用户扩展数据表
TableUserExpand = "userexpand"
///玩家设置数据表
TableSetting = "setting"
///用户表
TableUser = "user"
///任务活跃度表
TableTaskActive = "taskactive"
///每日任务表
TableTask = "task"
///商店数据表
TableShop = "shop"
///商店物品数据表
TableShopitems = "shopitems"
///公告信息表
TableNotify = "notify"
///主线数据表
TableMainline = "mainline"
///邮件表
TableMail = "mail"
///道具背包表
TableItems = "items"
///英雄数据表
TableHero = "hero"
///用户记录
TableUserRecord = "userrecord"
///好友数据表
TableFriend = "friend"
//论坛数据表
TableForum = "forum"
//装备数据表
TableEquipment = "equipment"
///聊天数据表
TableChat = "chat"
)
//RPC服务接口定义处 //RPC服务接口定义处
const ( //Rpc const ( //Rpc
//Gateway 网关消息 //Gateway 网关消息

View File

@ -108,6 +108,16 @@ func (this *Redis) LRange(key string, start, end int, v interface{}) (err error)
return return
} }
/*
Redis Lrange 返回列表中指定区间内的元素区间以偏移量 START END 指定 其中 0 表示列表的第一个元素 1 表示列表的第二个元素
以此类推 你也可以使用负数下标 -1 表示列表的最后一个元素 -2 表示列表的倒数第二个元素以此类推
*/
func (this *Redis) LRangeToStringSlice(key string, start, end int) *redis.StringSliceCmd {
cmd := redis.NewStringSliceCmd(this.client.Context(), "LRANGE", key, start, end)
this.client.Process(this.client.Context(), cmd)
return cmd
}
/* /*
Redis Lrem 根据参数 COUNT 的值移除列表中与参数 VALUE 相等的元素 Redis Lrem 根据参数 COUNT 的值移除列表中与参数 VALUE 相等的元素
COUNT 的值可以是以下几种 COUNT 的值可以是以下几种

View File

@ -2,6 +2,7 @@ package redis
import ( import (
"context" "context"
"go_dreamfactory/lego/sys/redis/pipe"
"time" "time"
"github.com/go-redis/redis/v8" "github.com/go-redis/redis/v8"
@ -56,6 +57,7 @@ type (
LPush(key string, values ...interface{}) (err error) LPush(key string, values ...interface{}) (err error)
LPushX(key string, values ...interface{}) (err error) LPushX(key string, values ...interface{}) (err error)
LRange(key string, start, end int, v interface{}) (err error) LRange(key string, start, end int, v interface{}) (err error)
LRangeToStringSlice(key string, start, end int) *redis.StringSliceCmd
LRem(key string, count int, target interface{}) (err error) LRem(key string, count int, target interface{}) (err error)
LSet(key string, index int, value interface{}) (err error) LSet(key string, index int, value interface{}) (err error)
Ltrim(key string, start, stop int) (err error) Ltrim(key string, start, stop int) (err error)
@ -127,6 +129,7 @@ type (
ISys interface { ISys interface {
IRedis IRedis
GetClient() IRedis GetClient() IRedis
RedisPipe(ctx context.Context) *pipe.RedisPipe
/*Lock*/ /*Lock*/
NewRedisMutex(key string, opt ...RMutexOption) (result *RedisMutex, err error) NewRedisMutex(key string, opt ...RMutexOption) (result *RedisMutex, err error)
} }
@ -156,7 +159,9 @@ func Close() (err error) {
func GetClient() IRedis { func GetClient() IRedis {
return defsys.GetClient() return defsys.GetClient()
} }
func RedisPipe(ctx context.Context) *pipe.RedisPipe {
return defsys.RedisPipe(ctx)
}
func Context() context.Context { func Context() context.Context {
return defsys.Context() return defsys.Context()
} }
@ -296,6 +301,9 @@ func LPushX(key string, values ...interface{}) (err error) {
func LRange(key string, start, end int, v interface{}) (err error) { func LRange(key string, start, end int, v interface{}) (err error) {
return defsys.LRange(key, start, end, v) return defsys.LRange(key, start, end, v)
} }
func LRangeToStringSlice(key string, start, end int) *redis.StringSliceCmd {
return defsys.LRangeToStringSlice(key, start, end)
}
func LRem(key string, count int, target interface{}) (err error) { func LRem(key string, count int, target interface{}) (err error) {
return defsys.LRem(key, count, target) return defsys.LRem(key, count, target)
} }

View File

@ -0,0 +1,78 @@
package pipe
import (
"context"
"go_dreamfactory/lego/sys/redis/core"
"github.com/go-redis/redis/v8"
)
func NewPipe(ctx context.Context, pipe redis.Pipeliner, codec core.ICodec) *RedisPipe {
return &RedisPipe{
ctx: ctx,
client: pipe,
codec: codec,
}
}
type RedisPipe struct {
ctx context.Context
client redis.Pipeliner
codec core.ICodec
}
func (this *RedisPipe) Exec() ([]redis.Cmder, error) {
return this.client.Exec(this.ctx)
}
/// 命令接口
func (this *RedisPipe) Do(args ...interface{}) *redis.Cmd {
return this.client.Do(this.ctx, args...)
}
///批处理
func (this *RedisPipe) Pipeline() redis.Pipeliner {
return this.client.Pipeline()
}
///批处理
func (this *RedisPipe) Pipelined(fn func(pipe redis.Pipeliner) error) (err error) {
_, err = this.client.Pipelined(this.ctx, fn)
return
}
///事务
func (this *RedisPipe) TxPipelined(fn func(pipe redis.Pipeliner) error) (err error) {
_, err = this.client.TxPipelined(this.ctx, fn)
return
}
//锁
func (this *RedisPipe) Lock(key string, outTime int) (result bool, err error) {
cmd := redis.NewBoolCmd(this.ctx, "set", key, 1, "ex", outTime, "nx")
this.client.Process(this.ctx, cmd)
result, err = cmd.Result()
return
}
//锁
func (this *RedisPipe) UnLock(key string) (err error) {
err = this.Delete(key)
return
}
//lua Script
func (this *RedisPipe) NewScript(src string) *redis.StringCmd {
script := redis.NewScript(src)
return script.Load(this.ctx, this.client)
}
func (this *RedisPipe) Eval(ctx context.Context, script string, keys []string, args ...interface{}) *redis.Cmd {
return this.client.Eval(ctx, script, keys, args...)
}
func (this *RedisPipe) EvalSha(ctx context.Context, sha1 string, keys []string, args ...interface{}) *redis.Cmd {
return this.client.EvalSha(ctx, sha1, keys, args...)
}
func (this *RedisPipe) ScriptExists(ctx context.Context, hashes ...string) *redis.BoolSliceCmd {
return this.client.ScriptExists(ctx, hashes...)
}

197
lego/sys/redis/pipe/hash.go Normal file
View File

@ -0,0 +1,197 @@
package pipe
import (
"go_dreamfactory/lego/sys/redis/core"
"github.com/go-redis/redis/v8"
)
/*
Redis Hdel 命令用于删除哈希表 key 中的一个或多个指定字段不存在的字段将被忽略
*/
func (this *RedisPipe) HDel(key string, fields ...string) (err error) {
agrs := make([]interface{}, 0)
agrs = append(agrs, "HDEL")
agrs = append(agrs, key)
for _, v := range fields {
agrs = append(agrs, v)
}
err = this.client.Do(this.ctx, agrs...).Err()
return
}
/*
Redis Hexists 命令用于查看哈希表的指定字段是否存在
*/
func (this *RedisPipe) HExists(key string, field string) (result bool, err error) {
result, err = this.client.Do(this.ctx, "HEXISTS", key, field).Bool()
return
}
/*
Redis Hmset 命令用于同时将多个 field-value (字段-)对设置到哈希表中
此命令会覆盖哈希表中已存在的字段
如果哈希表不存在会创建一个空哈希表并执行 HMSET 操作
*/
func (this *RedisPipe) HMSet(key string, v interface{}) (err error) {
agrs := make([]interface{}, 0)
agrs = append(agrs, "HMSET")
agrs = append(agrs, key)
var data map[string]string
if data, err = this.codec.MarshalMap(v); err != nil {
return
}
for k, v := range data {
agrs = append(agrs, k, v)
}
err = this.client.Do(this.ctx, agrs...).Err()
return
}
func (this *RedisPipe) HMSetForMap(key string, v map[string]string) (err error) {
agrs := make([]interface{}, 0)
agrs = append(agrs, "HMSET")
agrs = append(agrs, key)
for k, v := range v {
agrs = append(agrs, k, v)
}
err = this.client.Do(this.ctx, agrs...).Err()
return
}
/*
Redis Hget 命令用于返回哈希表中指定字段的值
*/
func (this *RedisPipe) HGet(key string, field string, v interface{}) (err error) {
cmd := redis.NewStringCmd(this.ctx, "HGET", key, field)
this.client.Process(this.ctx, cmd)
var _result []byte
if _result, err = cmd.Bytes(); err == nil {
if len(_result) == 0 {
err = redis.Nil
return
}
err = this.codec.Unmarshal(_result, v)
}
return
}
/*
Redis Hgetall 命令用于返回哈希表中所有的字段和值
在返回值里紧跟每个字段名(field name)之后是字段的值(value)所以返回值的长度是哈希表大小的两倍
*/
func (this *RedisPipe) HGetAll(key string, v interface{}) (err error) {
cmd := redis.NewStringStringMapCmd(this.ctx, "HGETALL", key)
this.client.Process(this.ctx, cmd)
var _result map[string]string
if _result, err = cmd.Result(); err == nil {
if len(_result) == 0 {
err = redis.Nil
return
}
err = this.codec.UnmarshalMap(_result, v)
}
return
}
/*
读取全部hash集合数据到map中
*/
func (this *RedisPipe) HGetAllToMapString(key string) (cmd *redis.StringStringMapCmd) {
return this.client.HGetAll(this.ctx, key)
}
/*
Redis Hincrby 命令用于为哈希表中的字段值加上指定增量值
增量也可以为负数相当于对指定字段进行减法操作
如果哈希表的 key 不存在一个新的哈希表被创建并执行 HINCRBY 命令
如果指定的字段不存在那么在执行命令前字段的值被初始化为 0
对一个储存字符串值的字段执行 HINCRBY 命令将造成一个错误
本操作的值被限制在 64 (bit)有符号数字表示之内
*/
func (this *RedisPipe) HIncrBy(key string, field string, value int) (err error) {
err = this.client.Do(this.ctx, "HINCRBY", key, field, value).Err()
return
}
/*
Redis Hincrbyfloat 命令用于为哈希表中的字段值加上指定浮点数增量值
如果指定的字段不存在那么在执行命令前字段的值被初始化为 0
*/
func (this *RedisPipe) HIncrByFloat(key string, field string, value float32) (err error) {
err = this.client.Do(this.ctx, "HINCRBYFLOAT", key, field, value).Err()
return
}
/*
Redis Hkeys 命令用于获取哈希表中的所有域(field)
*/
func (this *RedisPipe) Hkeys(key string) (result []string, err error) {
cmd := redis.NewStringSliceCmd(this.ctx, "HKEYS", key)
this.client.Process(this.ctx, cmd)
result, err = cmd.Result()
return
}
/*
Redis Hlen 命令用于获取哈希表中字段的数量
*/
func (this *RedisPipe) Hlen(key string) (result int, err error) {
result, err = this.client.Do(this.ctx, "HLEN", key).Int()
return
}
/*
Redis Hmget 命令用于返回哈希表中一个或多个给定字段的值
如果指定的字段不存在于哈希表那么返回一个 nil
*/
func (this *RedisPipe) HMGet(key string, v interface{}, fields ...string) (err error) {
agrs := make([]interface{}, 0)
agrs = append(agrs, "HMGET")
agrs = append(agrs, key)
for _, v := range fields {
agrs = append(agrs, v)
}
cmd := redis.NewStringStringMapCmd(this.ctx, agrs...)
this.client.Process(this.ctx, cmd)
var _result map[string]string
if _result, err = cmd.Result(); err == nil {
if len(_result) == 0 {
err = redis.Nil
return
}
err = this.codec.UnmarshalMap(_result, v)
}
return
}
/*
Redis Hset 命令用于为哈希表中的字段赋值
如果哈希表不存在一个新的哈希表被创建并进行 HSET 操作
如果字段已经存在于哈希表中旧值将被覆盖
*/
func (this *RedisPipe) HSet(key string, field string, value interface{}) (err error) {
var resultvalue []byte
if !core.IsBaseType(value) {
if resultvalue, err = this.codec.Marshal(value); err == nil {
err = this.client.Do(this.ctx, "HSET", key, field, resultvalue).Err()
}
} else {
err = this.client.Do(this.ctx, "HSET", key, field, value).Err()
}
return
}
/*
Redis Hsetnx 命令用于为哈希表中不存在的的字段赋值
如果哈希表不存在一个新的哈希表被创建并进行 HSET 操作
如果字段已经存在于哈希表中操作无效
如果 key 不存在一个新哈希表被创建并执行 HSETNX 命令
*/
func (this *RedisPipe) HSetNX(key string, field string, value interface{}) (err error) {
var resultvalue []byte
if resultvalue, err = this.codec.Marshal(value); err == nil {
err = this.client.Do(this.ctx, "HSETNX", key, field, resultvalue).Err()
}
return
}

View File

@ -0,0 +1,85 @@
package pipe
import (
"time"
)
/* Key *******************************************************************************/
///删除redis key
func (this *RedisPipe) Delete(key string) (err error) {
err = this.client.Do(this.ctx, "DEL", key).Err()
return
}
///判断是否存在key
func (this *RedisPipe) ExistsKey(key string) (iskeep bool, err error) {
iskeep, err = this.client.Do(this.ctx, "EXISTS", key).Bool()
return
}
///设置key的过期时间 单位以秒级
func (this *RedisPipe) Expire(key string, expiration time.Duration) (err error) {
this.client.Expire(this.ctx, key, expiration)
return
}
///设置key的过期时间戳 秒级时间戳
func (this *RedisPipe) ExpireAt(key string, tm time.Time) (err error) {
err = this.client.ExpireAt(this.ctx, key, tm).Err()
return
}
///设置key的过期时间 单位以毫秒级
func (this *RedisPipe) PExpire(key string, expiration time.Duration) (err error) {
err = this.client.PExpire(this.ctx, key, expiration).Err()
return
}
///设置key的过期时间戳 单位以豪秒级
func (this *RedisPipe) PExpireAt(key string, tm time.Time) (err error) {
err = this.client.PExpireAt(this.ctx, key, tm).Err()
return
}
///移除Key的过期时间
func (this *RedisPipe) Persist(key string) (err error) {
err = this.client.Persist(this.ctx, key).Err()
return
}
///获取key剩余过期时间 单位毫秒
func (this *RedisPipe) PTTL(key string) (leftexpire time.Duration, err error) {
leftexpire, err = this.client.PTTL(this.ctx, key).Result()
return
}
///获取key剩余过期时间 单位秒
func (this *RedisPipe) TTL(key string) (leftexpire time.Duration, err error) {
leftexpire, err = this.client.TTL(this.ctx, key).Result()
return
}
///重命名Key
func (this *RedisPipe) Rename(oldkey string, newkey string) (err error) {
err = this.client.Rename(this.ctx, oldkey, newkey).Err()
return
}
///重命名key 在新的 key 不存在时修改 key 的名称
func (this *RedisPipe) RenameNX(oldkey string, newkey string) (err error) {
err = this.client.RenameNX(this.ctx, oldkey, newkey).Err()
return
}
///判断是否存在key pattern:key*
func (this *RedisPipe) Keys(pattern string) (keys []string, err error) {
keys, err = this.client.Keys(this.ctx, pattern).Result()
return
}
///获取键类型
func (this *RedisPipe) Type(key string) (ty string, err error) {
ty, err = this.client.Type(this.ctx, key).Result()
return
}

228
lego/sys/redis/pipe/list.go Normal file
View File

@ -0,0 +1,228 @@
package pipe
import (
"github.com/go-redis/redis/v8"
)
/*
Redis Lindex 命令用于通过索引获取列表中的元素你也可以使用负数下标 -1 表示列表的最后一个元素 -2 表示列表的倒数第二个元素以此类推
*/
func (this *RedisPipe) Lindex(key string, v interface{}) (err error) {
cmd := redis.NewStringCmd(this.ctx, "LINDEX", key)
this.client.Process(this.ctx, cmd)
var _result []byte
if _result, err = cmd.Bytes(); err == nil {
if len(_result) == 0 {
err = redis.Nil
return
}
err = this.codec.Unmarshal(_result, v)
}
return
}
/*
Redis Linsert 命令用于在列表的元素前或者后插入元素当指定元素不存在于列表中时不执行任何操作
当列表不存在时被视为空列表不执行任何操作
如果 key 不是列表类型返回一个错误
*/
func (this *RedisPipe) Linsert(key string, isbefore bool, tager interface{}, value interface{}) (err error) {
var (
tagervalue []byte
resultvalue []byte
)
if tagervalue, err = this.codec.Marshal(tager); err != nil {
return
}
if resultvalue, err = this.codec.Marshal(value); err != nil {
return
}
if isbefore {
err = this.client.Do(this.ctx, "LINSERT", key, "BEFORE", tagervalue, resultvalue).Err()
} else {
err = this.client.Do(this.ctx, "LINSERT", key, "AFTER", tagervalue, resultvalue).Err()
}
return
}
/*
Redis Llen 命令用于返回列表的长度 如果列表 key 不存在 key 被解释为一个空列表返回 0 如果 key 不是列表类型返回一个错误
*/
func (this *RedisPipe) Llen(key string) *redis.IntCmd {
return this.client.LLen(this.ctx, key)
}
/*
Redis Lpop 命令用于移除并返回列表的第一个元素
*/
func (this *RedisPipe) LPop(key string, v interface{}) (err error) {
cmd := redis.NewStringCmd(this.ctx, "LPOP", key)
this.client.Process(this.ctx, cmd)
var _result []byte
if _result, err = cmd.Bytes(); err == nil {
err = this.codec.Unmarshal(_result, v)
}
return
}
/*
Redis Lpush 命令将一个或多个值插入到列表头部 如果 key 不存在一个空列表会被创建并执行 LPUSH 操作 key 存在但不是列表类型时返回一个错误
*/
func (this *RedisPipe) LPush(key string, values ...interface{}) (err error) {
agrs := make([]interface{}, 0)
agrs = append(agrs, "LPUSH")
for _, v := range values {
result, _ := this.codec.Marshal(v)
agrs = append(agrs, result)
}
err = this.client.Do(this.ctx, agrs...).Err()
return
}
/*
Redis Lpushx 将一个值插入到已存在的列表头部列表不存在时操作无效
*/
func (this *RedisPipe) LPushX(key string, values ...interface{}) (err error) {
agrs := make([]interface{}, 0)
agrs = append(agrs, "LPUSHX")
for _, v := range values {
result, _ := this.codec.Marshal(v)
agrs = append(agrs, result)
}
err = this.client.Do(this.ctx, agrs...).Err()
return
}
/*
Redis Lrange 返回列表中指定区间内的元素区间以偏移量 START END 指定 其中 0 表示列表的第一个元素 1 表示列表的第二个元素
以此类推 你也可以使用负数下标 -1 表示列表的最后一个元素 -2 表示列表的倒数第二个元素以此类推
*/
func (this *RedisPipe) LRange(key string, start, end int, v interface{}) (err error) {
var _result []string
cmd := redis.NewStringSliceCmd(this.ctx, "LRANGE", key, start, end)
this.client.Process(this.ctx, cmd)
if _result, err = cmd.Result(); err == nil {
err = this.codec.UnmarshalSlice(_result, v)
}
return
}
/*
Redis Lrange 返回列表中指定区间内的元素区间以偏移量 START END 指定 其中 0 表示列表的第一个元素 1 表示列表的第二个元素
以此类推 你也可以使用负数下标 -1 表示列表的最后一个元素 -2 表示列表的倒数第二个元素以此类推
*/
func (this *RedisPipe) LRangeToStringSlice(key string, start, end int) *redis.StringSliceCmd {
cmd := redis.NewStringSliceCmd(this.ctx, "LRANGE", key, start, end)
this.client.Process(this.ctx, cmd)
return cmd
}
/*
Redis Lrem 根据参数 COUNT 的值移除列表中与参数 VALUE 相等的元素
COUNT 的值可以是以下几种
count > 0 : 从表头开始向表尾搜索移除与 VALUE 相等的元素数量为 COUNT
count < 0 : 从表尾开始向表头搜索移除与 VALUE 相等的元素数量为 COUNT 的绝对值
count = 0 : 移除表中所有与 VALUE 相等的值
*/
func (this *RedisPipe) LRem(key string, count int, target interface{}) (err error) {
var resultvalue []byte
if resultvalue, err = this.codec.Marshal(target); err != nil {
return
}
err = this.client.Do(this.ctx, "LREM", key, count, resultvalue).Err()
return
}
/*
Redis Lset 通过索引来设置元素的值
当索引参数超出范围或对一个空列表进行 LSET 返回一个错误
*/
func (this *RedisPipe) LSet(key string, index int, value interface{}) (err error) {
var resultvalue []byte
if resultvalue, err = this.codec.Marshal(value); err == nil {
return
}
err = this.client.Do(this.ctx, "LSET", key, index, resultvalue).Err()
return
}
/*
Redis Ltrim 对一个列表进行修剪(trim)就是说让列表只保留指定区间内的元素不在指定区间之内的元素都将被删除
下标 0 表示列表的第一个元素 1 表示列表的第二个元素以此类推 你也可以使用负数下标
-1 表示列表的最后一个元素 -2 表示列表的倒数第二个元素以此类推
*/
func (this *RedisPipe) Ltrim(key string, start, stop int) (err error) {
err = this.client.Do(this.ctx, "LTRIM", key, start, stop).Err()
return
}
/*
Redis Rpop 命令用于移除列表的最后一个元素返回值为移除的元素
*/
func (this *RedisPipe) Rpop(key string, v interface{}) (err error) {
cmd := redis.NewStringCmd(this.ctx, "RPOP", key)
this.client.Process(this.ctx, cmd)
var _result []byte
if _result, err = cmd.Bytes(); err == nil {
err = this.codec.Unmarshal(_result, v)
}
return
}
/*
Redis Rpoplpush 命令用于移除列表的最后一个元素并将该元素添加到另一个列表并返回
*/
func (this *RedisPipe) RPopLPush(oldkey string, newkey string, v interface{}) (err error) {
cmd := redis.NewStringCmd(this.ctx, "RPOPLPUSH", oldkey, newkey)
this.client.Process(this.ctx, cmd)
var _result []byte
if _result, err = cmd.Bytes(); err == nil {
err = this.codec.Unmarshal(_result, v)
}
return
}
/*
Redis Rpush 命令用于将一个或多个值插入到列表的尾部(最右边)
如果列表不存在一个空列表会被创建并执行 RPUSH 操作 当列表存在但不是列表类型时返回一个错误
注意 Redis 2.4 版本以前的 RPUSH 命令都只接受单个 value
*/
func (this *RedisPipe) RPush(key string, values ...interface{}) (err error) {
agrs := make([]interface{}, 0)
agrs = append(agrs, "RPUSH")
for _, v := range values {
result, _ := this.codec.Marshal(v)
agrs = append(agrs, result)
}
err = this.client.Do(this.ctx, agrs...).Err()
return
}
/*
Redis Rpush 命令用于将一个或多个值插入到列表的尾部(最右边)
如果列表不存在一个空列表会被创建并执行 RPUSH 操作 当列表存在但不是列表类型时返回一个错误
注意 Redis 2.4 版本以前的 RPUSH 命令都只接受单个 value
*/
func (this *RedisPipe) RPushForStringSlice(key string, values ...string) (err error) {
agrs := make([]interface{}, 0)
agrs = append(agrs, "RPUSH")
for _, v := range values {
agrs = append(agrs, v)
}
err = this.client.Do(this.ctx, agrs...).Err()
return
}
/*
Redis Rpushx 命令用于将一个值插入到已存在的列表尾部(最右边)如果列表不存在操作无效
*/
func (this *RedisPipe) RPushX(key string, values ...interface{}) (err error) {
agrs := make([]interface{}, 0)
agrs = append(agrs, "RPUSHX")
for _, v := range values {
result, _ := this.codec.Marshal(v)
agrs = append(agrs, result)
}
err = this.client.Do(this.ctx, agrs...).Err()
return
}

159
lego/sys/redis/pipe/set.go Normal file
View File

@ -0,0 +1,159 @@
package pipe
/*
Redis Sadd 命令将一个或多个成员元素加入到集合中已经存在于集合的成员元素将被忽略
假如集合 key 不存在则创建一个只包含添加的元素作成员的集合
当集合 key 不是集合类型时返回一个错误
*/
func (this *RedisPipe) SAdd(key string, values ...interface{}) (err error) {
agrs := make([]interface{}, 0)
agrs = append(agrs, "SADD")
agrs = append(agrs, key)
for _, v := range values {
result, _ := this.codec.Marshal(v)
agrs = append(agrs, result)
}
err = this.client.Do(this.ctx, agrs...).Err()
return
}
/*
Redis Scard 命令返回集合中元素的数量
*/
func (this *RedisPipe) SCard(key string) (result int64, err error) {
result, err = this.client.SCard(this.ctx, key).Result()
return
}
/*
Redis Sdiff 命令返回第一个集合与其他集合之间的差异也可以认为说第一个集合中独有的元素不存在的集合 key 将视为空集
差集的结果来自前面的 FIRST_KEY ,而不是后面的 OTHER_KEY1也不是整个 FIRST_KEY OTHER_KEY1..OTHER_KEYN 的差集
实例:
*/
func (this *RedisPipe) SDiff(v interface{}, keys ...string) (err error) {
var _result []string
cmd := this.client.SDiff(this.ctx, keys...)
if _result, err = cmd.Result(); err == nil {
err = this.codec.UnmarshalSlice(_result, v)
}
return
}
/*
Redis Sdiffstore 命令将给定集合之间的差集合存储在指定的集合中
*/
func (this *RedisPipe) SDiffStore(destination string, keys ...string) (result int64, err error) {
result, err = this.client.SDiffStore(this.ctx, destination, keys...).Result()
return
}
/*
Redis Sismember 命令返回给定所有给定集合的交集 不存在的集合 key 被视为空集 当给定集合当中有一个空集时结果也为空集(根据集合运算定律)
*/
func (this *RedisPipe) SInter(v interface{}, keys ...string) (err error) {
var _result []string
cmd := this.client.SInter(this.ctx, keys...)
if _result, err = cmd.Result(); err == nil {
err = this.codec.UnmarshalSlice(_result, v)
}
return
}
/*
Redis Sinterstore 决定将给定集合之间的交集在指定的集合中如果指定的集合已经存在则将其覆盖
*/
func (this *RedisPipe) SInterStore(destination string, keys ...string) (result int64, err error) {
result, err = this.client.SInterStore(this.ctx, destination, keys...).Result()
return
}
/*
Redis Sismember 命令判断成员元素是否是集合的成员
*/
func (this *RedisPipe) Sismember(key string, value interface{}) (iskeep bool, err error) {
iskeep, err = this.client.SIsMember(this.ctx, key, value).Result()
return
}
/*
Redis Smembers 号召返回集合中的所有成员
*/
func (this *RedisPipe) SMembers(v interface{}, key string) (err error) {
var _result []string
cmd := this.client.SMembers(this.ctx, key)
if _result, err = cmd.Result(); err == nil {
err = this.codec.UnmarshalSlice(_result, v)
}
return
}
/*
Redis Smove 命令将指定成员 member 元素从 source 集合移动到 destination 集合
SMOVE 是原子性操作
如果 source 集合不存在或不包含指定的 member 元素 SMOVE 命令不执行任何操作仅返回 0 否则 member 元素从 source 集合中被移除并添加到 destination 集合中去
destination 集合已经包含 member 元素时 SMOVE 命令只是简单地将 source 集合中的 member 元素删除
source destination 不是集合类型时返回一个错误
*/
func (this *RedisPipe) SMove(source string, destination string, member interface{}) (result bool, err error) {
result, err = this.client.SMove(this.ctx, source, destination, member).Result()
return
}
/*
Redis Spop命令用于移除集合中的指定键的一个或多个随机元素移除后会返回移除的元素
该命令类似于Srandmember命令但SPOP将随机元素从集合中移除并返回而Srandmember则返回元素而不是对集合进行任何改动
*/
func (this *RedisPipe) Spop(key string) (result string, err error) {
result, err = this.client.SPop(this.ctx, key).Result()
return
}
/*
Redis Srandmember 命令用于返回集合中的一个随机元素
Redis 2.6 版本开始 Srandmember 命令接受可选的 count 参数
如果 count 为正数且小于集合基数那么命令返回一个包含 count 个元素的数组数组中的元素各不相同如果 count 大于等于集合基数那么返回整个集合
如果 count 为负数那么命令返回一个数组数组中的元素可能会重复出现多次而数组的长度为 count 的绝对值
该操作和 SPOP 相似 SPOP 将随机元素从集合中移除并返回 Srandmember 则仅仅返回随机元素而不对集合进行任何改动
*/
func (this *RedisPipe) Srandmember(key string) (result string, err error) {
result, err = this.client.SRandMember(this.ctx, key).Result()
return
}
/*
Redis Srem 呼吁用于移除集合中的一个或多个元素元素不存在的元素元素会被忽略
当键不是集合类型返回一个错误
Redis 2.4 版本以前SREM 只接受个别成员值
*/
func (this *RedisPipe) SRem(key string, members ...interface{}) (result int64, err error) {
result, err = this.client.SRem(this.ctx, key, members...).Result()
return
}
/*
Redis Sunion 命令返回给定集合的并集
*/
func (this *RedisPipe) SUnion(v interface{}, keys ...string) (err error) {
var _result []string
cmd := this.client.SUnion(this.ctx, keys...)
if _result, err = cmd.Result(); err == nil {
err = this.codec.UnmarshalSlice(_result, v)
}
return
}
/*
Redis Sunionstore 命令将给定集合的并集存储在指定的集合 destination 如果 destination 已经存在则将其覆盖
*/
func (this *RedisPipe) Sunionstore(destination string, keys ...string) (result int64, err error) {
result, err = this.client.SUnionStore(this.ctx, destination, keys...).Result()
return
}
/*
Redis Sscan 用于继承集合中键的元素Sscan 继承自Scan
*/
func (this *RedisPipe) Sscan(key string, _cursor uint64, match string, count int64) (keys []string, cursor uint64, err error) {
keys, cursor, err = this.client.SScan(this.ctx, key, _cursor, match, count).Result()
return
}

View File

@ -0,0 +1,182 @@
package pipe
import (
"time"
"github.com/go-redis/redis/v8"
)
/* String *******************************************************************************/
/*
命令用于设置给定 key 的值如果 key 已经存储其他值 SET 就覆写旧值且无视类型
*/
func (this *RedisPipe) Set(key string, value interface{}, expiration time.Duration) (err error) {
var result []byte
if result, err = this.codec.Marshal(value); err != nil {
return
}
err = this.client.Set(this.ctx, key, result, expiration).Err()
return
}
/*
指定的 key 不存在时 key 设置指定的值
*/
func (this *RedisPipe) SetNX(key string, value interface{}) (result int64, err error) {
cmd := redis.NewIntCmd(this.ctx, "SETNX", key, value)
this.client.Process(this.ctx, cmd)
result, err = cmd.Result()
// }
return
}
/*
同时设置一个或多个 key-value
*/
func (this *RedisPipe) MSet(v map[string]interface{}) (err error) {
agrs := make([]interface{}, 0)
agrs = append(agrs, "MSET")
for k, v := range v {
result, _ := this.codec.Marshal(v)
agrs = append(agrs, k, result)
}
err = this.client.Do(this.ctx, agrs...).Err()
return
}
/*
命令用于所有给定 key 都不存在时同时设置一个或多个 key-value
*/
func (this *RedisPipe) MSetNX(v map[string]interface{}) (err error) {
agrs := make([]interface{}, 0)
agrs = append(agrs, "MSETNX")
for k, v := range v {
result, _ := this.codec.Marshal(v)
agrs = append(agrs, k, result)
}
err = this.client.Do(this.ctx, agrs...).Err()
return
}
/*
Redis Incr 命令将 key 中储存的数字值增一
如果 key 不存在那么 key 的值会先被初始化为 0 然后再执行 INCR 操作
如果值包含错误的类型或字符串类型的值不能表示为数字那么返回一个错误
本操作的值限制在 64 (bit)有符号数字表示之内
*/
func (this *RedisPipe) Incr(key string) (err error) {
err = this.client.Do(this.ctx, "INCR", key).Err()
return
}
/*
Redis Incrby 命令将 key 中储存的数字加上指定的增量值
如果 key 不存在那么 key 的值会先被初始化为 0 然后再执行 INCRBY 命令
如果值包含错误的类型或字符串类型的值不能表示为数字那么返回一个错误
本操作的值限制在 64 (bit)有符号数字表示之内
*/
func (this *RedisPipe) IncrBY(key string, value int) (err error) {
err = this.client.Do(this.ctx, "INCRBY", key, value).Err()
return
}
/*
Redis Incrbyfloat 命令为 key 中所储存的值加上指定的浮点数增量值
如果 key 不存在那么 INCRBYFLOAT 会先将 key 的值设为 0 再执行加法操作
*/
func (this *RedisPipe) Incrbyfloat(key string, value float32) (err error) {
err = this.client.Do(this.ctx, "INCRBYFLOAT", key, value).Err()
return
}
/*
Redis Decr 命令将 key 中储存的数字值减一
如果 key 不存在那么 key 的值会先被初始化为 0 然后再执行 DECR 操作
如果值包含错误的类型或字符串类型的值不能表示为数字那么返回一个错误
本操作的值限制在 64 (bit)有符号数字表示之内
*/
func (this *RedisPipe) Decr(key string, value int) (err error) {
err = this.client.Do(this.ctx, "DECR", key, value).Err()
return
}
/*
Redis Decrby 命令将 key 所储存的值减去指定的减量值
如果 key 不存在那么 key 的值会先被初始化为 0 然后再执行 DECRBY 操作
如果值包含错误的类型或字符串类型的值不能表示为数字那么返回一个错误
本操作的值限制在 64 (bit)有符号数字表示之内
*/
func (this *RedisPipe) DecrBy(key string, value int) (err error) {
err = this.client.Do(this.ctx, "DECRBY", key, value).Err()
return
}
/*
Redis Append 命令用于为指定的 key 追加值
如果 key 已经存在并且是一个字符串 APPEND 命令将 value 追加到 key 原来的值的末尾
如果 key 不存在 APPEND 就简单地将给定 key 设为 value 就像执行 SET key value 一样
*/
func (this *RedisPipe) Append(key string, value interface{}) (err error) {
var result []byte
if result, err = this.codec.Marshal(value); err != nil {
return
}
err = this.client.Do(this.ctx, "APPEND", key, result).Err()
return
}
/*
命令用于设置给定 key 的值如果 key 已经存储其他值 SET 就覆写旧值且无视类型
*/
func (this *RedisPipe) Get(key string, value interface{}) (err error) {
var result []byte
if result, err = this.client.Get(this.ctx, key).Bytes(); err == nil {
err = this.codec.Unmarshal(result, value)
}
return
}
/*
设置指定 key 的值并返回 key 的旧值
*/
func (this *RedisPipe) GetSet(key string, value interface{}, result interface{}) (err error) {
var (
_value []byte
)
if _value, err = this.codec.Marshal(value); err == nil {
cmd := redis.NewStringCmd(this.ctx, "GETSET", key, _value)
this.client.Process(this.ctx, cmd)
var _result []byte
if _result, err = cmd.Bytes(); err == nil {
err = this.codec.Unmarshal(_result, result)
}
}
return
}
/*
返回所有(一个或多个)给定 key 的值 如果给定的 key 里面有某个 key 不存在那么这个 key 返回特殊值 nil
*/
func (this *RedisPipe) MGet(v interface{}, keys ...string) (err error) {
agrs := make([]interface{}, 0)
agrs = append(agrs, "MGET")
for _, v := range keys {
agrs = append(agrs, v)
}
cmd := redis.NewStringSliceCmd(this.ctx, agrs...)
this.client.Process(this.ctx, cmd)
var result []string
if result, err = cmd.Result(); err != nil {
return
}
err = this.codec.UnmarshalSlice(result, v)
return
}
///判断是否存在key pattern:key*
func (this *RedisPipe) INCRBY(key string, amount int64) (result int64, err error) {
cmd := redis.NewIntCmd(this.ctx, "INCRBY", key, amount)
this.client.Process(this.ctx, cmd)
result, err = cmd.Result()
return
}

185
lego/sys/redis/pipe/zset.go Normal file
View File

@ -0,0 +1,185 @@
package pipe
import (
"github.com/go-redis/redis/v8"
)
/*
Redis ZAdd 向有序集合添加一个或多个成员或者更新已存在成员的分数
*/
func (this *RedisPipe) ZAdd(key string, members ...*redis.Z) (err error) {
this.client.ZAdd(this.ctx, key, members...)
return
}
/*
Redis Zcard 用于计算集合中元素的数量
*/
func (this *RedisPipe) ZCard(key string) (result int64, err error) {
result, err = this.client.ZCard(this.ctx, key).Result()
return
}
/*
Redis ZCount 用于计算集合中指定的范围内的数量
*/
func (this *RedisPipe) ZCount(key string, min string, max string) (result int64, err error) {
result, err = this.client.ZCount(this.ctx, key, min, max).Result()
return
}
/*
Redis ZIncrBy 有序集合中对指定成员的分数加上增量 increment
*/
func (this *RedisPipe) ZIncrBy(key string, increment float64, member string) (result float64, err error) {
result, err = this.client.ZIncrBy(this.ctx, key, increment, member).Result()
return
}
/*
Redis ZInterStore 计算给定的一个或多个有序集的交集并将结果集存储在新的有序集合 destination
*/
func (this *RedisPipe) ZInterStore(destination string, store *redis.ZStore) (result int64, err error) {
result, err = this.client.ZInterStore(this.ctx, destination, store).Result()
return
}
/*
Redis ZLexCount 在有序集合中计算指定字典区间内成员数量
*/
func (this *RedisPipe) ZLexCount(key string, min string, max string) (result int64, err error) {
result, err = this.client.ZLexCount(this.ctx, key, min, max).Result()
return
}
/*
Redis ZRange 通过索引区间返回有序集合指定区间内的成员
*/
func (this *RedisPipe) ZRange(key string, start int64, stop int64, v interface{}) (err error) {
var _result []string
cmd := this.client.ZRange(this.ctx, key, start, stop)
if _result, err = cmd.Result(); err == nil {
err = this.codec.UnmarshalSlice(_result, v)
}
return
}
/*
Redis ZRangeByLex 通过字典区间返回有序集合的成员
*/
func (this *RedisPipe) ZRangeByLex(key string, opt *redis.ZRangeBy, v interface{}) (err error) {
var _result []string
cmd := this.client.ZRangeByLex(this.ctx, key, opt)
if _result, err = cmd.Result(); err == nil {
err = this.codec.UnmarshalSlice(_result, v)
}
return
}
/*
Redis ZRangeByScore 通过分数返回有序集合指定区间内的成员
*/
func (this *RedisPipe) ZRangeByScore(key string, opt *redis.ZRangeBy, v interface{}) (err error) {
var _result []string
cmd := this.client.ZRangeByScore(this.ctx, key, opt)
if _result, err = cmd.Result(); err == nil {
err = this.codec.UnmarshalSlice(_result, v)
}
return
}
/*
Redis ZRank 返回有序集合中指定成员的索引
*/
func (this *RedisPipe) ZRank(key string, member string) (result int64, err error) {
result, err = this.client.ZRank(this.ctx, key, member).Result()
return
}
/*
Redis ZRem 移除有序集合中的一个或多个成员
*/
func (this *RedisPipe) ZRem(key string, members ...interface{}) (result int64, err error) {
result, err = this.client.ZRem(this.ctx, key, members...).Result()
return
}
/*
Redis ZRemRangeByLex 移除有序集合中给定的字典区间的所有成员
*/
func (this *RedisPipe) ZRemRangeByLex(key string, min string, max string) (result int64, err error) {
result, err = this.client.ZRemRangeByLex(this.ctx, key, min, max).Result()
return
}
/*
Redis ZRemRangeByRank 移除有序集合中给定的排名区间的所有成员
*/
func (this *RedisPipe) ZRemRangeByRank(key string, start int64, stop int64) (result int64, err error) {
result, err = this.client.ZRemRangeByRank(this.ctx, key, start, stop).Result()
return
}
/*
Redis ZRemRangeByScore 移除有序集合中给定的分数区间的所有成员
*/
func (this *RedisPipe) ZRemRangeByScore(key string, min string, max string) (result int64, err error) {
result, err = this.client.ZRemRangeByScore(this.ctx, key, min, max).Result()
return
}
/*
Redis ZRevRange 返回有序集中指定区间内的成员通过索引分数从高到低 ZREVRANGE
*/
func (this *RedisPipe) ZRevRange(key string, start int64, stop int64, v interface{}) (err error) {
var _result []string
cmd := this.client.ZRevRange(this.ctx, key, start, stop)
if _result, err = cmd.Result(); err == nil {
err = this.codec.UnmarshalSlice(_result, v)
}
return
}
/*
Redis ZRevRangeByScore 返回有序集中指定分数区间内的成员分数从高到低排序
*/
func (this *RedisPipe) ZRevRangeByScore(key string, opt *redis.ZRangeBy, v interface{}) (err error) {
var _result []string
cmd := this.client.ZRevRangeByScore(this.ctx, key, opt)
if _result, err = cmd.Result(); err == nil {
err = this.codec.UnmarshalSlice(_result, v)
}
return
}
/*
Redis ZRevRank 返回有序集中指定分数区间内的成员分数从高到低排序
*/
func (this *RedisPipe) ZRevRank(key string, member string) (result int64, err error) {
result, err = this.client.ZRevRank(this.ctx, key, member).Result()
return
}
/*
Redis ZScore 返回有序集中指定分数区间内的成员分数从高到低排序
*/
func (this *RedisPipe) ZScore(key string, member string) (result float64, err error) {
result, err = this.client.ZScore(this.ctx, key, member).Result()
return
}
/*
Redis ZScore 返回有序集中指定分数区间内的成员分数从高到低排序 ZUNIONSTORE
*/
func (this *RedisPipe) ZUnionStore(dest string, store *redis.ZStore) (result int64, err error) {
result, err = this.client.ZUnionStore(this.ctx, dest, store).Result()
return
}
/*
Redis ZScan 迭代有序集合中的元素包括元素成员和元素分值
*/
func (this *RedisPipe) ZScan(key string, _cursor uint64, match string, count int64) (keys []string, cursor uint64, err error) {
keys, cursor, err = this.client.ZScan(this.ctx, key, _cursor, match, count).Result()
return
}

View File

@ -6,6 +6,7 @@ import (
"time" "time"
"go_dreamfactory/lego/sys/redis/cluster" "go_dreamfactory/lego/sys/redis/cluster"
"go_dreamfactory/lego/sys/redis/pipe"
"go_dreamfactory/lego/sys/redis/single" "go_dreamfactory/lego/sys/redis/single"
"go_dreamfactory/lego/utils/codec/json" "go_dreamfactory/lego/utils/codec/json"
@ -54,10 +55,12 @@ func (this *Redis) GetClient() IRedis {
func (this *Redis) Context() context.Context { func (this *Redis) Context() context.Context {
return this.client.Context() return this.client.Context()
} }
func (this *Redis) Do(ctx context.Context, args ...interface{}) *redis.Cmd { func (this *Redis) Do(ctx context.Context, args ...interface{}) *redis.Cmd {
return this.client.Do(ctx, args...) return this.client.Do(ctx, args...)
} }
func (this *Redis) RedisPipe(ctx context.Context) *pipe.RedisPipe {
return pipe.NewPipe(ctx, this.client.Pipeline(), this)
}
func (this *Redis) Pipeline() redis.Pipeliner { func (this *Redis) Pipeline() redis.Pipeliner {
return this.client.Pipeline() return this.client.Pipeline()
} }
@ -182,6 +185,9 @@ func (this *Redis) LPushX(key string, values ...interface{}) (err error) {
func (this *Redis) LRange(key string, start, end int, v interface{}) (err error) { func (this *Redis) LRange(key string, start, end int, v interface{}) (err error) {
return this.client.LRange(key, start, end, v) return this.client.LRange(key, start, end, v)
} }
func (this *Redis) LRangeToStringSlice(key string, start, end int) *redis.StringSliceCmd {
return this.client.LRangeToStringSlice(key, start, end)
}
func (this *Redis) LRem(key string, count int, target interface{}) (err error) { func (this *Redis) LRem(key string, count int, target interface{}) (err error) {
return this.client.LRem(key, count, target) return this.client.LRem(key, count, target)
} }

View File

@ -103,6 +103,15 @@ func (this *Redis) LRange(key string, start, end int, v interface{}) (err error)
} }
return return
} }
/*
Redis Lrange 返回列表中指定区间内的元素区间以偏移量 START END 指定 其中 0 表示列表的第一个元素 1 表示列表的第二个元素
以此类推 你也可以使用负数下标 -1 表示列表的最后一个元素 -2 表示列表的倒数第二个元素以此类推
*/
func (this *Redis) LRangeToStringSlice(key string, start, end int) *redis.StringSliceCmd {
cmd := redis.NewStringSliceCmd(this.client.Context(), "LRANGE", key, start, end)
this.client.Process(this.client.Context(), cmd)
return cmd
}
/* /*
Redis Lrem 根据参数 COUNT 的值移除列表中与参数 VALUE 相等的元素 Redis Lrem 根据参数 COUNT 的值移除列表中与参数 VALUE 相等的元素

View File

@ -54,7 +54,7 @@ func (this *apiComp) Send(session comm.IUserSession, req *pb.ChatSendReq) (code
} }
switch msg.Channel { switch msg.Channel {
case pb.ChatChannel_World: case pb.ChatChannel_World:
if err = this.module.modelChat.addChatMsg(worldchatkey, max, msg); err != nil { if err = this.module.modelChat.addChatMsg(worldchatkey, int64(max), msg); err != nil {
code = pb.ErrorCode_DBError code = pb.ErrorCode_DBError
return return
} }
@ -65,7 +65,7 @@ func (this *apiComp) Send(session comm.IUserSession, req *pb.ChatSendReq) (code
break break
case pb.ChatChannel_Union: case pb.ChatChannel_Union:
msg.UnionId = req.TargetId msg.UnionId = req.TargetId
if err = this.module.modelChat.addChatMsg(fmt.Sprintf("%s:%s", unionchatkey, req.TargetId), max_chat, msg); err != nil { if err = this.module.modelChat.addChatMsg(fmt.Sprintf("%s:%s", unionchatkey, req.TargetId), int64(max_chat), msg); err != nil {
code = pb.ErrorCode_DBError code = pb.ErrorCode_DBError
return return
} }

View File

@ -48,7 +48,7 @@ func (this *apiComp) SpanSend(session comm.IUserSession, req *pb.ChatSpanSendReq
} }
switch msg.Channel { switch msg.Channel {
case pb.ChatChannel_CrossServer: case pb.ChatChannel_CrossServer:
if err = this.module.modelChat.addChatMsg(fmt.Sprintf("%s:%d--%d", crosschatkey, group, userexpand.Chatchannel), max_chat, msg); err != nil { if err = this.module.modelChat.addChatMsg(fmt.Sprintf("%s:%d--%d", crosschatkey, group, userexpand.Chatchannel), int64(max_chat), msg); err != nil {
code = pb.ErrorCode_DBError code = pb.ErrorCode_DBError
return return
} }

View File

@ -6,9 +6,9 @@ import (
"go_dreamfactory/comm" "go_dreamfactory/comm"
"go_dreamfactory/lego/core" "go_dreamfactory/lego/core"
"go_dreamfactory/lego/sys/redis" "go_dreamfactory/lego/sys/redis"
"go_dreamfactory/lego/utils/codec/json"
"go_dreamfactory/modules" "go_dreamfactory/modules"
"go_dreamfactory/pb" "go_dreamfactory/pb"
"strings"
"go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo"
@ -28,9 +28,9 @@ type modelChatComp struct {
//组件初始化接口 //组件初始化接口
func (this *modelChatComp) Init(service core.IService, module core.IModule, comp core.IModuleComp, opt core.IModuleOptions) (err error) { func (this *modelChatComp) Init(service core.IService, module core.IModule, comp core.IModuleComp, opt core.IModuleOptions) (err error) {
this.TableName = comm.TableChat
this.MCompModel.Init(service, module, comp, opt) this.MCompModel.Init(service, module, comp, opt)
this.module = module.(*Chat) this.module = module.(*Chat)
this.TableName = "chat"
//创建uid索引 //创建uid索引
this.DB.CreateIndex(core.SqlTable(this.TableName), mongo.IndexModel{ this.DB.CreateIndex(core.SqlTable(this.TableName), mongo.IndexModel{
Keys: bsonx.Doc{{Key: "ruid", Value: bsonx.Int32(1)}}, Keys: bsonx.Doc{{Key: "ruid", Value: bsonx.Int32(1)}},
@ -66,7 +66,6 @@ func (this *modelChatComp) QueryUserMsg(uid string) (result []*pb.DBChat, err er
func (this *modelChatComp) GetChatQueue(channel pb.ChatChannel, union, group, area int32) (result []*pb.DBChat, err error) { func (this *modelChatComp) GetChatQueue(channel pb.ChatChannel, union, group, area int32) (result []*pb.DBChat, err error) {
var ( var (
key string key string
cdata []map[string]string
find bson.M find bson.M
c *mongo.Cursor c *mongo.Cursor
n int n int
@ -97,17 +96,8 @@ func (this *modelChatComp) GetChatQueue(channel pb.ChatChannel, union, group, ar
if readmax_chat, err = this.module.configure.GetChannelReadRecordNum(); err != nil { if readmax_chat, err = this.module.configure.GetChannelReadRecordNum(); err != nil {
return return
} }
if cdata, err = this.Batchgetqueues(key, readmax_chat); err == nil { result = make([]*pb.DBChat, 0)
result = make([]*pb.DBChat, len(cdata)) err = this.GetQueues(key, int(readmax_chat), &result)
for i, v := range cdata {
chat := &pb.DBChat{}
if err = json.UnmarshalMap(v, chat); err != nil {
return
}
result[i] = chat
}
}
if err == redis.RedisNil { if err == redis.RedisNil {
//query from mgo //query from mgo
if c, err = this.DB.Find(core.SqlTable(this.TableName), find); err != nil { if c, err = this.DB.Find(core.SqlTable(this.TableName), find); err != nil {
@ -123,7 +113,7 @@ func (this *modelChatComp) GetChatQueue(channel pb.ChatChannel, union, group, ar
n++ n++
} }
if len(result) > 0 { if len(result) > 0 {
this.addChatMsg(key, max_chat, result...) this.addChatMsg(key, int64(max_chat), result...)
} }
} }
} }
@ -244,27 +234,17 @@ func (this *modelChatComp) SaveUserMsg(msg *pb.DBChat) (err error) {
return return
} }
func (this *modelChatComp) addChatMsg(key string, count int32, msgs ...*pb.DBChat) (err error) { func (this *modelChatComp) addChatMsg(key string, count int64, msgs ...*pb.DBChat) (err error) {
var ( var (
tempdata map[string]string data map[string]*pb.DBChat = make(map[string]*pb.DBChat, len(msgs))
outkey []string values []interface{} = make([]interface{}, len(msgs))
ks []string outkey []string
vs []map[string]string
values []interface{}
) )
ks = make([]string, len(msgs))
vs = make([]map[string]string, len(msgs))
values = make([]interface{}, len(msgs))
for i, v := range msgs { for i, v := range msgs {
if tempdata, err = json.MarshalMap(v); err != nil { data[fmt.Sprintf("%s-%s", key, v.Id)] = v
this.module.Errorf("err:%v", err)
return
}
ks[i] = fmt.Sprintf("%s-%s", key, v.Id)
vs[i] = tempdata
values[i] = v values[i] = v
} }
if outkey, err = this.Batchsetqueues(key, count, ks, vs); err != nil { if outkey, err = this.AddQueues(key, count, data); err != nil {
this.module.Errorf("err:%v", err) this.module.Errorf("err:%v", err)
return return
} }
@ -273,7 +253,14 @@ func (this *modelChatComp) addChatMsg(key string, count int32, msgs ...*pb.DBCha
return return
} }
if len(outkey) > 0 { if len(outkey) > 0 {
if err = this.DeleteModelLogs(this.TableName, "", bson.M{"_id": bson.M{"$in": outkey}}); err != nil { delkeys := make([]string, 0)
for _, v := range outkey {
temp := strings.Split(v, "_")
if len(temp) == 2 {
delkeys = append(delkeys, temp[1])
}
}
if err = this.DeleteModelLogs(this.TableName, "", bson.M{"_id": bson.M{"$in": delkeys}}); err != nil {
this.module.Errorf("err:%v", err) this.module.Errorf("err:%v", err)
return return
} }

View File

@ -1,667 +1,123 @@
package modules package modules
import ( import (
"context"
"fmt"
"go_dreamfactory/comm"
"go_dreamfactory/lego/core" "go_dreamfactory/lego/core"
"go_dreamfactory/lego/core/cbase" "go_dreamfactory/lego/core/cbase"
"go_dreamfactory/lego/sys/log"
"go_dreamfactory/lego/sys/mgo" "go_dreamfactory/lego/sys/mgo"
"go_dreamfactory/lego/sys/redis" "go_dreamfactory/lego/sys/redis"
"go_dreamfactory/lego/utils/codec"
"go_dreamfactory/lego/utils/codec/codecore"
"go_dreamfactory/lego/utils/codec/json"
"go_dreamfactory/sys/db" "go_dreamfactory/sys/db"
"reflect" "log"
"unsafe"
"github.com/modern-go/reflect2"
"go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
"go.mongodb.org/mongo-driver/mongo"
) )
var defconf = &codecore.Config{
SortMapKeys: true,
IndentionStep: 1,
OnlyTaggedField: false,
DisallowUnknownFields: false,
CaseSensitive: false,
TagKey: "json",
}
//Redis 自定义脚本 批量读取列表数据
var LuaScriptgetList = `
local key = tostring(KEYS[1])
local keys = redis.call("HGETALL", key)
local data = {}
local n = 1
for i, v in ipairs(keys) do
if i%2 == 0 then
data[n] = redis.call("HGETALL", v)
n = n+1
end
end
return data
`
//Redis 自定义脚本 批量写入列表数据
var LuaScriptsetList = `
local n = 1
for i, v in ipairs(KEYS) do
local key = v
local argv = {}
for i=n,#ARGV,1 do
n = n+1
if ARGV[i] == "#end" then
redis.call("HMSet", key,unpack(argv))
break
else
table.insert(argv, ARGV[i])
end
end
end
return "OK"
`
//Redis 自定义脚本 批量卸载列表数据
var LuaScriptdelList = `
local key = tostring(KEYS[1])
local keys = redis.call("HGETALL", key)
for i, v in ipairs(keys) do
if i%2 == 0 then
redis.call("DEL", v)
end
end
redis.call("DEL", key)
return "OK"
`
//Redis 自定义脚本 批量读取队列数据
var LuaScriptgetQueue = `
local key = tostring(KEYS[1])
local count = tonumber(ARGV[1]) * -1
local keys = redis.call("LRANGE", key,count,-1)
local data = {}
for i, v in ipairs(keys) do
data[i] = redis.call("HGETALL", v)
end
return data
`
//Redis 自定义脚本 批量写入队列数据
var LuaScriptsetQueue = `
local count = tonumber(ARGV[1])
local k = tostring(ARGV[3])
local keys = {}
local out = {}
local n = 1
for i, v in ipairs(KEYS) do
if (i == 1) then
for i=n,#ARGV,1 do
n = n+1
if ARGV[i] == "#end" then
break
end
end
elseif (i == 2) then
for i=n,#ARGV,1 do
n = n+1
if ARGV[i] == "#end" then
break
end
end
else
local key = v
local argv = {}
table.insert(keys, key)
for i=n,#ARGV,1 do
n = n+1
if ARGV[i] == "#end" then
redis.call("HMSet", key,unpack(argv))
break
else
table.insert(argv, ARGV[i])
end
end
end
end
redis.call("RPush", k,unpack(keys))
local c = tonumber(redis.call("LLEN", k))
count = count * 3
if (c > count) then
local off = c-count
out = redis.call("LRANGE", k,0,off-1)
redis.call("LTRIM", k,off,-1)
for i, v in ipairs(out) do
redis.call("DEL", v)
end
end
return out
`
/* /*
基础组件 缓存组件 读写缓存数据 基础组件 缓存组件 读写缓存数据
DB组件也封装进来 DB组件也封装进来
*/ */
type MCompModel struct { type MCompModel struct {
cbase.ModuleCompBase cbase.ModuleCompBase
Redis redis.ISys TableName string
DB mgo.ISys Redis redis.ISys
DB mgo.ISys
TableName string //redis key前缀 DBModel *db.DBModel
getListSha1 string //getList LusScript 的shal值
setListSha1 string //getList LusScript 的shal值
dellListSha1 string //getList LusScript 的shal值
getQueueSha1 string //getList LusScript 的shal值
setQueueSha1 string //getList LusScript 的shal值
} }
const (
DB_ModelTable core.SqlTable = "model_log"
)
//组件初始化接口 //组件初始化接口
func (this *MCompModel) Init(service core.IService, module core.IModule, comp core.IModuleComp, options core.IModuleOptions) (err error) { func (this *MCompModel) Init(service core.IService, module core.IModule, comp core.IModuleComp, options core.IModuleOptions) (err error) {
this.ModuleCompBase.Init(service, module, comp, options) this.ModuleCompBase.Init(service, module, comp, options)
this.Redis = db.Local().Redis
this.DB = db.Local().Mgo this.DB = db.Local().Mgo
this.Redis = db.Local().Redis
if this.TableName == "" {
log.Panicf("TableName is nil")
return
}
this.DBModel = db.NewDBModel(this.TableName, db.Local())
return return
} }
func (this *MCompModel) Start() (err error) {
err = this.ModuleCompBase.Start()
if this.getListSha1, err = this.Redis.NewScript(LuaScriptgetList).Result(); err != nil {
return
}
if this.setListSha1, err = this.Redis.NewScript(LuaScriptsetList).Result(); err != nil {
return
}
if this.dellListSha1, err = this.Redis.NewScript(LuaScriptdelList).Result(); err != nil {
return
}
if this.getQueueSha1, err = this.Redis.NewScript(LuaScriptgetQueue).Result(); err != nil {
return
}
if this.setQueueSha1, err = this.Redis.NewScript(LuaScriptsetQueue).Result(); err != nil {
return
}
return
}
func (this *MCompModel) ukey(uid string) string {
return fmt.Sprintf("%s:%s{%s}", this.TableName, uid, this.TableName)
}
func (this *MCompModel) ukeylist(uid string, id string) string {
return fmt.Sprintf("%s:%s-%s{%s}", this.TableName, uid, id, this.TableName)
}
func (this *MCompModel) InsertModelLogs(table string, uID string, target interface{}) (err error) { func (this *MCompModel) InsertModelLogs(table string, uID string, target interface{}) (err error) {
return this.DBModel.InsertModelLogs(table, uID, target)
data := &comm.Autogenerated{
ID: primitive.NewObjectID().Hex(),
UID: uID,
Act: string(comm.LogHandleType_Insert),
}
data.D = append(data.D, table) // D[0]
data.D = append(data.D, target) // D[1]
_, err = this.DB.InsertOne(DB_ModelTable, data)
if err != nil {
log.Errorf("insert model db err %v", err)
}
return err
} }
func (this *MCompModel) DeleteModelLogs(table string, uID string, where interface{}) (err error) { func (this *MCompModel) DeleteModelLogs(table string, uID string, where interface{}) (err error) {
return this.DBModel.DeleteModelLogs(table, uID, where)
data := &comm.Autogenerated{
ID: primitive.NewObjectID().Hex(),
UID: uID,
Act: string(comm.LogHandleType_Delete),
}
data.D = append(data.D, table) // D[0]
data.D = append(data.D, where) // D[1]
_, err = this.DB.InsertOne(DB_ModelTable, data)
if err != nil {
log.Errorf("insert model db err %v", err)
}
return err
} }
func (this *MCompModel) UpdateModelLogs(table string, uID string, where bson.M, target interface{}) (err error) { func (this *MCompModel) UpdateModelLogs(table string, uID string, where bson.M, target interface{}) (err error) {
return this.DBModel.UpdateModelLogs(table, uID, where, target)
data := &comm.Autogenerated{
ID: primitive.NewObjectID().Hex(),
UID: uID,
Act: string(comm.LogHandleType_Update),
}
data.D = append(data.D, table) // D[0]
data.D = append(data.D, where) // D[1]
data.D = append(data.D, target) // D[2]
_, err = this.DB.InsertOne(DB_ModelTable, data)
if err != nil {
log.Errorf("insert model db err %v", err)
}
return err
} }
//添加新的数据 //添加新的数据
func (this *MCompModel) Add(uid string, data interface{}, opt ...DBOption) (err error) { func (this *MCompModel) Add(uid string, data interface{}, opt ...db.DBOption) (err error) {
if err = this.Redis.HMSet(this.ukey(uid), data); err != nil { return this.DBModel.Add(uid, data)
return
}
option := newDBOption(opt...)
if option.IsMgoLog {
err = this.InsertModelLogs(this.TableName, uid, []interface{}{data})
}
if option.Expire > 0 {
err = this.Redis.Expire(this.ukey(uid), option.Expire)
}
return
} }
//添加新的数据到列表 //添加新的数据到列表
func (this *MCompModel) AddList(uid string, id string, data interface{}, opt ...DBOption) (err error) { func (this *MCompModel) AddList(uid string, id string, data interface{}, opt ...db.DBOption) (err error) {
key := this.ukeylist(uid, id) return this.DBModel.AddList(uid, id, data, opt...)
if err = this.Redis.HMSet(key, data); err != nil {
return
}
if err = this.Redis.HSet(this.ukey(uid), id, key); err != nil {
return
}
option := newDBOption(opt...)
if option.IsMgoLog {
err = this.InsertModelLogs(this.TableName, uid, []interface{}{data})
}
if option.Expire > 0 {
err = this.Redis.Expire(this.ukey(uid), option.Expire)
}
return
} }
//添加新的多个数据到列表 data map[string]type //添加新的多个数据到列表 data map[string]type
func (this *MCompModel) AddLists(uid string, data interface{}, opt ...DBOption) (err error) { func (this *MCompModel) AddLists(uid string, data interface{}, opt ...db.DBOption) (err error) {
vof := reflect.ValueOf(data) return this.DBModel.AddLists(uid, data, opt...)
if !vof.IsValid() { }
return fmt.Errorf("Model_Comp: AddLists(nil)")
}
if vof.Kind() != reflect.Map {
return fmt.Errorf("Model_Comp: AddLists(non-pointer %T)", data)
}
listskeys := make(map[string]string)
keys := vof.MapKeys()
lists := make([]interface{}, len(keys))
for i, k := range keys {
value := vof.MapIndex(k)
keydata := k.Interface().(string)
valuedata := value.Interface()
key := this.ukeylist(uid, keydata)
if err = this.Redis.HMSet(key, valuedata); err != nil { //添加新的多个数据到队列中 data map[string]type
return func (this *MCompModel) AddQueues(key string, uplimit int64, data interface{}) (outkey []string, err error) {
} return this.DBModel.AddQueues(key, uplimit, data)
listskeys[keydata] = key
lists[i] = valuedata
}
if err = this.Redis.HMSetForMap(this.ukey(uid), listskeys); err != nil {
return
}
option := newDBOption(opt...)
if option.IsMgoLog {
err = this.InsertModelLogs(this.TableName, uid, lists)
}
if option.Expire > 0 {
this.Redis.Expire(this.ukey(uid), option.Expire)
for _, v := range listskeys {
this.Redis.Expire(v, option.Expire)
}
}
return
} }
//修改数据多个字段 uid 作为主键 //修改数据多个字段 uid 作为主键
func (this *MCompModel) Change(uid string, data map[string]interface{}, opt ...DBOption) (err error) { func (this *MCompModel) Change(uid string, data map[string]interface{}, opt ...db.DBOption) (err error) {
if err = this.Redis.HMSet(this.ukey(uid), data); err != nil { return this.DBModel.Change(uid, data, opt...)
return
}
option := newDBOption(opt...)
if option.IsMgoLog {
err = this.UpdateModelLogs(this.TableName, uid, bson.M{"uid": uid}, data)
}
if option.Expire > 0 {
this.Redis.Expire(this.ukey(uid), option.Expire)
}
return nil
} }
//修改数据多个字段 uid 作为主键 //修改数据多个字段 uid 作为主键
func (this *MCompModel) ChangeList(uid string, _id string, data map[string]interface{}, opt ...DBOption) (err error) { func (this *MCompModel) ChangeList(uid string, _id string, data map[string]interface{}, opt ...db.DBOption) (err error) {
if err = this.Redis.HMSet(this.ukeylist(uid, _id), data); err != nil { return this.DBModel.ChangeList(uid, _id, data, opt...)
return
}
option := newDBOption(opt...)
if option.IsMgoLog {
err = this.UpdateModelLogs(this.TableName, uid, bson.M{"_id": _id, "uid": uid}, data)
}
if option.Expire > 0 {
this.Redis.Expire(this.ukey(uid), option.Expire)
}
return nil
} }
//读取全部数据 //读取全部数据
func (this *MCompModel) Get(uid string, data interface{}, opt ...DBOption) (err error) { func (this *MCompModel) Get(uid string, data interface{}, opt ...db.DBOption) (err error) {
if err = this.Redis.HGetAll(this.ukey(uid), data); err != nil && err != redis.RedisNil { return this.DBModel.Get(uid, data, opt...)
return
}
if err == redis.RedisNil {
if err = this.DB.FindOne(core.SqlTable(this.TableName), bson.M{"uid": uid}).Decode(data); err != nil {
return
}
err = this.Redis.HMSet(this.ukey(uid), data)
}
option := newDBOption(opt...)
if option.Expire > 0 {
this.Redis.Expire(this.ukey(uid), option.Expire)
}
return
} }
//获取列表数据 注意 data 必须是 切片的指针 *[]type //获取列表数据 注意 data 必须是 切片的指针 *[]type
func (this *MCompModel) GetList(uid string, data interface{}) (err error) { func (this *MCompModel) GetList(uid string, data interface{}) (err error) {
var ( return this.DBModel.GetFields(uid, data)
dtype reflect2.Type }
dkind reflect.Kind
sType reflect2.Type
sliceType *reflect2.UnsafeSliceType
sliceelemType reflect2.Type
decoder codecore.IDecoderMapJson
encoder codecore.IEncoderMapJson
dptr unsafe.Pointer
elemPtr unsafe.Pointer
n int
ok bool
keys map[string]string
cdata []map[string]string
wdata map[string]map[string]string
tempdata map[string]string
c *mongo.Cursor
)
keys = make(map[string]string)
dptr = reflect2.PtrOf(data)
dtype = reflect2.TypeOf(data)
dkind = dtype.Kind()
if dkind != reflect.Ptr {
err = fmt.Errorf("MCompModel: GetList(non-pointer %T)", data)
return
}
sType = dtype.(*reflect2.UnsafePtrType).Elem()
if sType.Kind() != reflect.Slice {
err = fmt.Errorf("MCompModel: GetList(data no slice %T)", data)
return
}
sliceType = sType.(*reflect2.UnsafeSliceType)
sliceelemType = sliceType.Elem()
if sliceelemType.Kind() != reflect.Ptr {
err = fmt.Errorf("MCompModel: GetList(sliceelemType non-pointer %T)", data)
return
}
if decoder, ok = codec.DecoderOf(sliceelemType, defconf).(codecore.IDecoderMapJson); !ok {
err = fmt.Errorf("MCompModel: GetList(data not support MarshalMapJson %T)", data)
return
}
sliceelemType = sliceelemType.(*reflect2.UnsafePtrType).Elem()
if cdata, err = this.Batchgetlists(this.ukey(uid)); err == nil {
for _, v := range cdata {
sliceType.UnsafeGrow(dptr, n+1)
elemPtr = sliceType.UnsafeGetIndex(dptr, n)
if *((*unsafe.Pointer)(elemPtr)) == nil {
newPtr := sliceelemType.UnsafeNew()
if err = decoder.DecodeForMapJson(newPtr, json.GetReader([]byte{}), v); err != nil {
log.Errorf("err:%v", err)
return
}
*((*unsafe.Pointer)(elemPtr)) = newPtr
} else {
decoder.DecodeForMapJson(*((*unsafe.Pointer)(elemPtr)), json.GetReader([]byte{}), v)
}
n++
}
}
if err == redis.RedisNil {
//query from mgo
if c, err = this.DB.Find(core.SqlTable(this.TableName), bson.M{"uid": uid}); err != nil {
return err
} else {
if encoder, ok = codec.EncoderOf(sliceelemType, defconf).(codecore.IEncoderMapJson); !ok {
err = fmt.Errorf("MCompModel: GetList(data not support UnMarshalMapJson %T)", data)
return
}
n = 0
wdata = make(map[string]map[string]string)
for c.Next(context.Background()) {
_id := c.Current.Lookup("_id").StringValue()
sliceType.UnsafeGrow(dptr, n+1)
elemPtr = sliceType.UnsafeGetIndex(dptr, n)
if *((*unsafe.Pointer)(elemPtr)) == nil {
newPtr := sliceelemType.UnsafeNew()
*((*unsafe.Pointer)(elemPtr)) = newPtr
}
elem := sliceType.GetIndex(data, n)
if err = c.Decode(elem); err != nil {
return
}
if tempdata, err = encoder.EncodeToMapJson(*((*unsafe.Pointer)(elemPtr)), json.GetWriter()); err != nil {
return
}
key := this.ukeylist(uid, _id)
wdata[key] = tempdata
keys[_id] = key
n++
}
if len(wdata) > 0 {
wdata[this.ukey(uid)] = keys
err = this.Batchsetlists(wdata)
}
}
}
return err //查询队列信息
func (this *MCompModel) GetQueues(key string, count int, data interface{}) (err error) {
return this.DBModel.GetQueues(key, count, data)
} }
//读取单个数据中 多个字段数据 //读取单个数据中 多个字段数据
func (this *MCompModel) GetFields(uid string, data interface{}, fields ...string) (err error) { func (this *MCompModel) GetFields(uid string, data interface{}, fields ...string) (err error) {
this.Redis.HMGet(this.ukey(uid), data, fields...) return this.DBModel.GetFields(uid, data, fields...)
return
} }
//读取List列表中单个数据中 多个字段数据 //读取List列表中单个数据中 多个字段数据
func (this *MCompModel) GetListFields(uid string, id string, data interface{}, fields ...string) (err error) { func (this *MCompModel) GetListFields(uid string, id string, data interface{}, fields ...string) (err error) {
this.Redis.HMGet(this.ukeylist(uid, id), data, fields...) return this.DBModel.GetListFields(uid, id, data, fields...)
return
} }
//读取列表数据中单个数据 //读取列表数据中单个数据
func (this *MCompModel) GetListObj(uid string, id string, data interface{}) (err error) { func (this *MCompModel) GetListObj(uid string, id string, data interface{}) (err error) {
err = this.Redis.HGetAll(this.ukeylist(uid, id), data) return this.DBModel.GetListObj(uid, id, data)
return
} }
//删除用户数据 //删除用户数据
func (this *MCompModel) Del(uid string, opt ...DBOption) (err error) { func (this *MCompModel) Del(uid string, opt ...db.DBOption) (err error) {
err = this.Redis.Delete(this.ukey(uid)) return this.DBModel.Del(uid, opt...)
if err != nil {
return err
}
option := newDBOption(opt...)
if option.IsMgoLog {
err = this.DeleteModelLogs(this.TableName, uid, bson.M{"uid": uid})
}
return nil
} }
//删除多条数据 //删除多条数据
func (this *MCompModel) DelListlds(uid string, ids ...string) (err error) { func (this *MCompModel) DelListlds(uid string, ids ...string) (err error) {
listkey := this.ukey(uid) return this.DBModel.DelListlds(uid, ids...)
for _, v := range ids {
key := this.ukeylist(uid, v)
if err = this.Redis.Delete(key); err != nil {
return
}
}
if err = this.Redis.HDel(listkey, ids...); err == nil {
err = this.DeleteModelLogs(this.TableName, uid, bson.M{"_id": bson.M{"$in": ids}})
}
return
}
// 清除玩家英雄缓存信息
// func (this *MCompModel) ClearnHeroCache(uid string, ids ...string) (err error) {
// listkey := this.ukey(uid)
// for _, v := range ids {
// key := this.ukeylist(uid, v)
// if err = this.Redis.Delete(key); err != nil {
// return
// }
// }
// err = this.Redis.HDel(listkey, ids...)
// return
// }
//批量读取列表数据
func (this *MCompModel) Batchgetlists(key string) (result []map[string]string, err error) {
var data interface{}
ret := this.Redis.EvalSha(this.Redis.Context(), this.getListSha1, []string{key})
if data, err = ret.Result(); err != nil {
fmt.Printf("Execute batchgetlists err: %v", err.Error())
} else {
temp1 := data.([]interface{})
result = make([]map[string]string, len(temp1))
for i, v := range temp1 {
temp2 := v.([]interface{})
result[i] = make(map[string]string)
for n := 0; n < len(temp2); n += 2 {
result[i][temp2[n].(string)] = temp2[n+1].(string)
}
}
if len(result) == 0 {
err = redis.RedisNil
return
}
}
return
}
//批量写入数据
func (this *MCompModel) Batchsetlists(data map[string]map[string]string) (err error) {
var (
n int
keys []string
values []interface{}
)
keys = make([]string, len(data))
values = make([]interface{}, 0)
for k, v := range data {
keys[n] = k
for k1, v1 := range v {
values = append(values, k1, v1)
}
values = append(values, "#end")
n++
}
ret := this.Redis.EvalSha(this.Redis.Context(), this.setListSha1, keys, values...)
if _, err := ret.Result(); err != nil {
fmt.Printf("Execute batchsetlists err: %v", err.Error())
}
return
}
//批量读取队列数据
func (this *MCompModel) Batchgetqueues(key string, count int32) (result []map[string]string, err error) {
var data interface{}
ret := this.Redis.EvalSha(this.Redis.Context(), this.getQueueSha1, []string{key}, count)
if data, err = ret.Result(); err != nil {
fmt.Printf("Execute batchgetqueues err: %v", err.Error())
} else {
temp1 := data.([]interface{})
result = make([]map[string]string, len(temp1))
for i, v := range temp1 {
temp2 := v.([]interface{})
result[i] = make(map[string]string)
for n := 0; n < len(temp2); n += 2 {
result[i][temp2[n].(string)] = temp2[n+1].(string)
}
}
if len(result) == 0 {
err = redis.RedisNil
return
}
}
return
}
//批量写入队列 并返回移除队列
func (this *MCompModel) Batchsetqueues(key string, count int32, ks []string, vs []map[string]string) (outkey []string, err error) {
var (
n int
keys []string
values []interface{}
result interface{}
)
keys = make([]string, len(ks)+2)
values = make([]interface{}, 0)
keys[0] = "count"
values = append(values, count)
values = append(values, "#end")
keys[1] = "key"
values = append(values, key)
values = append(values, "#end")
n = 2
for i, v := range ks {
keys[n] = v
for k1, v1 := range vs[i] {
values = append(values, k1, v1)
}
values = append(values, "#end")
n++
}
ret := this.Redis.EvalSha(this.Redis.Context(), this.setQueueSha1, keys, values...)
if result, err = ret.Result(); err != nil {
fmt.Printf("Execute batchsetqueues err: %v", err.Error())
} else {
outkey = make([]string, len(result.([]interface{})))
for i, v := range result.([]interface{}) {
outkey[i] = v.(string)
}
}
return
} }
//批量删除数据 //批量删除数据
func (this *MCompModel) BatchDelLists(uid string) (err error) { func (this *MCompModel) BatchDelLists(uid string) (err error) {
ret := this.Redis.EvalSha(this.Redis.Context(), this.dellListSha1, []string{this.ukey(uid)}) return this.DBModel.BatchDelLists(uid)
if _, err := ret.Result(); err != nil {
fmt.Printf("Execute batchsetlists err: %v", err.Error())
}
return
}
// 删除玩家缓存信息
func (this *MCompModel) CleanUserRecord(uid string) (err error) {
err = this.Redis.Delete(this.ukey(uid))
if err != nil {
return err
}
return
} }

View File

@ -1,6 +1,7 @@
package equipment package equipment
import ( import (
"go_dreamfactory/comm"
"go_dreamfactory/lego/core" "go_dreamfactory/lego/core"
"go_dreamfactory/lego/sys/log" "go_dreamfactory/lego/sys/log"
"go_dreamfactory/modules" "go_dreamfactory/modules"
@ -22,9 +23,9 @@ type modelEquipmentComp struct {
//组件初始化接口 //组件初始化接口
func (this *modelEquipmentComp) Init(service core.IService, module core.IModule, comp core.IModuleComp, opt core.IModuleOptions) (err error) { func (this *modelEquipmentComp) Init(service core.IService, module core.IModule, comp core.IModuleComp, opt core.IModuleOptions) (err error) {
this.TableName = comm.TableEquipment
this.MCompModel.Init(service, module, comp, opt) this.MCompModel.Init(service, module, comp, opt)
this.module = module.(*Equipment) this.module = module.(*Equipment)
this.TableName = "equipment"
//创建uid索引 //创建uid索引
this.DB.CreateIndex(core.SqlTable(this.TableName), mongo.IndexModel{ this.DB.CreateIndex(core.SqlTable(this.TableName), mongo.IndexModel{
Keys: bsonx.Doc{{Key: "uid", Value: bsonx.Int32(1)}}, Keys: bsonx.Doc{{Key: "uid", Value: bsonx.Int32(1)}},

View File

@ -1,9 +1,8 @@
package forum package forum
import ( import (
"go_dreamfactory/comm"
"go_dreamfactory/lego/core" "go_dreamfactory/lego/core"
"go_dreamfactory/lego/sys/redis"
"go_dreamfactory/lego/utils/codec/json"
"go_dreamfactory/modules" "go_dreamfactory/modules"
"go_dreamfactory/pb" "go_dreamfactory/pb"
@ -19,9 +18,10 @@ type modelForumComp struct {
//组件初始化接口 //组件初始化接口
func (this *modelForumComp) Init(service core.IService, module core.IModule, comp core.IModuleComp, opt core.IModuleOptions) (err error) { func (this *modelForumComp) Init(service core.IService, module core.IModule, comp core.IModuleComp, opt core.IModuleOptions) (err error) {
this.TableName = comm.TableForum
this.MCompModel.Init(service, module, comp, opt) this.MCompModel.Init(service, module, comp, opt)
this.module = module.(*Forum) this.module = module.(*Forum)
this.TableName = "forum"
//创建uid索引 //创建uid索引
this.DB.CreateIndex(core.SqlTable(this.TableName), mongo.IndexModel{ this.DB.CreateIndex(core.SqlTable(this.TableName), mongo.IndexModel{
Keys: bsonx.Doc{{Key: "heroid", Value: bsonx.Int32(1)}}, Keys: bsonx.Doc{{Key: "heroid", Value: bsonx.Int32(1)}},
@ -31,25 +31,7 @@ func (this *modelForumComp) Init(service core.IService, module core.IModule, com
//查询用户未读消息 //查询用户未读消息
func (this *modelForumComp) GetComment(herocId string) (result []*pb.DBComment, err error) { func (this *modelForumComp) GetComment(herocId string) (result []*pb.DBComment, err error) {
var (
key string
cdata []map[string]string
readmax_chat int32
)
if cdata, err = this.Batchgetqueues(key, readmax_chat); err == nil {
result = make([]*pb.DBComment, len(cdata))
for i, v := range cdata {
comment := &pb.DBComment{}
if err = json.UnmarshalMap(v, comment); err != nil {
return
}
result[i] = comment
}
}
if err == redis.RedisNil {
err = nil
}
return return
} }

View File

@ -1,6 +1,7 @@
package friend package friend
import ( import (
"go_dreamfactory/comm"
"go_dreamfactory/lego/core" "go_dreamfactory/lego/core"
"go_dreamfactory/lego/sys/log" "go_dreamfactory/lego/sys/log"
"go_dreamfactory/lego/sys/redis" "go_dreamfactory/lego/sys/redis"
@ -11,24 +12,20 @@ import (
"go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo"
) )
const (
TableFriend core.SqlTable = "friend"
TableUser core.SqlTable = "user" //用户表
)
type ModelFriend struct { type ModelFriend struct {
modules.MCompModel modules.MCompModel
} }
func (this *ModelFriend) Init(service core.IService, module core.IModule, comp core.IModuleComp, options core.IModuleOptions) (err error) { func (this *ModelFriend) Init(service core.IService, module core.IModule, comp core.IModuleComp, options core.IModuleOptions) (err error) {
this.TableName = comm.TableFriend
err = this.MCompModel.Init(service, module, comp, options) err = this.MCompModel.Init(service, module, comp, options)
this.TableName = string(TableFriend)
return return
} }
func (this *ModelFriend) Frined_FindCond(nickName string) *pb.DBUser { func (this *ModelFriend) Frined_FindCond(nickName string) *pb.DBUser {
var user *pb.DBUser var user *pb.DBUser
err := this.DB.FindOne(TableUser, bson.M{ err := this.DB.FindOne(comm.TableUser, bson.M{
"name": nickName, "name": nickName,
}).Decode(&user) }).Decode(&user)
if err != nil { if err != nil {

View File

@ -23,9 +23,9 @@ type ModelHero struct {
} }
func (this *ModelHero) Init(service core.IService, module core.IModule, comp core.IModuleComp, options core.IModuleOptions) (err error) { func (this *ModelHero) Init(service core.IService, module core.IModule, comp core.IModuleComp, options core.IModuleOptions) (err error) {
this.TableName = comm.TableHero
err = this.MCompModel.Init(service, module, comp, options) err = this.MCompModel.Init(service, module, comp, options)
this.moduleHero = module.(*Hero) this.moduleHero = module.(*Hero)
this.TableName = "hero"
// 通过uid创建索引 // 通过uid创建索引
this.DB.CreateIndex(core.SqlTable(this.TableName), mongo.IndexModel{ this.DB.CreateIndex(core.SqlTable(this.TableName), mongo.IndexModel{
Keys: bsonx.Doc{{Key: "uid", Value: bsonx.Int32(1)}}, Keys: bsonx.Doc{{Key: "uid", Value: bsonx.Int32(1)}},
@ -217,7 +217,7 @@ func (this *ModelHero) createMultiHero(uid string, heroCfgIds ...string) error {
//获取一个英雄(参数唯一objID) //获取一个英雄(参数唯一objID)
func (this *ModelHero) getOneHero(uid, heroId string) *pb.DBHero { func (this *ModelHero) getOneHero(uid, heroId string) *pb.DBHero {
hero := &pb.DBHero{} hero := &pb.DBHero{}
err := this.moduleHero.modelHero.GetListObj(uid, heroId, hero) err := this.GetListObj(uid, heroId, hero)
if err != nil { if err != nil {
return nil return nil
} }
@ -241,7 +241,7 @@ func (this *ModelHero) consumeHeroCard(uid string, hero *pb.DBHero, count int32)
} }
hero.SameCount -= count // 数量-1 hero.SameCount -= count // 数量-1
if hero.SameCount == 0 { if hero.SameCount == 0 {
if err := this.moduleHero.modelHero.DelListlds(uid, hero.Id); err != nil { if err := this.DelListlds(uid, hero.Id); err != nil {
this.moduleHero.Errorf("%v", err) this.moduleHero.Errorf("%v", err)
} }
} else { } else {

View File

@ -1,6 +1,7 @@
package hero package hero
import ( import (
"go_dreamfactory/comm"
"go_dreamfactory/lego/core" "go_dreamfactory/lego/core"
"go_dreamfactory/lego/sys/log" "go_dreamfactory/lego/sys/log"
"go_dreamfactory/modules" "go_dreamfactory/modules"
@ -14,8 +15,8 @@ type ModelRecord struct {
} }
func (this *ModelRecord) Init(service core.IService, module core.IModule, comp core.IModuleComp, options core.IModuleOptions) (err error) { func (this *ModelRecord) Init(service core.IService, module core.IModule, comp core.IModuleComp, options core.IModuleOptions) (err error) {
this.TableName = comm.TableUserRecord
err = this.MCompModel.Init(service, module, comp, options) err = this.MCompModel.Init(service, module, comp, options)
this.TableName = "userrecord"
return return
} }

View File

@ -2,6 +2,7 @@ package items
import ( import (
"fmt" "fmt"
"go_dreamfactory/comm"
"go_dreamfactory/lego/core" "go_dreamfactory/lego/core"
"go_dreamfactory/modules" "go_dreamfactory/modules"
"go_dreamfactory/pb" "go_dreamfactory/pb"
@ -21,9 +22,9 @@ type ModelItemsComp struct {
//组件初始化接口 //组件初始化接口
func (this *ModelItemsComp) Init(service core.IService, module core.IModule, comp core.IModuleComp, opt core.IModuleOptions) (err error) { func (this *ModelItemsComp) Init(service core.IService, module core.IModule, comp core.IModuleComp, opt core.IModuleOptions) (err error) {
this.TableName = comm.TableItems
this.MCompModel.Init(service, module, comp, opt) this.MCompModel.Init(service, module, comp, opt)
this.module = module.(*Items) this.module = module.(*Items)
this.TableName = "items"
//创建uid索引 //创建uid索引
this.DB.CreateIndex(core.SqlTable(this.TableName), mongo.IndexModel{ this.DB.CreateIndex(core.SqlTable(this.TableName), mongo.IndexModel{
Keys: bsonx.Doc{{Key: "uid", Value: bsonx.Int32(1)}}, Keys: bsonx.Doc{{Key: "uid", Value: bsonx.Int32(1)}},

View File

@ -2,6 +2,7 @@ package mail
import ( import (
"context" "context"
"go_dreamfactory/comm"
"go_dreamfactory/modules" "go_dreamfactory/modules"
"go_dreamfactory/pb" "go_dreamfactory/pb"
@ -14,19 +15,16 @@ import (
"go.mongodb.org/mongo-driver/x/bsonx" "go.mongodb.org/mongo-driver/x/bsonx"
) )
const (
DB_MailTable core.SqlTable = "mail"
)
type modelMail struct { type modelMail struct {
modules.MCompModel modules.MCompModel
} }
func (this *modelMail) Init(service core.IService, module core.IModule, comp core.IModuleComp, options core.IModuleOptions) (err error) { func (this *modelMail) Init(service core.IService, module core.IModule, comp core.IModuleComp, options core.IModuleOptions) (err error) {
this.TableName = comm.TableMail
this.MCompModel.Init(service, module, comp, options) this.MCompModel.Init(service, module, comp, options)
this.TableName = "mail"
//创建uid索引 //创建uid索引
this.DB.CreateIndex(core.SqlTable(DB_MailTable), mongo.IndexModel{ this.DB.CreateIndex(core.SqlTable(comm.TableMail), mongo.IndexModel{
Keys: bsonx.Doc{{Key: "uid", Value: bsonx.Int32(1)}}, Keys: bsonx.Doc{{Key: "uid", Value: bsonx.Int32(1)}},
}) })
return return
@ -34,7 +32,7 @@ func (this *modelMail) Init(service core.IService, module core.IModule, comp cor
func (this *modelMail) MailQueryUserMail(uId string) (mail []*pb.DBMailData, err error) { func (this *modelMail) MailQueryUserMail(uId string) (mail []*pb.DBMailData, err error) {
if _data, err := this.DB.Find(DB_MailTable, bson.M{"uid": uId}); err == nil { if _data, err := this.DB.Find(comm.TableMail, bson.M{"uid": uId}); err == nil {
for _data.Next(context.TODO()) { for _data.Next(context.TODO()) {
temp := &pb.DBMailData{} temp := &pb.DBMailData{}
if err = _data.Decode(temp); err == nil { if err = _data.Decode(temp); err == nil {
@ -55,7 +53,7 @@ func (this *modelMail) MailInsertUserMail(mail *pb.DBMailData) (err error) {
if len(mail.GetItems()) > 0 { if len(mail.GetItems()) > 0 {
mail.Reward = false mail.Reward = false
} }
_, err = this.DB.InsertOne(DB_MailTable, mail) _, err = this.DB.InsertOne(comm.TableMail, mail)
return err return err
} }
@ -63,7 +61,7 @@ func (this *modelMail) MailInsertUserMail(mail *pb.DBMailData) (err error) {
func (this *modelMail) MailReadOneMail(objId string) (mail *pb.DBMailData, err error) { func (this *modelMail) MailReadOneMail(objId string) (mail *pb.DBMailData, err error) {
err = this.DB.FindOneAndUpdate( err = this.DB.FindOneAndUpdate(
DB_MailTable, comm.TableMail,
bson.M{"_id": objId}, bson.M{"_id": objId},
bson.M{"$set": bson.M{ bson.M{"$set": bson.M{
"check": true, "check": true,
@ -78,7 +76,7 @@ func (this *modelMail) MailReadOneMail(objId string) (mail *pb.DBMailData, err e
func (this *modelMail) MailGetMailAttachment(objId string) (itmes []*pb.UserAssets, err error) { func (this *modelMail) MailGetMailAttachment(objId string) (itmes []*pb.UserAssets, err error) {
var nd *pb.DBMailData var nd *pb.DBMailData
err = this.DB.FindOne(DB_MailTable, bson.M{"_id": objId}).Decode(&nd) err = this.DB.FindOne(comm.TableMail, bson.M{"_id": objId}).Decode(&nd)
if err == nil { if err == nil {
itmes = nd.GetItems() itmes = nd.GetItems()
} }
@ -88,7 +86,7 @@ func (this *modelMail) MailGetMailAttachment(objId string) (itmes []*pb.UserAsse
// 查看领取附件状态 // 查看领取附件状态
func (this *modelMail) MailGetMailAttachmentState(objId string) (*pb.DBMailData, error) { func (this *modelMail) MailGetMailAttachmentState(objId string) (*pb.DBMailData, error) {
var nd *pb.DBMailData var nd *pb.DBMailData
err := this.DB.FindOne(DB_MailTable, bson.M{"_id": objId}).Decode(&nd) err := this.DB.FindOne(comm.TableMail, bson.M{"_id": objId}).Decode(&nd)
return nd, err return nd, err
//return !nd.Reward && len(nd.GetItems()) > 0 && nd.Uid == uid //return !nd.Reward && len(nd.GetItems()) > 0 && nd.Uid == uid
@ -97,7 +95,7 @@ func (this *modelMail) MailGetMailAttachmentState(objId string) (*pb.DBMailData,
// 更新领取附件状态 // 更新领取附件状态
func (this *modelMail) MailUpdateMailAttachmentState(objId string) bool { func (this *modelMail) MailUpdateMailAttachmentState(objId string) bool {
this.DB.FindOneAndUpdate( this.DB.FindOneAndUpdate(
DB_MailTable, comm.TableMail,
bson.M{"_id": objId}, bson.M{"_id": objId},
bson.M{"$set": bson.M{ bson.M{"$set": bson.M{
"reward": true, "reward": true,
@ -112,18 +110,18 @@ func (this *modelMail) MailUpdateMailAttachmentState(objId string) bool {
// 删除一封邮件 // 删除一封邮件
func (this *modelMail) MailDelUserMail(objId string) bool { func (this *modelMail) MailDelUserMail(objId string) bool {
var obj *pb.DBMailData var obj *pb.DBMailData
err := this.DB.FindOne(DB_MailTable, bson.M{"_id": objId}).Decode(&obj) err := this.DB.FindOne(comm.TableMail, bson.M{"_id": objId}).Decode(&obj)
if err != nil { if err != nil {
return false return false
} }
this.DB.DeleteOne(DB_MailTable, bson.M{"_id": objId}) this.DB.DeleteOne(comm.TableMail, bson.M{"_id": objId})
return true return true
} }
func (this *modelMail) MailQueryUserMailByReard(uId string) (mail []*pb.DBMailData, err error) { func (this *modelMail) MailQueryUserMailByReard(uId string) (mail []*pb.DBMailData, err error) {
if _data, err := this.DB.Find(DB_MailTable, bson.M{"uid": uId, "reward": false}); err == nil { if _data, err := this.DB.Find(comm.TableMail, bson.M{"uid": uId, "reward": false}); err == nil {
for _data.Next(context.TODO()) { for _data.Next(context.TODO()) {
temp := &pb.DBMailData{} temp := &pb.DBMailData{}
if err = _data.Decode(temp); err == nil { if err = _data.Decode(temp); err == nil {

View File

@ -1,24 +1,21 @@
package mainline package mainline
import ( import (
"go_dreamfactory/comm"
"go_dreamfactory/lego/core" "go_dreamfactory/lego/core"
"go_dreamfactory/modules" "go_dreamfactory/modules"
"go_dreamfactory/pb" "go_dreamfactory/pb"
) )
const ( //Redis
TableMainline core.SqlTable = "mainline"
)
type ModelMainline struct { type ModelMainline struct {
modules.MCompModel modules.MCompModel
module *Mainline module *Mainline
} }
func (this *ModelMainline) Init(service core.IService, module core.IModule, comp core.IModuleComp, options core.IModuleOptions) (err error) { func (this *ModelMainline) Init(service core.IService, module core.IModule, comp core.IModuleComp, options core.IModuleOptions) (err error) {
this.TableName = comm.TableMainline
err = this.MCompModel.Init(service, module, comp, options) err = this.MCompModel.Init(service, module, comp, options)
this.module = module.(*Mainline) this.module = module.(*Mainline)
this.TableName = string(TableMainline)
return return
} }

View File

@ -20,9 +20,9 @@ type DB_Comp struct {
} }
func (this *DB_Comp) Init(service core.IService, module core.IModule, comp core.IModuleComp, options core.IModuleOptions) (err error) { func (this *DB_Comp) Init(service core.IService, module core.IModule, comp core.IModuleComp, options core.IModuleOptions) (err error) {
this.TableName = comm.TableModellog
this.MCompModel.Init(service, module, comp, options) this.MCompModel.Init(service, module, comp, options)
this.task = make(chan string, TaskMaxNum) this.task = make(chan string, TaskMaxNum)
this.TableName = "model_log"
return return
} }

View File

@ -2,6 +2,7 @@ package notify
import ( import (
"context" "context"
"go_dreamfactory/comm"
"go_dreamfactory/lego/core" "go_dreamfactory/lego/core"
"go_dreamfactory/modules" "go_dreamfactory/modules"
"go_dreamfactory/pb" "go_dreamfactory/pb"
@ -21,9 +22,9 @@ type modelNotifyComp struct {
//组件初始化接口 //组件初始化接口
func (this *modelNotifyComp) Init(service core.IService, module core.IModule, comp core.IModuleComp, opt core.IModuleOptions) (err error) { func (this *modelNotifyComp) Init(service core.IService, module core.IModule, comp core.IModuleComp, opt core.IModuleOptions) (err error) {
this.TableName = comm.TableNotify
this.MCompModel.Init(service, module, comp, opt) this.MCompModel.Init(service, module, comp, opt)
this.module = module.(*Notify) this.module = module.(*Notify)
this.TableName = "notify"
//创建uid索引 //创建uid索引
this.DB.CreateIndex(core.SqlTable(this.TableName), mongo.IndexModel{ this.DB.CreateIndex(core.SqlTable(this.TableName), mongo.IndexModel{
Keys: bsonx.Doc{{Key: "uid", Value: bsonx.Int32(1)}}, Keys: bsonx.Doc{{Key: "uid", Value: bsonx.Int32(1)}},

View File

@ -1,6 +1,7 @@
package shop package shop
import ( import (
"go_dreamfactory/comm"
"go_dreamfactory/lego/core" "go_dreamfactory/lego/core"
"go_dreamfactory/modules" "go_dreamfactory/modules"
"go_dreamfactory/pb" "go_dreamfactory/pb"
@ -17,9 +18,9 @@ type modelShopComp struct {
//组件初始化接口 //组件初始化接口
func (this *modelShopComp) Init(service core.IService, module core.IModule, comp core.IModuleComp, opt core.IModuleOptions) (err error) { func (this *modelShopComp) Init(service core.IService, module core.IModule, comp core.IModuleComp, opt core.IModuleOptions) (err error) {
this.TableName = comm.TableShop
this.MCompModel.Init(service, module, comp, opt) this.MCompModel.Init(service, module, comp, opt)
this.module = module.(*Shop) this.module = module.(*Shop)
this.TableName = "shop"
//创建uid索引 //创建uid索引
this.DB.CreateIndex(core.SqlTable(this.TableName), mongo.IndexModel{ this.DB.CreateIndex(core.SqlTable(this.TableName), mongo.IndexModel{
Keys: bsonx.Doc{{Key: "uid", Value: bsonx.Int32(1)}}, Keys: bsonx.Doc{{Key: "uid", Value: bsonx.Int32(1)}},

View File

@ -1,6 +1,7 @@
package shop package shop
import ( import (
"go_dreamfactory/comm"
"go_dreamfactory/lego/core" "go_dreamfactory/lego/core"
"go_dreamfactory/lego/sys/mgo" "go_dreamfactory/lego/sys/mgo"
"go_dreamfactory/modules" "go_dreamfactory/modules"
@ -18,10 +19,9 @@ type modelShopItemsComp struct {
//组件初始化接口 //组件初始化接口
func (this *modelShopItemsComp) Init(service core.IService, module core.IModule, comp core.IModuleComp, opt core.IModuleOptions) (err error) { func (this *modelShopItemsComp) Init(service core.IService, module core.IModule, comp core.IModuleComp, opt core.IModuleOptions) (err error) {
this.TableName = comm.TableShopitems
this.MCompModel.Init(service, module, comp, opt) this.MCompModel.Init(service, module, comp, opt)
this.module = module.(*Shop) this.module = module.(*Shop)
this.TableName = "shopitems"
//创建uid索引 //创建uid索引
this.DB.CreateIndex(core.SqlTable(this.TableName), mongo.IndexModel{ this.DB.CreateIndex(core.SqlTable(this.TableName), mongo.IndexModel{
Keys: bsonx.Doc{{Key: "uid", Value: bsonx.Int32(1)}, {Key: "goodsid", Value: bsonx.Int32(1)}}, Keys: bsonx.Doc{{Key: "uid", Value: bsonx.Int32(1)}, {Key: "goodsid", Value: bsonx.Int32(1)}},

View File

@ -4,6 +4,7 @@ import (
"go_dreamfactory/comm" "go_dreamfactory/comm"
"go_dreamfactory/lego/core" "go_dreamfactory/lego/core"
"go_dreamfactory/modules" "go_dreamfactory/modules"
"go_dreamfactory/sys/db"
) )
/* /*
@ -46,6 +47,6 @@ func (this *Shop) OnInstallComp() {
//Event------------------------------------------------------------------------------------------------------------ //Event------------------------------------------------------------------------------------------------------------
func (this *Shop) EventUserOffline(session comm.IUserSession) { func (this *Shop) EventUserOffline(session comm.IUserSession) {
this.modelShop.Del(session.GetUserId(), modules.SetDBMgoLog(false)) this.modelShop.Del(session.GetUserId(), db.SetDBMgoLog(false))
this.modelShopItems.BatchDelLists(session.GetUserId()) this.modelShopItems.BatchDelLists(session.GetUserId())
} }

View File

@ -10,19 +10,15 @@ import (
"go.mongodb.org/mongo-driver/bson/primitive" "go.mongodb.org/mongo-driver/bson/primitive"
) )
const ( //Redis
TableTaskActive core.SqlTable = "taskactive" //活跃度表
)
type ModelTaskActive struct { type ModelTaskActive struct {
modules.MCompModel modules.MCompModel
moduleTask *ModuleTask moduleTask *ModuleTask
} }
func (this *ModelTaskActive) Init(service core.IService, module core.IModule, comp core.IModuleComp, options core.IModuleOptions) (err error) { func (this *ModelTaskActive) Init(service core.IService, module core.IModule, comp core.IModuleComp, options core.IModuleOptions) (err error) {
this.TableName = comm.TableTaskActive
err = this.MCompModel.Init(service, module, comp, options) err = this.MCompModel.Init(service, module, comp, options)
this.moduleTask = module.(*ModuleTask) this.moduleTask = module.(*ModuleTask)
this.TableName = string(TableTaskActive)
return return
} }

View File

@ -11,19 +11,15 @@ import (
"go.mongodb.org/mongo-driver/bson/primitive" "go.mongodb.org/mongo-driver/bson/primitive"
) )
const ( //Redis
TableTask core.SqlTable = "task" //每日任务表
)
type ModelTask struct { type ModelTask struct {
modules.MCompModel modules.MCompModel
moduleTask *ModuleTask moduleTask *ModuleTask
} }
func (this *ModelTask) Init(service core.IService, module core.IModule, comp core.IModuleComp, options core.IModuleOptions) (err error) { func (this *ModelTask) Init(service core.IService, module core.IModule, comp core.IModuleComp, options core.IModuleOptions) (err error) {
this.TableName = comm.TableTask
err = this.MCompModel.Init(service, module, comp, options) err = this.MCompModel.Init(service, module, comp, options)
this.moduleTask = module.(*ModuleTask) this.moduleTask = module.(*ModuleTask)
this.TableName = string(TableTask)
return return
} }

View File

@ -4,8 +4,8 @@ import (
"go_dreamfactory/comm" "go_dreamfactory/comm"
"go_dreamfactory/lego/sys/event" "go_dreamfactory/lego/sys/event"
"go_dreamfactory/lego/sys/log" "go_dreamfactory/lego/sys/log"
"go_dreamfactory/modules"
"go_dreamfactory/pb" "go_dreamfactory/pb"
"go_dreamfactory/sys/db"
"go_dreamfactory/utils" "go_dreamfactory/utils"
"time" "time"
@ -87,8 +87,8 @@ func (this *apiComp) Login(session comm.IUserSession, req *pb.UserLoginReq) (cod
"gatewayServiceId": session.GetGatewayServiceId(), "gatewayServiceId": session.GetGatewayServiceId(),
"ip": session.GetIP(), "ip": session.GetIP(),
}, },
modules.SetDBExpire(time.Hour*12), db.SetDBExpire(time.Hour*12),
modules.SetDBMgoLog(false)) db.SetDBMgoLog(false))
if err != nil { if err != nil {
code = pb.ErrorCode_DBError code = pb.ErrorCode_DBError
return return

View File

@ -1,6 +1,7 @@
package user package user
import ( import (
"go_dreamfactory/comm"
"go_dreamfactory/lego/core" "go_dreamfactory/lego/core"
"go_dreamfactory/lego/sys/log" "go_dreamfactory/lego/sys/log"
"go_dreamfactory/modules" "go_dreamfactory/modules"
@ -14,8 +15,8 @@ type ModelExpand struct {
} }
func (this *ModelExpand) Init(service core.IService, module core.IModule, comp core.IModuleComp, options core.IModuleOptions) (err error) { func (this *ModelExpand) Init(service core.IService, module core.IModule, comp core.IModuleComp, options core.IModuleOptions) (err error) {
this.TableName = comm.TableUserExpand
err = this.MCompModel.Init(service, module, comp, options) err = this.MCompModel.Init(service, module, comp, options)
this.TableName = "userexpand"
this.moduleUser = module.(*User) this.moduleUser = module.(*User)
return return
} }

View File

@ -1,6 +1,7 @@
package user package user
import ( import (
"go_dreamfactory/comm"
"go_dreamfactory/lego/core" "go_dreamfactory/lego/core"
"go_dreamfactory/lego/sys/log" "go_dreamfactory/lego/sys/log"
"go_dreamfactory/modules" "go_dreamfactory/modules"
@ -12,8 +13,8 @@ type ModelSession struct {
} }
func (this *ModelSession) Init(service core.IService, module core.IModule, comp core.IModuleComp, options core.IModuleOptions) (err error) { func (this *ModelSession) Init(service core.IService, module core.IModule, comp core.IModuleComp, options core.IModuleOptions) (err error) {
this.TableName = comm.TableSession
err = this.MCompModel.Init(service, module, comp, options) err = this.MCompModel.Init(service, module, comp, options)
this.TableName = "session"
return return
} }

View File

@ -2,6 +2,7 @@ package user
import ( import (
"fmt" "fmt"
"go_dreamfactory/comm"
"go_dreamfactory/lego/core" "go_dreamfactory/lego/core"
"go_dreamfactory/lego/sys/redis" "go_dreamfactory/lego/sys/redis"
"go_dreamfactory/modules" "go_dreamfactory/modules"
@ -18,9 +19,9 @@ type ModelSetting struct {
} }
func (this *ModelSetting) Init(service core.IService, module core.IModule, comp core.IModuleComp, options core.IModuleOptions) (err error) { func (this *ModelSetting) Init(service core.IService, module core.IModule, comp core.IModuleComp, options core.IModuleOptions) (err error) {
this.TableName = comm.TableSetting
err = this.MCompModel.Init(service, module, comp, options) err = this.MCompModel.Init(service, module, comp, options)
this.moduleUser = module.(*User) this.moduleUser = module.(*User)
this.TableName = "setting"
return return
} }

View File

@ -17,10 +17,6 @@ import (
"go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo"
) )
const ( //Redis
TableUser core.SqlTable = "user" //用户表
)
type ModelUser struct { type ModelUser struct {
modules.MCompModel modules.MCompModel
moduleUser *User moduleUser *User
@ -28,8 +24,8 @@ type ModelUser struct {
} }
func (this *ModelUser) Init(service core.IService, module core.IModule, comp core.IModuleComp, options core.IModuleOptions) (err error) { func (this *ModelUser) Init(service core.IService, module core.IModule, comp core.IModuleComp, options core.IModuleOptions) (err error) {
this.TableName = comm.TableUser
err = this.MCompModel.Init(service, module, comp, options) err = this.MCompModel.Init(service, module, comp, options)
this.TableName = string(TableUser)
this.moduleUser = module.(*User) this.moduleUser = module.(*User)
this.eventApp = event_v2.NewApp() this.eventApp = event_v2.NewApp()
this.eventApp.Listen(comm.EventUserChanged, this.ChangeExp) this.eventApp.Listen(comm.EventUserChanged, this.ChangeExp)
@ -42,7 +38,7 @@ func (this *ModelUser) FindByAccount(sid int32, account string) (*pb.DBUser, err
"sid": sid, "sid": sid,
"binduid": account, "binduid": account,
} }
sr := this.DB.FindOne(TableUser, filter) sr := this.DB.FindOne(comm.TableUser, filter)
var nd *pb.DBUser var nd *pb.DBUser
err := sr.Decode(&nd) err := sr.Decode(&nd)
return nd, err return nd, err
@ -50,7 +46,7 @@ func (this *ModelUser) FindByAccount(sid int32, account string) (*pb.DBUser, err
//查询昵称 //查询昵称
func (this *ModelUser) NickNameIsExist(name string) bool { func (this *ModelUser) NickNameIsExist(name string) bool {
if err := this.DB.FindOne(TableUser, bson.M{"name": name}).Err(); err != nil { if err := this.DB.FindOne(comm.TableUser, bson.M{"name": name}).Err(); err != nil {
if err == mongo.ErrNoDocuments { //无记录 if err == mongo.ErrNoDocuments { //无记录
return true return true
} }

View File

@ -4,6 +4,7 @@ import (
"go_dreamfactory/comm" "go_dreamfactory/comm"
"go_dreamfactory/modules" "go_dreamfactory/modules"
"go_dreamfactory/pb" "go_dreamfactory/pb"
"go_dreamfactory/sys/db"
"go_dreamfactory/lego/core" "go_dreamfactory/lego/core"
"go_dreamfactory/lego/sys/event" "go_dreamfactory/lego/sys/event"
@ -31,7 +32,6 @@ func (this *User) GetType() core.M_Modules {
func (this *User) Init(service core.IService, module core.IModule, options core.IModuleOptions) (err error) { func (this *User) Init(service core.IService, module core.IModule, options core.IModuleOptions) (err error) {
err = this.ModuleBase.Init(service, module, options) err = this.ModuleBase.Init(service, module, options)
return return
} }
@ -70,10 +70,10 @@ func (this *User) GetUserSession(uid string) *pb.CacheUser {
// 清除session // 清除session
func (this *User) CleanSession(session comm.IUserSession) { func (this *User) CleanSession(session comm.IUserSession) {
this.modelSession.Del(session.GetUserId(), modules.SetDBMgoLog(false)) this.modelSession.Del(session.GetUserId(), db.SetDBMgoLog(false))
this.modelUser.Del(session.GetUserId(), modules.SetDBMgoLog(false)) this.modelUser.Del(session.GetUserId(), db.SetDBMgoLog(false))
//this.modelExpand.Del(session.GetUserId(), modules.SetDBMgoLog(false)) // 暂时不清 //this.modelExpand.Del(session.GetUserId(), modules.SetDBMgoLog(false)) // 暂时不清
this.modelSetting.Del(session.GetUserId(), modules.SetDBMgoLog(false)) this.modelSetting.Del(session.GetUserId(), db.SetDBMgoLog(false))
} }
//查询用户属性值 例如 金币 经验 //查询用户属性值 例如 金币 经验

View File

@ -17,9 +17,9 @@ type modelMailComp struct {
} }
func (this *modelMailComp) Init(service core.IService, module core.IModule, comp core.IModuleComp, opt core.IModuleOptions) (err error) { func (this *modelMailComp) Init(service core.IService, module core.IModule, comp core.IModuleComp, opt core.IModuleOptions) (err error) {
this.TableName = "mail"
this.MCompModel.Init(service, module, comp, opt) this.MCompModel.Init(service, module, comp, opt)
this.module = module.(*Web) this.module = module.(*Web)
this.TableName = "mail"
return return
} }

View File

@ -16,9 +16,9 @@ type modelNotifyComp struct {
} }
func (this *modelNotifyComp) Init(service core.IService, module core.IModule, comp core.IModuleComp, opt core.IModuleOptions) (err error) { func (this *modelNotifyComp) Init(service core.IService, module core.IModule, comp core.IModuleComp, opt core.IModuleOptions) (err error) {
this.TableName = "notify"
this.MCompModel.Init(service, module, comp, opt) this.MCompModel.Init(service, module, comp, opt)
this.module = module.(*Web) this.module = module.(*Web)
this.TableName = "notify"
return return
} }

View File

@ -2,6 +2,7 @@ package web
import ( import (
"fmt" "fmt"
"go_dreamfactory/comm"
"go_dreamfactory/lego/core" "go_dreamfactory/lego/core"
"go_dreamfactory/modules" "go_dreamfactory/modules"
"go_dreamfactory/pb" "go_dreamfactory/pb"
@ -18,9 +19,9 @@ type modelUserComp struct {
} }
func (this *modelUserComp) Init(service core.IService, module core.IModule, comp core.IModuleComp, opt core.IModuleOptions) (err error) { func (this *modelUserComp) Init(service core.IService, module core.IModule, comp core.IModuleComp, opt core.IModuleOptions) (err error) {
this.TableName = comm.TableUser
this.MCompModel.Init(service, module, comp, opt) this.MCompModel.Init(service, module, comp, opt)
this.module = module.(*Web) this.module = module.(*Web)
this.TableName = "user"
return return
} }

View File

@ -2,44 +2,8 @@ package db
import ( import (
"go_dreamfactory/lego/sys/log" "go_dreamfactory/lego/sys/log"
"go_dreamfactory/lego/sys/mgo"
"go_dreamfactory/lego/sys/redis"
) )
type DBConn struct {
Redis redis.ISys
Mgo mgo.ISys
}
func newDBConn(conf DBConfig) (conn *DBConn, err error) {
conn = &DBConn{}
if conf.RedisIsCluster {
conn.Redis, err = redis.NewSys(
redis.SetRedisType(redis.Redis_Cluster),
redis.SetRedis_Cluster_Addr(conf.RedisAddr),
redis.SetRedis_Cluster_Password(conf.RedisPassword))
} else {
conn.Redis, err = redis.NewSys(
redis.SetRedisType(redis.Redis_Single),
redis.SetRedis_Single_Addr(conf.RedisAddr[0]),
redis.SetRedis_Single_Password(conf.RedisPassword),
redis.SetRedis_Single_DB(conf.RedisDB),
)
}
if err != nil {
log.Error(err.Error(), log.Field{"config", conf})
return
}
if conn.Mgo, err = mgo.NewSys(
mgo.SetMongodbUrl(conf.MongodbUrl),
mgo.SetMongodbDatabase(conf.MongodbDatabase),
); err != nil {
log.Error(err.Error(), log.Field{"config", conf})
return
}
return
}
func newSys(options *Options) (sys *DB, err error) { func newSys(options *Options) (sys *DB, err error) {
sys = &DB{options: options} sys = &DB{options: options}
err = sys.init() err = sys.init()

545
sys/db/dbconn.go Normal file
View File

@ -0,0 +1,545 @@
package db
import (
"context"
"fmt"
"go_dreamfactory/comm"
"go_dreamfactory/lego/core"
"go_dreamfactory/lego/sys/log"
"go_dreamfactory/lego/sys/mgo"
lgredis "go_dreamfactory/lego/sys/redis"
"go_dreamfactory/lego/utils/codec"
"go_dreamfactory/lego/utils/codec/codecore"
"go_dreamfactory/lego/utils/codec/json"
"reflect"
"unsafe"
"github.com/go-redis/redis/v8"
"github.com/modern-go/reflect2"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
"go.mongodb.org/mongo-driver/mongo"
)
var defconf = &codecore.Config{
SortMapKeys: true,
IndentionStep: 1,
OnlyTaggedField: false,
DisallowUnknownFields: false,
CaseSensitive: false,
TagKey: "json",
}
const (
DB_ModelTable core.SqlTable = "model_log"
)
func newDBConn(conf DBConfig) (conn *DBConn, err error) {
conn = &DBConn{}
if conf.RedisIsCluster {
conn.Redis, err = lgredis.NewSys(
lgredis.SetRedisType(lgredis.Redis_Cluster),
lgredis.SetRedis_Cluster_Addr(conf.RedisAddr),
lgredis.SetRedis_Cluster_Password(conf.RedisPassword))
} else {
conn.Redis, err = lgredis.NewSys(
lgredis.SetRedisType(lgredis.Redis_Single),
lgredis.SetRedis_Single_Addr(conf.RedisAddr[0]),
lgredis.SetRedis_Single_Password(conf.RedisPassword),
lgredis.SetRedis_Single_DB(conf.RedisDB),
)
}
if err != nil {
log.Error(err.Error(), log.Field{"config", conf})
return
}
if conn.Mgo, err = mgo.NewSys(
mgo.SetMongodbUrl(conf.MongodbUrl),
mgo.SetMongodbDatabase(conf.MongodbDatabase),
); err != nil {
log.Error(err.Error(), log.Field{"config", conf})
return
}
return
}
type DBConn struct {
Redis lgredis.ISys
Mgo mgo.ISys
}
func NewDBModel(TableName string, conn *DBConn) *DBModel {
return &DBModel{
TableName: TableName,
Redis: conn.Redis,
DB: conn.Mgo,
}
}
//DB模型
type DBModel struct {
TableName string
Redis lgredis.ISys
DB mgo.ISys
}
func (this *DBModel) ukey(uid string) string {
return fmt.Sprintf("%s:%s{%s}", this.TableName, uid, this.TableName)
}
func (this *DBModel) ukeylist(uid string, id string) string {
return fmt.Sprintf("%s:%s-%s{%s}", this.TableName, uid, id, this.TableName)
}
func (this *DBModel) InsertModelLogs(table string, uID string, target interface{}) (err error) {
data := &comm.Autogenerated{
ID: primitive.NewObjectID().Hex(),
UID: uID,
Act: string(comm.LogHandleType_Insert),
}
data.D = append(data.D, table) // D[0]
data.D = append(data.D, target) // D[1]
_, err = this.DB.InsertOne(DB_ModelTable, data)
if err != nil {
log.Errorf("insert model db err %v", err)
}
return err
}
func (this *DBModel) DeleteModelLogs(table string, uID string, where interface{}) (err error) {
data := &comm.Autogenerated{
ID: primitive.NewObjectID().Hex(),
UID: uID,
Act: string(comm.LogHandleType_Delete),
}
data.D = append(data.D, table) // D[0]
data.D = append(data.D, where) // D[1]
_, err = this.DB.InsertOne(DB_ModelTable, data)
if err != nil {
log.Errorf("insert model db err %v", err)
}
return err
}
func (this *DBModel) UpdateModelLogs(table string, uID string, where bson.M, target interface{}) (err error) {
data := &comm.Autogenerated{
ID: primitive.NewObjectID().Hex(),
UID: uID,
Act: string(comm.LogHandleType_Update),
}
data.D = append(data.D, table) // D[0]
data.D = append(data.D, where) // D[1]
data.D = append(data.D, target) // D[2]
_, err = this.DB.InsertOne(DB_ModelTable, data)
if err != nil {
log.Errorf("insert model db err %v", err)
}
return err
}
//添加新的数据
func (this *DBModel) Add(uid string, data interface{}, opt ...DBOption) (err error) {
if err = this.Redis.HMSet(this.ukey(uid), data); err != nil {
return
}
option := newDBOption(opt...)
if option.IsMgoLog {
err = this.InsertModelLogs(this.TableName, uid, []interface{}{data})
}
if option.Expire > 0 {
err = this.Redis.Expire(this.ukey(uid), option.Expire)
}
return
}
//添加新的数据到列表
func (this *DBModel) AddList(uid string, id string, data interface{}, opt ...DBOption) (err error) {
key := this.ukeylist(uid, id)
if err = this.Redis.HMSet(key, data); err != nil {
return
}
if err = this.Redis.HSet(this.ukey(uid), id, key); err != nil {
return
}
option := newDBOption(opt...)
if option.IsMgoLog {
err = this.InsertModelLogs(this.TableName, uid, []interface{}{data})
}
if option.Expire > 0 {
err = this.Redis.Expire(this.ukey(uid), option.Expire)
}
return
}
//添加新的多个数据到列表 data map[string]type
func (this *DBModel) AddLists(uid string, data interface{}, opt ...DBOption) (err error) {
vof := reflect.ValueOf(data)
if !vof.IsValid() {
return fmt.Errorf("Model_Comp: AddLists(nil)")
}
if vof.Kind() != reflect.Map {
return fmt.Errorf("Model_Comp: AddLists(non-pointer %T)", data)
}
listskeys := make(map[string]string)
keys := vof.MapKeys()
lists := make([]interface{}, len(keys))
pipe := this.Redis.RedisPipe(context.TODO())
for _, k := range keys {
value := vof.MapIndex(k)
keydata := k.Interface().(string)
valuedata := value.Interface()
key := this.ukeylist(uid, keydata)
pipe.HMSet(key, valuedata)
listskeys[keydata] = key
}
pipe.HMSetForMap(this.ukey(uid), listskeys)
if _, err = pipe.Exec(); err != nil {
return
}
option := newDBOption(opt...)
if option.IsMgoLog {
err = this.InsertModelLogs(this.TableName, uid, lists)
}
if option.Expire > 0 {
this.Redis.Expire(this.ukey(uid), option.Expire)
for _, v := range listskeys {
this.Redis.Expire(v, option.Expire)
}
}
return
}
//添加队列
func (this *DBModel) AddQueues(key string, uplimit int64, data interface{}) (outkey []string, err error) {
vof := reflect.ValueOf(data)
if !vof.IsValid() {
err = fmt.Errorf("Model_Comp: AddLists(nil)")
return
}
if vof.Kind() != reflect.Map {
err = fmt.Errorf("Model_Comp: AddLists(non-pointer %T)", data)
return
}
keys := make([]string, 0)
pipe := this.Redis.RedisPipe(context.TODO())
for _, k := range vof.MapKeys() {
value := vof.MapIndex(k)
tkey := k.Interface().(string)
valuedata := value.Interface()
pipe.HMSet(tkey, valuedata)
keys = append(keys, tkey)
}
pipe.RPushForStringSlice(key, keys...)
lcmd := pipe.Llen(key)
pipe.Exec()
if lcmd.Err() == nil {
if lcmd.Val() > uplimit*3 { //操作3倍上限移除多余数据
off := uplimit - lcmd.Val()
if outkey, err = this.Redis.LRangeToStringSlice(key, 0, int(off-1)).Result(); err != nil {
return
}
pipe.Ltrim(key, int(off), -1)
for _, v := range outkey {
pipe.Delete(v)
}
_, err = pipe.Exec()
}
}
return
}
//修改数据多个字段 uid 作为主键
func (this *DBModel) Change(uid string, data map[string]interface{}, opt ...DBOption) (err error) {
if err = this.Redis.HMSet(this.ukey(uid), data); err != nil {
return
}
option := newDBOption(opt...)
if option.IsMgoLog {
err = this.UpdateModelLogs(this.TableName, uid, bson.M{"uid": uid}, data)
}
if option.Expire > 0 {
this.Redis.Expire(this.ukey(uid), option.Expire)
}
return nil
}
//修改数据多个字段 uid 作为主键
func (this *DBModel) ChangeList(uid string, _id string, data map[string]interface{}, opt ...DBOption) (err error) {
if err = this.Redis.HMSet(this.ukeylist(uid, _id), data); err != nil {
return
}
option := newDBOption(opt...)
if option.IsMgoLog {
err = this.UpdateModelLogs(this.TableName, uid, bson.M{"_id": _id, "uid": uid}, data)
}
if option.Expire > 0 {
this.Redis.Expire(this.ukey(uid), option.Expire)
}
return nil
}
//读取全部数据
func (this *DBModel) Get(uid string, data interface{}, opt ...DBOption) (err error) {
if err = this.Redis.HGetAll(this.ukey(uid), data); err != nil && err != lgredis.RedisNil {
return
}
if err == lgredis.RedisNil {
if err = this.DB.FindOne(core.SqlTable(this.TableName), bson.M{"uid": uid}).Decode(data); err != nil {
return
}
err = this.Redis.HMSet(this.ukey(uid), data)
}
option := newDBOption(opt...)
if option.Expire > 0 {
this.Redis.Expire(this.ukey(uid), option.Expire)
}
return
}
//获取列表数据 注意 data 必须是 切片的指针 *[]type
func (this *DBModel) GetList(uid string, data interface{}) (err error) {
var (
dtype reflect2.Type
dkind reflect.Kind
sType reflect2.Type
sliceType *reflect2.UnsafeSliceType
sliceelemType reflect2.Type
decoder codecore.IDecoderMapJson
encoder codecore.IEncoderMapJson
dptr unsafe.Pointer
elemPtr unsafe.Pointer
n int
ok bool
keys map[string]string
tempdata map[string]string
result []*redis.StringStringMapCmd
c *mongo.Cursor
)
keys = make(map[string]string)
dptr = reflect2.PtrOf(data)
dtype = reflect2.TypeOf(data)
dkind = dtype.Kind()
if dkind != reflect.Ptr {
err = fmt.Errorf("MCompModel: GetList(non-pointer %T)", data)
return
}
sType = dtype.(*reflect2.UnsafePtrType).Elem()
if sType.Kind() != reflect.Slice {
err = fmt.Errorf("MCompModel: GetList(data no slice %T)", data)
return
}
sliceType = sType.(*reflect2.UnsafeSliceType)
sliceelemType = sliceType.Elem()
if sliceelemType.Kind() != reflect.Ptr {
err = fmt.Errorf("MCompModel: GetList(sliceelemType non-pointer %T)", data)
return
}
if decoder, ok = codec.DecoderOf(sliceelemType, defconf).(codecore.IDecoderMapJson); !ok {
err = fmt.Errorf("MCompModel: GetList(data not support MarshalMapJson %T)", data)
return
}
sliceelemType = sliceelemType.(*reflect2.UnsafePtrType).Elem()
pipe := this.Redis.RedisPipe(context.TODO())
if keys, err = this.Redis.HGetAllToMapString(this.ukey(uid)); err == nil {
result = make([]*redis.StringStringMapCmd, 0)
for _, v := range keys {
cmd := pipe.HGetAllToMapString(v)
result = append(result, cmd)
}
pipe.Exec()
for _, v := range result {
tempdata, err = v.Result()
sliceType.UnsafeGrow(dptr, n+1)
elemPtr = sliceType.UnsafeGetIndex(dptr, n)
if *((*unsafe.Pointer)(elemPtr)) == nil {
newPtr := sliceelemType.UnsafeNew()
if err = decoder.DecodeForMapJson(newPtr, json.GetReader([]byte{}), tempdata); err != nil {
log.Errorf("err:%v", err)
return
}
*((*unsafe.Pointer)(elemPtr)) = newPtr
} else {
decoder.DecodeForMapJson(*((*unsafe.Pointer)(elemPtr)), json.GetReader([]byte{}), tempdata)
}
n++
}
}
if err == lgredis.RedisNil {
//query from mgo
if c, err = this.DB.Find(core.SqlTable(this.TableName), bson.M{"uid": uid}); err != nil {
return err
} else {
if encoder, ok = codec.EncoderOf(sliceelemType, defconf).(codecore.IEncoderMapJson); !ok {
err = fmt.Errorf("MCompModel: GetList(data not support UnMarshalMapJson %T)", data)
return
}
n = 0
for c.Next(context.Background()) {
_id := c.Current.Lookup("_id").StringValue()
sliceType.UnsafeGrow(dptr, n+1)
elemPtr = sliceType.UnsafeGetIndex(dptr, n)
if *((*unsafe.Pointer)(elemPtr)) == nil {
newPtr := sliceelemType.UnsafeNew()
*((*unsafe.Pointer)(elemPtr)) = newPtr
}
elem := sliceType.GetIndex(data, n)
if err = c.Decode(elem); err != nil {
return
}
if tempdata, err = encoder.EncodeToMapJson(*((*unsafe.Pointer)(elemPtr)), json.GetWriter()); err != nil {
return
}
key := this.ukeylist(uid, _id)
pipe.HMSetForMap(key, tempdata)
keys[_id] = key
n++
}
if len(keys) > 0 {
pipe.HMSetForMap(this.ukey(uid), keys)
_, err = pipe.Exec()
}
}
}
return err
}
//获取队列数据
func (this *DBModel) GetQueues(key string, count int, data interface{}) (err error) {
var (
dtype reflect2.Type
dkind reflect.Kind
sType reflect2.Type
sliceType *reflect2.UnsafeSliceType
sliceelemType reflect2.Type
dptr unsafe.Pointer
elemPtr unsafe.Pointer
decoder codecore.IDecoderMapJson
ok bool
n int
keys = make([]string, 0)
result = make([]*redis.StringStringMapCmd, 0)
tempdata map[string]string
)
dptr = reflect2.PtrOf(data)
dtype = reflect2.TypeOf(data)
dkind = dtype.Kind()
if dkind != reflect.Ptr {
err = fmt.Errorf("MCompModel: GetList(non-pointer %T)", data)
return
}
sType = dtype.(*reflect2.UnsafePtrType).Elem()
if sType.Kind() != reflect.Slice {
err = fmt.Errorf("MCompModel: GetList(data no slice %T)", data)
return
}
sliceType = sType.(*reflect2.UnsafeSliceType)
sliceelemType = sliceType.Elem()
if sliceelemType.Kind() != reflect.Ptr {
err = fmt.Errorf("MCompModel: GetList(sliceelemType non-pointer %T)", data)
return
}
if decoder, ok = codec.DecoderOf(sliceelemType, defconf).(codecore.IDecoderMapJson); !ok {
err = fmt.Errorf("MCompModel: GetList(data not support MarshalMapJson %T)", data)
return
}
sliceelemType = sliceelemType.(*reflect2.UnsafePtrType).Elem()
pipe := this.Redis.RedisPipe(context.TODO())
if err = this.Redis.LRange(key, -1*count, -1, keys); err == nil {
result = make([]*redis.StringStringMapCmd, 0)
for _, v := range keys {
cmd := pipe.HGetAllToMapString(v)
result = append(result, cmd)
}
pipe.Exec()
for _, v := range result {
tempdata, err = v.Result()
sliceType.UnsafeGrow(dptr, n+1)
elemPtr = sliceType.UnsafeGetIndex(dptr, n)
if *((*unsafe.Pointer)(elemPtr)) == nil {
newPtr := sliceelemType.UnsafeNew()
if err = decoder.DecodeForMapJson(newPtr, json.GetReader([]byte{}), tempdata); err != nil {
log.Errorf("err:%v", err)
return
}
*((*unsafe.Pointer)(elemPtr)) = newPtr
} else {
decoder.DecodeForMapJson(*((*unsafe.Pointer)(elemPtr)), json.GetReader([]byte{}), tempdata)
}
n++
}
}
return
}
//读取单个数据中 多个字段数据
func (this *DBModel) GetFields(uid string, data interface{}, fields ...string) (err error) {
this.Redis.HMGet(this.ukey(uid), data, fields...)
return
}
//读取List列表中单个数据中 多个字段数据
func (this *DBModel) GetListFields(uid string, id string, data interface{}, fields ...string) (err error) {
this.Redis.HMGet(this.ukeylist(uid, id), data, fields...)
return
}
//读取列表数据中单个数据
func (this *DBModel) GetListObj(uid string, id string, data interface{}) (err error) {
err = this.Redis.HGetAll(this.ukeylist(uid, id), data)
return
}
//删除用户数据
func (this *DBModel) Del(uid string, opt ...DBOption) (err error) {
err = this.Redis.Delete(this.ukey(uid))
if err != nil {
return err
}
option := newDBOption(opt...)
if option.IsMgoLog {
err = this.DeleteModelLogs(this.TableName, uid, bson.M{"uid": uid})
}
return nil
}
//删除多条数据
func (this *DBModel) DelListlds(uid string, ids ...string) (err error) {
listkey := this.ukey(uid)
pipe := this.Redis.RedisPipe(context.TODO())
for _, v := range ids {
key := this.ukeylist(uid, v)
pipe.Delete(key)
}
pipe.HDel(listkey, ids...)
if _, err = pipe.Exec(); err == nil {
err = this.DeleteModelLogs(this.TableName, uid, bson.M{"_id": bson.M{"$in": ids}})
}
return
}
//批量删除数据
func (this *DBModel) BatchDelLists(uid string) (err error) {
var keys map[string]string
pipe := this.Redis.RedisPipe(context.TODO())
if keys, err = this.Redis.HGetAllToMapString(this.ukey(uid)); err == nil {
for _, v := range keys {
pipe.Delete(v)
}
pipe.Delete(this.ukey(uid))
pipe.Exec()
}
return
}

View File

@ -1 +1,3 @@
package db package db

View File

@ -2,6 +2,7 @@ package db
import ( import (
"go_dreamfactory/lego/utils/mapstructure" "go_dreamfactory/lego/utils/mapstructure"
"time"
) )
//DB层配置 //DB层配置
@ -67,3 +68,34 @@ func newOptionsByOption(opts ...Option) (options *Options, err error) {
} }
return return
} }
type DBOption func(*DBOptions)
type DBOptions struct {
IsMgoLog bool //是否写mgolog
Expire time.Duration //过期时间
}
//设置是否写mgor日志
func SetDBMgoLog(v bool) DBOption {
return func(o *DBOptions) {
o.IsMgoLog = v
}
}
//设置过期时间
func SetDBExpire(v time.Duration) DBOption {
return func(o *DBOptions) {
o.Expire = v
}
}
//更具 Option 序列化 系统参数对象
func newDBOption(opts ...DBOption) DBOptions {
options := DBOptions{
IsMgoLog: true,
}
for _, o := range opts {
o(&options)
}
return options
}

241
sys/db/redislua.go Normal file
View File

@ -0,0 +1,241 @@
package db
/*
Redis Lua 脚本备份
*/
//Redis 自定义脚本 批量读取列表数据
var LuaScriptgetList = `
local key = tostring(KEYS[1])
local keys = redis.call("HGETALL", key)
local data = {}
local n = 1
for i, v in ipairs(keys) do
if i%2 == 0 then
data[n] = redis.call("HGETALL", v)
n = n+1
end
end
return data
`
//Redis 自定义脚本 批量写入列表数据
var LuaScriptsetList = `
local n = 1
for i, v in ipairs(KEYS) do
local key = v
local argv = {}
for i=n,#ARGV,1 do
n = n+1
if ARGV[i] == "#end" then
redis.call("HMSet", key,unpack(argv))
break
else
table.insert(argv, ARGV[i])
end
end
end
return "OK"
`
//Redis 自定义脚本 批量卸载列表数据
var LuaScriptdelList = `
local key = tostring(KEYS[1])
local keys = redis.call("HGETALL", key)
for i, v in ipairs(keys) do
if i%2 == 0 then
redis.call("DEL", v)
end
end
redis.call("DEL", key)
return "OK"
`
//Redis 自定义脚本 批量读取队列数据
var LuaScriptgetQueue = `
local key = tostring(KEYS[1])
local count = tonumber(ARGV[1]) * -1
local keys = redis.call("LRANGE", key,count,-1)
local data = {}
for i, v in ipairs(keys) do
data[i] = redis.call("HGETALL", v)
end
return data
`
//Redis 自定义脚本 批量写入队列数据
var LuaScriptsetQueue = `
local count = tonumber(ARGV[1])
local k = tostring(ARGV[3])
local keys = {}
local out = {}
local n = 1
for i, v in ipairs(KEYS) do
if (i == 1) then
for i=n,#ARGV,1 do
n = n+1
if ARGV[i] == "#end" then
break
end
end
elseif (i == 2) then
for i=n,#ARGV,1 do
n = n+1
if ARGV[i] == "#end" then
break
end
end
else
local key = v
local argv = {}
table.insert(keys, key)
for i=n,#ARGV,1 do
n = n+1
if ARGV[i] == "#end" then
redis.call("HMSet", key,unpack(argv))
break
else
table.insert(argv, ARGV[i])
end
end
end
end
redis.call("RPush", k,unpack(keys))
local c = tonumber(redis.call("LLEN", k))
count = count * 3
if (c > count) then
local off = c-count
out = redis.call("LRANGE", k,0,off-1)
redis.call("LTRIM", k,off,-1)
for i, v in ipairs(out) do
redis.call("DEL", v)
end
end
return out
`
/*
//批量读取列表数据
func (this *MCompModel) Batchgetlists(key string) (result []map[string]string, err error) {
var data interface{}
ret := this.Redis.EvalSha(this.Redis.Context(), this.getListSha1, []string{key})
if data, err = ret.Result(); err != nil {
fmt.Printf("Execute batchgetlists err: %v", err.Error())
} else {
temp1 := data.([]interface{})
result = make([]map[string]string, len(temp1))
for i, v := range temp1 {
temp2 := v.([]interface{})
result[i] = make(map[string]string)
for n := 0; n < len(temp2); n += 2 {
result[i][temp2[n].(string)] = temp2[n+1].(string)
}
}
if len(result) == 0 {
err = redis.RedisNil
return
}
}
return
}
//批量写入数据
func (this *MCompModel) Batchsetlists(data map[string]map[string]string) (err error) {
var (
n int
keys []string
values []interface{}
)
keys = make([]string, len(data))
values = make([]interface{}, 0)
for k, v := range data {
keys[n] = k
for k1, v1 := range v {
values = append(values, k1, v1)
}
values = append(values, "#end")
n++
}
ret := this.Redis.EvalSha(this.Redis.Context(), this.setListSha1, keys, values...)
if _, err := ret.Result(); err != nil {
fmt.Printf("Execute batchsetlists err: %v", err.Error())
}
return
}
//批量读取队列数据
func (this *MCompModel) Batchgetqueues(key string, count int32) (result []map[string]string, err error) {
var data interface{}
ret := this.Redis.EvalSha(this.Redis.Context(), this.getQueueSha1, []string{key}, count)
if data, err = ret.Result(); err != nil {
fmt.Printf("Execute batchgetqueues err: %v", err.Error())
} else {
temp1 := data.([]interface{})
result = make([]map[string]string, len(temp1))
for i, v := range temp1 {
temp2 := v.([]interface{})
result[i] = make(map[string]string)
for n := 0; n < len(temp2); n += 2 {
result[i][temp2[n].(string)] = temp2[n+1].(string)
}
}
if len(result) == 0 {
err = redis.RedisNil
return
}
}
return
}
//批量写入队列 并返回移除队列
func (this *MCompModel) Batchsetqueues(key string, count int32, ks []string, vs []map[string]string) (outkey []string, err error) {
var (
n int
keys []string
values []interface{}
result interface{}
)
keys = make([]string, len(ks)+2)
values = make([]interface{}, 0)
keys[0] = "count"
values = append(values, count)
values = append(values, "#end")
keys[1] = "key"
values = append(values, key)
values = append(values, "#end")
n = 2
for i, v := range ks {
keys[n] = v
for k1, v1 := range vs[i] {
values = append(values, k1, v1)
}
values = append(values, "#end")
n++
}
ret := this.Redis.EvalSha(this.Redis.Context(), this.setQueueSha1, keys, values...)
if result, err = ret.Result(); err != nil {
fmt.Printf("Execute batchsetqueues err: %v", err.Error())
} else {
outkey = make([]string, len(result.([]interface{})))
for i, v := range result.([]interface{}) {
outkey[i] = v.(string)
}
}
return
}
//批量删除数据
func (this *MCompModel) BatchDelLists(uid string) (err error) {
ret := this.Redis.EvalSha(this.Redis.Context(), this.dellListSha1, []string{this.ukey(uid)})
if _, err := ret.Result(); err != nil {
fmt.Printf("Execute batchsetlists err: %v", err.Error())
}
return
}
*/