package mdbc import ( "context" "time" "github.com/go-redis/redis/v8" ) type cacheConfig struct { enable bool // 是否缓存 ttl time.Duration // 缓存时间 client redis.UniversalClient // 全局缓存redis句柄 [缓存、熔断器] } type breakerConfig struct { ttl time.Duration // 熔断时间 reporter bool // 是否开启熔断告警 开启熔断告警 需要配置全局的redis 否则开启无效 } // CacheObject 生成的缓存对象 type CacheObject struct { // Key redis的key Key string // Value redis的value 请自行marshal对象value // 如果value是一个对象 请将该对象实现 encoding.BinaryMarshaler // 你可以参考 DefaultFindOneCacheFunc 其利用 json.Marshal 实现了对 value 的序列化 Value interface{} } // Scope 所有操作基于此结构 自定义结构体 将其匿名以继承其子scope type Scope struct { *Model // 模型 cache *cacheConfig // 缓存配置项 breaker *breakerConfig // 熔断配置项 execT time.Duration // 执行时间 后续debug和熔断告警用到 debug bool // 是否开启debug debugWhenError bool // 当错误时才输出debug信息 } type ctxWrap struct { ctx context.Context // 上下文 cancel context.CancelFunc // 上下文取消 } func (s *Scope) newDefaultCtxWrap() *ctxWrap { return &ctxWrap{} } // SetDebug 是否开启执行语句的日志输出 目前仅支持终端输出 func (s *Scope) SetDebug(debug bool) *Scope { s.debug = debug return s } // SetDebugError 是否开启仅当错误时打印执行语句的日志 目前仅支持终端输出 func (s *Scope) SetDebugError(debug bool) *Scope { s.debugWhenError = debug return s } // SetBreaker 设置熔断时间 不配置默认5s熔断 // 此处建议在全局进行配置一次 否则会有覆盖后失效风险 func (s *Scope) SetBreaker(duration time.Duration) *Scope { if s.breaker == nil { s.breaker = &breakerConfig{} } s.breaker.ttl = duration return s } // SetBreakerReporter 设置开启熔断告警 func (s *Scope) SetBreakerReporter(br bool) *Scope { if s.breaker == nil { s.breaker = &breakerConfig{} } s.breaker.reporter = br return s } // SetCacheIdle 设置redis句柄 方便查询操作进行缓存 // 此处建议在全局进行配置一次 否则会有覆盖后失效风险 func (s *Scope) SetCacheIdle(cli redis.UniversalClient) *Scope { if s.cache == nil { s.cache = &cacheConfig{} } s.cache.client = cli return s } // SetCacheExpiredAt 设置redis缓存过期时间 不设置 则不缓存 单位time.Duration // 此处建议在全局进行配置一次 否则会有覆盖后失效风险 func (s *Scope) SetCacheExpiredAt(t time.Duration) *Scope { if s.cache == nil { s.cache = &cacheConfig{} } s.cache.ttl = t s.cache.enable = true return s } // SetCacheForever 设置key永不过期 true永不过期 // 此处建议在全局进行配置一次 否则会有覆盖后失效风险 func (s *Scope) SetCacheForever(b bool) *Scope { if s.cache == nil { s.cache = &cacheConfig{} } if b { s.cache.ttl = -1 s.cache.enable = true } return s } // GetTableName 获取当前连接的表名 func (s *Scope) GetTableName() string { return s.tableName } // check ctx检测和初始化 func (s *Scope) check() { if s.breaker == nil { s.breaker = &breakerConfig{} } // 设置默认熔断时间 5秒 if s.breaker.ttl == 0 { s.breaker.ttl = 5 * time.Second } } // RawConn 返回原始的mongoDB 操作资源句柄 func (s *Scope) RawConn() *Collection { return db.Collection(s.tableName) } // Aggregate 聚合操作 func (s *Scope) Aggregate() *AggregateScope { s.check() as := &AggregateScope{cw: s.newDefaultCtxWrap(), scope: s} return as } // Find 查询列表操作 func (s *Scope) Find() *FindScope { s.check() fs := &FindScope{cw: s.newDefaultCtxWrap(), scope: s} return fs } // FindOne 查询一条操作 func (s *Scope) FindOne() *FindOneScope { s.check() fs := &FindOneScope{cw: s.newDefaultCtxWrap(), scope: s} return fs } // Update 更新文档操作 func (s *Scope) Update() *UpdateScope { s.check() us := &UpdateScope{cw: s.newDefaultCtxWrap(), scope: s} return us } // Delete 删除文档操作 func (s *Scope) Delete() *DeleteScope { s.check() ds := &DeleteScope{cw: s.newDefaultCtxWrap(), scope: s} return ds } // Insert 插入文档操作 func (s *Scope) Insert() *InsertScope { s.check() is := &InsertScope{cw: s.newDefaultCtxWrap(), scope: s} return is } // Distinct Distinct操作 func (s *Scope) Distinct() *DistinctScope { s.check() ds := &DistinctScope{cw: s.newDefaultCtxWrap(), scope: s} return ds } // Index 索引操作 func (s *Scope) Index() *IndexScope { s.check() is := &IndexScope{cw: s.newDefaultCtxWrap(), scope: s} return is } // BulkWrite 批量写操作 func (s *Scope) BulkWrite() *BulkWriteScope { s.check() bws := &BulkWriteScope{cw: s.newDefaultCtxWrap(), scope: s} return bws } // Count 计数操作 func (s *Scope) Count() *CountScope { s.check() cs := &CountScope{cw: s.newDefaultCtxWrap(), scope: s} return cs } // Drop 集合删除操作 func (s *Scope) Drop() *DropScope { s.check() ds := &DropScope{cw: s.newDefaultCtxWrap(), scope: s} return ds } // Transaction 事务操作 func (s *Scope) Transaction() *TransactionScope { s.check() tx := &TransactionScope{cw: s.newDefaultCtxWrap(), scope: s} return tx } // Retry mongo失败后的重试机制 func (s *Scope) Retry(since int64) {}