| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586 |
- package vrtxsql
- // 驱动错误: 在 database/sql 边界给错误挂上 SQLSTATE (5 字符), 让调用方可以
- // errors.As 提取状态码做分支 (例如锁冲突重试、约束冲突提示), 而不必解析中文文本。
- //
- // database/sql 本身没有强制的 SQLState 接口; 这里沿用 PostgreSQL/ODBC 约定提供
- // SQLState() string。Unwrap 穿透到被包装的引擎哨兵错误, errors.Is/As 仍可用。
- import (
- "errors"
- "fmt"
- "git.ycl.pub/yl32940/TsDB2/DB/core"
- "git.ycl.pub/yl32940/TsDB2/DB/core/types"
- )
- // SQLError 携带 SQLSTATE 的错误。
- type SQLError struct {
- State string // 5 字符 SQLSTATE
- Message string
- cause error
- }
- func (e *SQLError) Error() string { return e.Message }
- func (e *SQLError) SQLState() string { return e.State }
- func (e *SQLError) Unwrap() error { return e.cause }
- // sqlError 直接构造一个带状态的错误。
- func sqlError(state, format string, args ...any) error {
- return &SQLError{State: state, Message: fmt.Sprintf(format, args...)}
- }
- // withState 给已有错误挂上状态 (保留 cause 链)。
- func withState(err error, state string) error {
- if err == nil {
- return nil
- }
- return &SQLError{State: state, Message: err.Error(), cause: err}
- }
- // classifyError 按引擎哨兵错误映射 SQLSTATE; 已是 *SQLError 的原样返回。
- func classifyError(err error) error {
- if err == nil {
- return nil
- }
- var se *SQLError
- if errors.As(err, &se) {
- return err
- }
- switch {
- // 08/55 — 连接 / 锁
- case errors.Is(err, core.ErrDatabaseLocked):
- return withState(err, "55006") // 库被占用 (object in use)
- // 23 — 完整性约束冲突
- case errors.Is(err, core.ErrDuplicatedKey), errors.Is(err, core.ErrDuplicatePK):
- return withState(err, "23000")
- // 25 — 事务状态
- case errors.Is(err, core.ErrReadOnly):
- return withState(err, "25008") // 只读连接/事务中不能执行
- case errors.Is(err, core.ErrTxnActive):
- return withState(err, "25001") // 活跃事务中
- // 42 — 语法 / 权限相关对象定义
- case errors.Is(err, core.ErrTableNotFound):
- return withState(err, "42S02") // 表不存在
- case errors.Is(err, core.ErrFieldNotFound):
- return withState(err, "42S22") // 列不存在
- case errors.Is(err, core.ErrIndexNotFound):
- return withState(err, "42S12") // 索引不存在
- case errors.Is(err, core.ErrTableExists):
- return withState(err, "42S01") // 表已存在
- case errors.Is(err, core.ErrIndexExists):
- return withState(err, "42S11") // 索引已存在
- case errors.Is(err, core.ErrFieldExists):
- return withState(err, "42S21") // 列已存在
- // 22 — 数据异常 (类型不匹配 / 超范围 / 编码)
- case errors.Is(err, types.ErrValueType), errors.Is(err, types.ErrValueRange),
- errors.Is(err, types.ErrColumnScale), errors.Is(err, types.ErrDecimalRange),
- errors.Is(err, types.ErrEncodeBufSize):
- return withState(err, "22000")
- }
- return err
- }
|