driver

package
v0.0.15 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 20, 2025 License: MIT Imports: 9 Imported by: 0

README

Database SQL Driver Hook

这个包提供了一个 Go 语言数据库驱动的扩展,允许在数据库操作的前后添加钩子(Hook)函数。通过这个扩展,你可以轻松地实现数据库操作的监控、日志记录、性能分析等功能。

设计思路

核心组件
  1. 操作类型(OpType)

    • 定义了所有可能的数据库操作类型
    • 包括:连接、事务、预处理语句、执行、查询等
    • 每个操作类型都有对应的字符串表示
  2. 钩子上下文(HookContext)

    • 包含操作的完整上下文信息
    • 原始 Context
    • 操作类型
    • SQL 语句
    • 参数列表
    • 开始时间
    • 结束时间
    • 操作结果
    • 错误信息
    • 自定义数据存储(hookMap)
  3. 钩子接口(Hook)

    • Before:操作执行前调用
    • After:操作执行后调用
    • 可以访问完整的操作上下文
  4. 钩子管理器(HookManager)

    • 管理多个钩子的执行
    • 支持添加多个钩子
    • Before 按正序执行
    • After 按倒序执行
  5. 驱动包装器(KitDriver)

    • 包装原始数据库驱动
    • 在所有操作前后调用钩子
    • 保持与原始驱动完全兼容
工作流程
  1. 创建钩子实例
  2. 创建钩子管理器
  3. 将钩子添加到管理器
  4. 使用管理器包装原始驱动
  5. 注册包装后的驱动
  6. 正常使用数据库,钩子会自动执行

使用方法

基本用法
import (
    "database/sql"
    "github.com/fsyyft-go/kit/database/sql/driver"
)

// 1. 实现自定义钩子
type MyHook struct{}

func (h *MyHook) Before(ctx *driver.HookContext) error {
    // 操作执行前的逻辑
    return nil
}

func (h *MyHook) After(ctx *driver.HookContext) error {
    // 操作执行后的逻辑
    return nil
}

// 2. 创建并注册包装的驱动
func main() {
    // 创建原始驱动
    originalDriver := &mysql.MySQLDriver{}

    // 创建钩子
    hook := &MyHook{}

    // 创建钩子管理器
    hookManager := driver.NewHookManager()
    hookManager.AddHook(hook)

    // 创建包装的驱动
    wrappedDriver := driver.NewKitDriver(originalDriver, hookManager)

    // 注册驱动
    sql.Register("mysql-with-hook", wrappedDriver)

    // 使用包装的驱动
    db, err := sql.Open("mysql-with-hook", "user:password@/dbname")
    if err != nil {
        log.Fatal(err)
    }
    defer db.Close()

    // 正常使用数据库
    // 所有操作都会触发钩子
}
示例:性能监控钩子
type TimingHook struct{}

func (h *TimingHook) Before(ctx *driver.HookContext) error {
    log.Printf("[%s] 开始执行,SQL: %s,参数: %v", 
        ctx.OpType(), ctx.Query(), ctx.Args())
    return nil
}

func (h *TimingHook) After(ctx *driver.HookContext) error {
    duration := ctx.EndTime().Sub(ctx.StartTime())
    log.Printf("[%s] 执行完成,耗时: %v,错误: %v", 
        ctx.OpType(), duration, ctx.OriginError())
    return nil
}

支持的操作类型

  • OpConnect: 连接数据库
  • OpBegin: 开始事务
  • OpCommit: 提交事务
  • OpRollback: 回滚事务
  • OpPrepare: 预处理语句
  • OpStmtExec: 执行预处理语句
  • OpStmtQuery: 查询预处理语句
  • OpStmtClose: 关闭预处理语句
  • OpExec: 执行 SQL
  • OpQuery: 查询 SQL
  • OpPing: Ping 操作

注意事项

  1. 钩子执行顺序

    • Before 钩子按添加顺序执行
    • After 钩子按添加顺序的反序执行
    • 任何钩子返回错误都会中断执行
  2. 上下文数据

    • HookContext 实现了 context.Context 接口
    • 可以通过 GetHookValue/SetHookValue 在钩子间共享数据
    • 所有时间相关的字段都是只读的
  3. 性能考虑

    • 钩子的执行会增加一定的开销
    • 建议在钩子中避免耗时操作
    • 可以使用 goroutine 处理异步任务
  4. 错误处理

    • Before 钩子的错误会阻止操作执行
    • After 钩子的错误会覆盖操作的错误
    • 建议在 After 钩子中避免返回错误

贡献

欢迎提交 Issue 和 Pull Request!

许可证

使用 BSD 许可证 - 查看 LICENSE 文件了解更多信息。

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Hook

type Hook interface {
	// Before 在操作执行前调用。
	//
	// 参数:
	//   - ctx:钩子上下文,包含操作的相关信息。
	//
	// 返回值:
	//   - error:如果钩子执行出错,返回相应的错误信息。
	Before(ctx *HookContext) error

	// After 在操作执行后调用。
	//
	// 参数:
	//   - ctx:钩子上下文,包含操作的相关信息和结果。
	//
	// 返回值:
	//   - error:如果钩子执行出错,返回相应的错误信息。
	After(ctx *HookContext) error
}

