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 环境变量注入
This commit is contained in:
2026-08-08 10:36:57 +08:00
parent 1f6c8a18a3
commit 9154afab6b
35 changed files with 4956 additions and 37 deletions
+80
View File
@@ -0,0 +1,80 @@
package tests
import (
"time"
"gorm.io/gorm"
)
// User 基本测试模型
type User struct {
ID uint `gorm:"column:id;primaryKey;autoIncrement"`
Name string `gorm:"size:100;not null"`
Email string `gorm:"size:200;uniqueIndex"`
Age int `gorm:"default:0"`
Active bool // 不使用 default,以便显式设置 false 时能正确存储
CreatedAt time.Time
UpdatedAt time.Time
DeletedAt gorm.DeletedAt `gorm:"index"`
}
func (User) TableName() string {
return "TEST_USERS"
}
// Product 测试数值类型
type Product struct {
ID uint `gorm:"column:id;primaryKey;autoIncrement"`
Name string `gorm:"size:200;not null"`
Price float64 `gorm:"precision:10;scale:2"`
Stock int `gorm:"default:0"`
Description string `gorm:"type:CLOB"`
CreatedAt time.Time
}
func (Product) TableName() string {
return "TEST_PRODUCTS"
}
// Order 测试关联关系
type Order struct {
ID uint `gorm:"column:id;primaryKey;autoIncrement"`
UserID uint `gorm:"not null;index"`
User User `gorm:"foreignKey:UserID"`
Total float64 `gorm:"precision:12;scale:2"`
Status string `gorm:"size:20;default:'pending'"`
CreatedAt time.Time
UpdatedAt time.Time
}
func (Order) TableName() string {
return "TEST_ORDERS"
}
// SeqDefaultModel 显式使用序列默认值的模型(主键不用 autoIncrement
// 而是通过列的 DEFAULT 值使用序列 SEQ_TEST_SEQ_DEFAULT.NEXTVAL
type SeqDefaultModel struct {
ID uint `gorm:"column:id;primaryKey"`
Name string `gorm:"size:100"`
}
func (SeqDefaultModel) TableName() string {
return "TEST_SEQ_DEFAULT"
}
// SeqDefaultViaDriverModel 通过驱动 AutoMigrate 建表,验证 11g 下序列默认值的
// 触发器路径(模型使用 gorm:"default:(SEQ_TEST_SEQ_DEF_CODE.NEXTVAL)")。
//
// Code 用 int 字段并给默认值加括号:GORM 对含括号的默认值会跳过 ParseInt 解析
// schema/field.go:231),从而 DefaultValueInterface 保持 nil,字段进入
// FieldsWithDefaultDBValue —— INSERT 时 GORM 会省略该列,触发 BEFORE INSERT 触发器回填序列值。
// 若不加括号,GORM 会把 "SEQ_...NEXTVAL" 当作整数解析失败,schema.Parse 直接报错。
type SeqDefaultViaDriverModel struct {
ID uint `gorm:"column:id;primaryKey"`
Code int `gorm:"column:code;default:(SEQ_TEST_SEQ_DEF_CODE.NEXTVAL)"`
Name string `gorm:"size:100"`
}
func (SeqDefaultViaDriverModel) TableName() string {
return "TEST_SEQ_DEF"
}