1 Star 1 Fork 1

xiaoyutab / xgotool

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
xmid.go 4.36 KB
一键复制 编辑 原始数据 按行查看 历史
xiaoyutab 提交于 2024-04-30 10:16 . 调整目录结构和依赖位置
package xmid
import (
"errors"
"sync"
"gorm.io/gorm"
)
// 执行事务处理的中间数据依赖
type Context struct {
db sync.Map // 数据库缓存[缓存gorm.DB类型]
oth sync.Map // 其他数据存储[缓存/存储一些其他类型的数据]
err error // 错误导出
handlers []HandlerFunc // 中间件列表
index int // 当前执行的组数据
maxLen int // 待执行的中间件最大数量
hookStart []HandlerFunc // 开始执行的钩子,在调用Run时会首先调用此处的钩子
hookEnd []HandlerFunc // 处理结束的钩子,会在调用Run结束时调用此处函数
hookRollback []HandlerFunc // 发生错误回退时回调的钩子,会在调用Run结束时且发生err时调用此处的钩子
hookCommit []HandlerFunc // 事务提交时的钩子,会在调用Run结束时且未发生err时调用此处的钩子
}
// 设置使用过程中需要调用的一些其他数据
//
// key 待设置的数据下标
// val 待设置的数据值
func (c *Context) SetOth(key string, val any) {
c.oth.Store(key, val)
}
// 获取使用过程中需要调用的一些其他数据
//
// key 待获取的数据下标
func (c *Context) GetOth(key string) (any, error) {
if v, ok := c.oth.Load(key); ok {
if v == nil {
return nil, errors.New("找到的数据值为空")
}
return v, nil
}
return nil, errors.New("数据未找到")
}
// 设置DB 中间件事务处理时使用
//
// key 数据库下标,多数据库连接时使用
// db 待设置的数据库连接
func (c *Context) SetDBS(key string, db *gorm.DB) {
c.db.Store(key, db)
}
// 设置DB 中间件事务处理时使用[等同于调用c.SetDBS("default",xxx)]
//
// db 待设置的数据库连接
func (c *Context) SetDB(db *gorm.DB) {
c.SetDBS("default", db)
}
// 获取事务处理的数据库连接[等同于调用c.GetDBS("default")]
func (c *Context) GetDB() (*gorm.DB, error) {
return c.GetDBS("default")
}
// 获取事务处理的数据库连接
//
// key 数据库下标,多数据库连接时使用
func (c *Context) GetDBS(key string) (*gorm.DB, error) {
if v, ok := c.db.Load(key); ok {
switch db := v.(type) {
case *gorm.DB:
return db, nil
default:
c.db.Delete(key)
}
}
return nil, errors.New("数据连接 " + key + " 不存在")
}
// 添加中间件支持
//
// h 中间件处理过程
func (c *Context) Use(h ...HandlerFunc) *Context {
c.handlers = append(c.handlers, h...)
return c
}
// 开始运行时的钩子
//
// h 开始运行时调用的函数
func (c *Context) HookStart(h ...HandlerFunc) *Context {
c.hookStart = append(c.hookStart, h...)
return c
}
// 运行结束时的钩子
//
// h 运行结束时调用的函数
func (c *Context) HookEnd(h ...HandlerFunc) *Context {
c.hookEnd = append(c.hookEnd, h...)
return c
}
// 发生错误时的回退钩子
//
// h 发生错误时调用的函数
func (c *Context) HookRollback(h ...HandlerFunc) *Context {
c.hookRollback = append(c.hookRollback, h...)
return c
}
// 未发生错误时的提交钩子
//
// h 提交时调用的函数
func (c *Context) HookCommit(h ...HandlerFunc) *Context {
c.hookCommit = append(c.hookCommit, h...)
return c
}
// 执行运行结果
//
// h 待运行函数
func (c *Context) Run(h HandlerFunc) error {
c.handlers = append(c.handlers, h)
c.maxLen = len(c.handlers)
for i := 0; i < len(c.hookStart); i++ {
c.hookStart[i](c)
}
c.index = -1
c.Next()
if c.err == nil {
for i := 0; i < len(c.hookCommit); i++ {
c.hookCommit[i](c)
}
} else {
for i := 0; i < len(c.hookRollback); i++ {
c.hookRollback[i](c)
}
}
for i := 0; i < len(c.hookEnd); i++ {
c.hookEnd[i](c)
}
return c.err
}
// 执行下一个中间件
func (c *Context) Next() {
c.index++
// 如果中间出现过错误信息,就不再往下进行处理,直接将错误信息抛出到最外层
if c.err != nil {
c.Abort()
}
for c.index < c.maxLen {
c.handlers[c.index](c)
c.index++
}
}
// 终止中间件的处理
// 此操作会终止中间件的执行,但是不会调用HookRollback钩子
func (c *Context) Abort() {
c.index = abortConst
}
// 携带错误信息终止中间件的处理,但是不会调用HookCommit钩子
//
// err 携带的错误信息
func (c *Context) AbortWithError(err error) {
c.err = err
c.index = abortConst
}
// 获取其中的错误信息
func (c *Context) Error() error {
return c.err
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Go
1
https://gitee.com/xiaoyutab/xgotool.git
git@gitee.com:xiaoyutab/xgotool.git
xiaoyutab
xgotool
xgotool
v0.3.13

搜索帮助

344bd9b3 5694891 D2dac590 5694891