🐛 fix(dameng): 修复 SQL 编辑器增删改执行失败

- 使用真实驱动事务执行达梦 DML,并支持显式提交与回滚
- 为 optional driver-agent 增加事务生命周期协议,仅向达梦暴露托管事务能力
- 同步驱动 revision,并补充驱动、代理与工厂回归测试
This commit is contained in:
Syngnat
2026-07-23 09:36:22 +08:00
parent f2d7e3febd
commit 8c0e685429
9 changed files with 508 additions and 63 deletions

View File

@@ -3,6 +3,7 @@ package db
import (
"bufio"
"bytes"
"context"
"strings"
"testing"
@@ -242,3 +243,80 @@ func TestOptionalDriverAgentDBQueryMultiWithMessagesParsesResultSets(t *testing.
t.Fatalf("请求未使用 queryMulti 方法: %s", stdin.String())
}
}
func TestDamengOptionalDriverAgentSupportsManagedTransactions(t *testing.T) {
damengDB, err := NewDatabase("dameng")
if err != nil {
t.Fatalf("create Dameng optional driver database: %v", err)
}
if _, ok := damengDB.(TransactionExecerProvider); !ok {
t.Fatal("expected Dameng optional driver database to expose managed transactions")
}
for _, dbType := range []string{"sqlserver", "kingbase"} {
dbInst, err := NewDatabase(dbType)
if err != nil {
t.Fatalf("create %s optional driver database: %v", dbType, err)
}
if _, ok := dbInst.(TransactionExecerProvider); ok {
t.Fatalf("expected %s to keep using its existing session transaction path", dbType)
}
}
}
func TestOptionalDriverAgentTransactionUsesTransactionRPC(t *testing.T) {
for _, tc := range []struct {
name string
finishMethod string
finish func(TransactionExecer) error
}{
{name: "commit", finishMethod: optionalAgentMethodCommitTransaction, finish: func(tx TransactionExecer) error { return tx.Commit() }},
{name: "rollback", finishMethod: optionalAgentMethodRollbackTransaction, finish: func(tx TransactionExecer) error { return tx.Rollback() }},
} {
t.Run(tc.name, func(t *testing.T) {
var stdin optionalAgentTestWriteCloser
stdout := strings.Join([]string{
`{"id":1,"success":true,"data":"transaction-1"}`,
`{"id":2,"success":true,"rowsAffected":1}`,
`{"id":3,"success":true}`,
`{"id":4,"success":true}`,
}, "\n") + "\n"
dbInst := &optionalDriverAgentTransactionalDB{
OptionalDriverAgentDB: &OptionalDriverAgentDB{
driverType: "dameng",
client: &optionalDriverAgentClient{
stdin: &stdin,
reader: bufio.NewReader(strings.NewReader(stdout)),
driver: "dameng",
},
},
}
tx, err := dbInst.OpenTransactionExecer(context.Background())
if err != nil {
t.Fatalf("OpenTransactionExecer returned error: %v", err)
}
if _, err := tx.ExecContext(context.Background(), "UPDATE t SET v = 1"); err != nil {
t.Fatalf("ExecContext returned error: %v", err)
}
if err := tc.finish(tx); err != nil {
t.Fatalf("finish transaction returned error: %v", err)
}
if err := tx.Close(); err != nil {
t.Fatalf("Close returned error: %v", err)
}
requests := stdin.String()
for _, fragment := range []string{
`"method":"openTransaction"`,
`"method":"exec","sessionId":"transaction-1"`,
`"method":"` + tc.finishMethod + `","sessionId":"transaction-1"`,
`"method":"closeSession","sessionId":"transaction-1"`,
} {
if !strings.Contains(requests, fragment) {
t.Fatalf("expected request fragment %q, got %s", fragment, requests)
}
}
})
}
}