Hook 定义数据库操作的钩子接口。 该接口提供了以下功能: - 在数据库操作执行前后执行自定义逻辑。 - 支持错误处理和日志记录。 - 支持性能监控和统计。 - 支持自定义的数据处理。

type HookContext

type HookContext struct {
	// contains filtered or unexported fields
}

HookContext 包含数据库操作的上下文信息。 该结构体提供了以下功能: - 记录数据库操作的详细信息,包括操作类型、SQL 语句和参数。 - 跟踪操作的执行时间和结果。 - 提供自定义数据的存储和访问。 - 支持上下文传递和取消。

func NewHookContext

func NewHookContext(ctx context.Context, opType OpType, query string, args []driver.NamedValue) *HookContext

NewHookContext 创建一个新的 HookContext 实例。

参数:

  • ctx:原始上下文对象,用于控制操作的生命周期。
  • opType:操作类型,表示当前执行的数据库操作。
  • query:SQL 查询语句,可以为空。
  • args:SQL 语句的参数列表,可以为 nil。

返回值:

  • *HookContext:返回一个新创建的 HookContext 实例。

func (*HookContext) Args

func (h *HookContext) Args() []driver.NamedValue

Args 返回操作参数。

返回值:

  • []driver.NamedValue:返回 SQL 语句的参数列表。

func (*HookContext) Deadline

func (h *HookContext) Deadline() (deadline time.Time, ok bool)

Deadline 实现 context.Context 接口。

返回值:

  • deadline:返回上下文的截止时间。
  • ok:如果设置了截止时间返回 true,否则返回 false。

func (*HookContext) Done

func (h *HookContext) Done() <-chan struct{}

Done 实现 context.Context 接口。

返回值:

  • <-chan struct{}:返回一个 channel,当上下文被取消时会被关闭。

func (*HookContext) Duration

func (h *HookContext) Duration() time.Duration

Duration 返回操作持续时间。

返回值:

  • time.Duration:返回操作的持续时间。

func (*HookContext) EndTime

func (h *HookContext) EndTime() time.Time

EndTime 返回操作结束时间。

返回值:

  • time.Time:返回操作的结束时间。

func (*HookContext) Err

func (h *HookContext) Err() error

Err 实现 context.Context 接口。

返回值:

  • error:如果上下文被取消,返回取消的原因。

func (*HookContext) GetHookValue

func (h *HookContext) GetHookValue(key string) (interface{}, bool)

GetHookValue 获取 hook 中的值。

参数:

  • key:要获取的键名。

返回值:

  • interface{}:返回与键关联的值。
  • bool:如果键存在返回 true,否则返回 false。

func (*HookContext) OpType

func (h *HookContext) OpType() OpType

OpType 返回操作类型。

返回值:

  • OpType:返回当前操作的类型。

func (*HookContext) OriginError

func (h *HookContext) OriginError() error

OriginError 返回原始操作错误。

返回值:

  • error:返回操作过程中产生的原始错误。

func (*HookContext) OriginResult

func (h *HookContext) OriginResult() interface{}

OriginResult 返回原始操作结果。

返回值:

  • interface{}:返回操作的原始结果。

func (*HookContext) Query

func (h *HookContext) Query() string

Query 返回操作语句。

返回值:

  • string:返回 SQL 查询语句。

func (*HookContext) SetHookValue

func (h *HookContext) SetHookValue(key string, value interface{})

SetHookValue 设置 hook 中的值。

参数:

  • key:要设置的键名。
  • value:要存储的值。

func (*HookContext) SetResult

func (h *HookContext) SetResult(result interface{}, err error)

SetResult 设置操作结果和结束时间。

参数:

  • result:操作的结果,可以是任意类型。
  • err:操作过程中产生的错误,如果没有错误则为 nil。

func (*HookContext) StartTime

func (h *HookContext) StartTime() time.Time

StartTime 返回操作开始时间。

返回值:

  • time.Time:返回操作的开始时间。

func (*HookContext) Value

func (h *HookContext) Value(key interface{}) interface{}

Value 实现 context.Context 接口。

参数:

  • key:要获取的值的键。

返回值:

  • interface{}:返回与键关联的值。

type HookLogError

type HookLogError struct {
	// contains filtered or unexported fields
}

HookLogError 用于记录数据库操作中的错误信息。

func NewHookLogError

func NewHookLogError(namespace string, logger kitlog.Logger) *HookLogError

NewHookLogError 创建一个新的 HookLogError 实例。

参数:

  • namespace:日志记录的命名空间。
  • logger:用于记录错误信息的日志记录器。

返回值:

  • *HookLogError:返回一个新创建的 HookLogError 实例。

func (*HookLogError) After

func (h *HookLogError) After(ctx *HookContext) error

