mirror of
https://github.com/Syngnat/GoNavi.git
synced 2026-05-06 20:03:05 +08:00
- 新增 ResultSetData 结构体承载单个结果集数据 - 新增 MultiResultQuerier/MultiResultQuerierContext 可选接口 - 新增 scanMultiRows 函数利用 NextResultSet() 遍历所有结果集 - MySQL 驱动 DSN 开启 multiStatements=true 并实现多结果集接口 - 新增 DBQueryMulti Wails 方法,支持驱动原生多结果集及自动回退逐条执行 - 新增 Go 版 SQL 拆分函数 splitSQLStatements 及 10 个单元测试 - 前端 QueryEditor handleRun 改为一次性调用 DBQueryMulti - MongoDB 保持独立的逐条执行路径不受影响 - refs #235
84 lines
1.9 KiB
Go
84 lines
1.9 KiB
Go
package db
|
|
|
|
import (
|
|
"database/sql"
|
|
|
|
"GoNavi-Wails/internal/connection"
|
|
)
|
|
|
|
func scanRows(rows *sql.Rows) ([]map[string]interface{}, []string, error) {
|
|
columns, err := rows.Columns()
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
|
|
colTypes, err := rows.ColumnTypes()
|
|
if err != nil || len(colTypes) != len(columns) {
|
|
colTypes = nil
|
|
}
|
|
|
|
resultData := make([]map[string]interface{}, 0)
|
|
|
|
for rows.Next() {
|
|
values := make([]interface{}, len(columns))
|
|
valuePtrs := make([]interface{}, len(columns))
|
|
for i := range columns {
|
|
valuePtrs[i] = &values[i]
|
|
}
|
|
|
|
if err := rows.Scan(valuePtrs...); err != nil {
|
|
continue
|
|
}
|
|
|
|
entry := make(map[string]interface{}, len(columns))
|
|
for i, col := range columns {
|
|
dbTypeName := ""
|
|
if colTypes != nil && i < len(colTypes) && colTypes[i] != nil {
|
|
dbTypeName = colTypes[i].DatabaseTypeName()
|
|
}
|
|
entry[col] = normalizeQueryValueWithDBType(values[i], dbTypeName)
|
|
}
|
|
resultData = append(resultData, entry)
|
|
}
|
|
|
|
if err := rows.Err(); err != nil {
|
|
return resultData, columns, err
|
|
}
|
|
return resultData, columns, nil
|
|
}
|
|
|
|
// scanMultiRows 遍历 sql.Rows 中的所有结果集,将每个结果集作为 ResultSetData 返回。
|
|
// 利用 rows.NextResultSet() 支持一次 query 返回多个结果集的场景。
|
|
func scanMultiRows(rows *sql.Rows) ([]connection.ResultSetData, error) {
|
|
var results []connection.ResultSetData
|
|
for {
|
|
data, cols, err := scanRows(rows)
|
|
if err != nil {
|
|
return results, err
|
|
}
|
|
if data == nil {
|
|
data = make([]map[string]interface{}, 0)
|
|
}
|
|
if cols == nil {
|
|
cols = []string{}
|
|
}
|
|
results = append(results, connection.ResultSetData{
|
|
Rows: data,
|
|
Columns: cols,
|
|
})
|
|
if !rows.NextResultSet() {
|
|
break
|
|
}
|
|
}
|
|
if len(results) == 0 {
|
|
results = []connection.ResultSetData{{
|
|
Rows: make([]map[string]interface{}, 0),
|
|
Columns: []string{},
|
|
}}
|
|
}
|
|
if err := rows.Err(); err != nil {
|
|
return results, err
|
|
}
|
|
return results, nil
|
|
}
|