Files
oracle/driver_adapter/godror.go
T
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

197 lines
4.0 KiB
Go
Raw 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.
//go:build godror
package driver_adapter
import (
"context"
"database/sql"
"fmt"
)
// GodrorAdapter godror 驱动适配器
type GodrorAdapter struct{}
// godrorOutParam godror 输出参数包装
type godrorOutParam struct {
dest interface{}
size int
}
func (p *godrorOutParam) GetDest() interface{} {
return p.dest
}
func (p *godrorOutParam) SetSize(size int) {
p.size = size
}
func (p *godrorOutParam) GetSize() int {
return p.size
}
// godrorLobData godror LOB 数据包装
type godrorLobData struct {
isClob bool
strVal string
byteVal []byte
valid bool
}
func (l *godrorLobData) IsCLOB() bool {
return l.isClob
}
func (l *godrorLobData) IsBLOB() bool {
return !l.isClob
}
func (l *godrorLobData) GetString() string {
return l.strVal
}
func (l *godrorLobData) GetBytes() []byte {
return l.byteVal
}
func (l *godrorLobData) IsValid() bool {
return l.valid
}
// godrorBatchData godror 批量数据包装
type godrorBatchData struct {
values []interface{}
}
func (b *godrorBatchData) Len() int {
return len(b.values)
}
func (b *godrorBatchData) GetValues() []interface{} {
return b.values
}
// Name 返回驱动名称
func (a *GodrorAdapter) Name() string {
return "godror"
}
// Type 返回驱动类型
func (a *GodrorAdapter) Type() DriverType {
return DriverGodror
}
// Open 打开数据库连接
func (a *GodrorAdapter) Open(dsn string) (*sql.DB, error) {
db, err := sql.Open("godror", dsn)
if err != nil {
return nil, fmt.Errorf("failed to open connection with godror: %w", err)
}
return db, nil
}
// CreateOutParam 创建输出参数(用于 RETURNING INTO
func (a *GodrorAdapter) CreateOutParam(dest interface{}, size int) OutParam {
return &godrorOutParam{
dest: dest,
size: size,
}
}
// CreateClob 创建 CLOB 数据
func (a *GodrorAdapter) CreateClob(value string) LobData {
return &godrorLobData{
isClob: true,
strVal: value,
valid: true,
byteVal: nil,
}
}
// CreateBlob 创建 BLOB 数据
func (a *GodrorAdapter) CreateBlob(value []byte) LobData {
return &godrorLobData{
isClob: false,
byteVal: value,
valid: true,
strVal: "",
}
}
// CreateBatch 创建批量数据
func (a *GodrorAdapter) CreateBatch(values []interface{}) BatchData {
return &godrorBatchData{
values: values,
}
}
// NeedsSizeForOut 返回输出参数是否需要指定 Size
func (a *GodrorAdapter) NeedsSizeForOut() bool {
return false
}
// SupportsReturningMultiRow 返回是否支持多行 RETURNING
func (a *GodrorAdapter) SupportsReturningMultiRow() bool {
return true
}
// SupportsBulkCopy 返回是否支持 BulkCopy
func (a *GodrorAdapter) SupportsBulkCopy() bool {
return false
}
// WrapClobForInsert 包装 CLOB 值用于插入
func (a *GodrorAdapter) WrapClobForInsert(value string) interface{} {
// godror 可以直接处理字符串作为 CLOB
return value
}
// WrapBlobForInsert 包装 BLOB 值用于插入
func (a *GodrorAdapter) WrapBlobForInsert(value []byte) interface{} {
// godror 可以直接处理字节数组作为 BLOB
return value
}
// UnwrapQueryResult 解包查询结果
func (a *GodrorAdapter) UnwrapQueryResult(value interface{}, typeName string) interface{} {
// godror 通常返回标准 Go 类型,无需特殊处理
// 但如果遇到特定类型,可以在这里进行转换
switch v := value.(type) {
case *string:
if v == nil {
return nil
}
return *v
case *[]byte:
if v == nil {
return nil
}
return *v
default:
return value
}
}
// GetConnection 获取底层连接(用于高级操作)
func (a *GodrorAdapter) GetConnection(db *sql.DB) (interface{}, error) {
// 从 sql.DB 获取原始连接
conn, err := db.Conn(context.Background())
if err != nil {
return nil, err
}
defer conn.Close()
// 返回原始连接
return conn, nil
}
// Ping 检查连接是否可用
func (a *GodrorAdapter) Ping(ctx context.Context, db *sql.DB) error {
return db.PingContext(ctx)
}
// init 注册 godror 驱动适配器
func init() {
Register(DriverGodror, func() Adapter {
return &GodrorAdapter{}
})
}