After 实现 Hook 接口的 After 方法,用于记录操作中的错误信息。

参数:

  • ctx:钩子上下文,包含操作的相关信息和结果。

返回值:

  • error:始终返回 nil,因为这个钩子不会中断操作。

func (*HookLogError) Before

func (h *HookLogError) Before(ctx *HookContext) error

Before 实现 Hook 接口的 Before 方法。

参数:

  • ctx:钩子上下文,包含操作的相关信息。

返回值:

  • error:始终返回 nil,因为这个钩子不会中断操作。

type HookLogSlow

type HookLogSlow struct {
	// contains filtered or unexported fields
}

HookLogSlow 用于记录数据库慢查询操作。

func NewHookLogSlow

func NewHookLogSlow(namespace string, logger kitlog.Logger, threshold time.Duration) *HookLogSlow

NewHookLogSlow 创建一个新的 HookLogSlow 实例。

参数:

  • namespace:日志记录的命名空间。
  • logger:用于记录慢查询信息的日志记录器。
  • threshold:慢查询的时间阈值,超过这个时间的查询会被记录。

返回值:

  • *HookLogSlow:返回一个新创建的 HookLogSlow 实例。

func (*HookLogSlow) After

func (h *HookLogSlow) After(ctx *HookContext) error

After 实现 Hook 接口的 After 方法,用于记录慢查询信息。

参数:

  • ctx:钩子上下文,包含操作的相关信息和结果。

返回值:

  • error:始终返回 nil,因为这个钩子不会中断操作。

func (*HookLogSlow) Before

func (h *HookLogSlow) Before(ctx *HookContext) error

Before 实现 Hook 接口的 Before 方法。

参数:

  • ctx:钩子上下文,包含操作的相关信息。

返回值:

  • error:始终返回 nil,因为这个钩子不会中断操作。

type HookManager

type HookManager struct {
	// contains filtered or unexported fields
}

HookManager 管理多个 Hook 的执行。 该结构体提供了以下功能: - 注册和管理多个钩子 - 按顺序执行钩子链 - 支持钩子的动态添加和移除 - 提供钩子执行的错误处理

func NewHookManager

func NewHookManager() *HookManager

NewHookManager 创建一个新的 HookManager 实例。

返回值:

  • *HookManager:返回一个新创建的 HookManager 实例。

func (*HookManager) AddHook

func (m *HookManager) AddHook(hook Hook)

AddHook 添加一个 Hook。

参数:

  • hook:要添加的钩子实例。

func (*HookManager) After

func (m *HookManager) After(ctx *HookContext) error

After 实现 Hook 接口,按逆序执行所有 Hook 的 After 方法。

参数:

  • ctx:钩子上下文,包含操作的相关信息和结果。

返回值:

  • error:如果任何钩子执行出错,返回第一个错误信息。

func (*HookManager) Before

func (m *HookManager) Before(ctx *HookContext) error

Before 实现 Hook 接口,按顺序执行所有 Hook 的 Before 方法。

参数:

  • ctx:钩子上下文,包含操作的相关信息。

返回值:

  • error:如果任何钩子执行出错,返回第一个错误信息。

type KitDriver

type KitDriver struct {
	// contains filtered or unexported fields
}

KitDriver 是一个数据库驱动包装器,用于添加钩子功能。

func NewKitDriver

func NewKitDriver(d driver.Driver, h Hook) *KitDriver

NewKitDriver 创建一个新的 KitDriver 实例。

参数:

  • d:原始数据库驱动实例,用于执行实际的数据库操作。
  • h:钩子接口实例,用于在数据库操作前后执行自定义逻辑。

返回值:

  • *KitDriver:返回一个新创建的 KitDriver 实例。

func (*KitDriver) Open

func (d *KitDriver) Open(name string) (driver.Conn, error)

Open 实现 driver.Driver 接口,用于创建数据库连接。

参数:

  • name:数据源名称(DSN),包含数据库连接所需的配置信息。

返回值:

  • driver.Conn:数据库连接接口。
  • error:如果连接过程中发生错误,返回相应的错误信息。

type OpType

type OpType int

OpType 表示数据库操作类型。

const (
	// OpConnect 表示连接操作。
	OpConnect OpType = iota
	// OpBegin 表示开始事务操作。
	OpBegin
	// OpCommit 表示提交事务操作。
	OpCommit
	// OpRollback 表示回滚事务操作。
	OpRollback
	// OpPrepare 表示预处理语句操作。
	OpPrepare
	// OpStmtExec 表示执行预处理语句操作。
	OpStmtExec
	// OpStmtQuery 表示查询预处理语句操作。
	OpStmtQuery
	// OpStmtClose 表示关闭预处理语句操作。
	OpStmtClose
	// OpExec 表示执行操作。
	OpExec
	// OpQuery 表示查询操作。
	OpQuery
	// OpPing 表示 ping 操作。
	OpPing
)

func (OpType) String

func (o OpType) String() string

String 返回操作类型的字符串表示。

返回值:

  • string:返回操作类型对应的字符串描述。

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL