Files
charlie 9154afab6b feat: Oracle 驱动完整化——回调体系、版本感知、驱动抽象层与测试套件
- 新增驱动抽象层 driver_adapter(go-ora/godror 双驱动切换)
- 新增 Update/Delete/Query 回调,完善 RETURNING INTO 子句
- 修复 create.go 事务悬挂行 BUG、批量 RowsAffected、主键 WHERE 注入
- 版本感知体系:分页/自增/序列默认值/BOOLEAN/32k VARCHAR2 分级能力判定
- 11g 序列+触发器自增、ON UPDATE 触发器、默认值智能转换
- 升级 go-ora v2.8.19 → v2.9.0
- 单元测试+模块测试+集成测试共 96 个,真实 Oracle 11g 全绿
- 测试 DSN 密码移除,改为 ORACLE_DSN 环境变量注入
2026-08-08 10:36:57 +08:00

190 lines
4.1 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// Package driver_adapter 提供 Oracle 驱动抽象层
// 支持 go-ora 和 godror 两种底层驱动的切换
package driver_adapter
import (
"context"
"database/sql"
go_ora "github.com/sijms/go-ora/v2"
)
// GoOraAdapter go-ora 驱动适配器
type GoOraAdapter struct{}
// goOraOutParam 包装 go_ora.Out
type goOraOutParam struct {
out go_ora.Out
}
// GetDest 返回目标指针
func (o *goOraOutParam) GetDest() interface{} {
return o.out.Dest
}
// SetSize 设置缓冲区大小(用于字符串类型)
func (o *goOraOutParam) SetSize(size int) {
o.out.Size = size
}
// GetSize 获取缓冲区大小
func (o *goOraOutParam) GetSize() int {
return o.out.Size
}
// goOraLobData 包装 go_ora.Clob 和 go_ora.Blob
type goOraLobData struct {
isClob bool
strVal string
byteVal []byte
valid bool
}
// IsCLOB 是否为 CLOB 类型
func (l *goOraLobData) IsCLOB() bool {
return l.isClob
}
// IsBLOB 是否为 BLOB 类型
func (l *goOraLobData) IsBLOB() bool {
return !l.isClob
}
// GetString 获取字符串值(CLOB
func (l *goOraLobData) GetString() string {
return l.strVal
}
// GetBytes 获取字节值(BLOB
func (l *goOraLobData) GetBytes() []byte {
return l.byteVal
}
// IsValid 是否有效
func (l *goOraLobData) IsValid() bool {
return l.valid
}
// goOraBatchData 包装批量数据
type goOraBatchData struct {
values []interface{}
}
// Len 返回数据长度
func (b *goOraBatchData) Len() int {
return len(b.values)
}
// GetValues 返回所有值
func (b *goOraBatchData) GetValues() []interface{} {
return b.values
}
// Name 返回驱动名称
func (a *GoOraAdapter) Name() string {
return "go-ora"
}
// Type 返回驱动类型
func (a *GoOraAdapter) Type() DriverType {
return DriverGoOra
}
// Open 打开数据库连接
func (a *GoOraAdapter) Open(dsn string) (*sql.DB, error) {
return sql.Open("oracle", dsn)
}
// CreateOutParam 创建输出参数(用于 RETURNING INTO
func (a *GoOraAdapter) CreateOutParam(dest interface{}, size int) OutParam {
return &goOraOutParam{
out: go_ora.Out{Dest: dest, Size: size},
}
}
// CreateClob 创建 CLOB 数据
func (a *GoOraAdapter) CreateClob(value string) LobData {
return &goOraLobData{
isClob: true,
strVal: value,
byteVal: nil,
valid: true,
}
}
// CreateBlob 创建 BLOB 数据
func (a *GoOraAdapter) CreateBlob(value []byte) LobData {
return &goOraLobData{
isClob: false,
strVal: "",
byteVal: value,
valid: true,
}
}
// CreateBatch 创建批量数据
func (a *GoOraAdapter) CreateBatch(values []interface{}) BatchData {
return &goOraBatchData{
values: values,
}
}
// NeedsSizeForOut 返回输出参数是否需要指定 Size
func (a *GoOraAdapter) NeedsSizeForOut() bool {
return true
}
// SupportsReturningMultiRow 返回是否支持多行 RETURNING
func (a *GoOraAdapter) SupportsReturningMultiRow() bool {
return false
}
// SupportsBulkCopy 返回是否支持 BulkCopy
func (a *GoOraAdapter) SupportsBulkCopy() bool {
return true
}
// WrapClobForInsert 包装 CLOB 值用于插入
func (a *GoOraAdapter) WrapClobForInsert(value string) interface{} {
return go_ora.Clob{String: value, Valid: true}
}
// WrapBlobForInsert 包装 BLOB 值用于插入
func (a *GoOraAdapter) WrapBlobForInsert(value []byte) interface{} {
return go_ora.Blob{Data: value, Valid: true}
}
// UnwrapQueryResult 解包查询结果
func (a *GoOraAdapter) UnwrapQueryResult(value interface{}, typeName string) interface{} {
// 根据需要处理 go-ora 特有的返回类型转换
// 这里简单返回原始值,可根据实际需求扩展
return value
}
// GetConnection 获取底层连接(用于高级操作)
func (a *GoOraAdapter) GetConnection(db *sql.DB) (interface{}, error) {
conn, err := db.Conn(context.Background())
if err != nil {
return nil, err
}
defer conn.Close()
var rawConn interface{}
err = conn.Raw(func(driverConn interface{}) error {
rawConn = driverConn
return nil
})
return rawConn, err
}
// Ping 检查连接是否可用
func (a *GoOraAdapter) Ping(ctx context.Context, db *sql.DB) error {
return db.PingContext(ctx)
}
// init 函数中注册驱动
func init() {
Register(DriverGoOra, func() Adapter {
return &GoOraAdapter{}
})
}