From 18ed4ca50c4bdac99801755fb1abd49ea8c20bd5 Mon Sep 17 00:00:00 2001 From: tianqijiuyun-latiao <69459608+tianqijiuyun-latiao@users.noreply.github.com> Date: Fri, 6 Mar 2026 08:01:40 +0800 Subject: [PATCH] =?UTF-8?q?fix(dameng-databases):=20=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E6=98=BE=E7=A4=BA=E5=85=A8=E9=83=A8=E5=BA=93=E6=97=B6=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E5=BA=93=E5=88=97=E8=A1=A8=E4=B8=8D=E5=AE=8C=E6=95=B4?= =?UTF-8?q?=20refs=20#154?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal/db/dameng_impl.go | 81 ++++++++++++++++++++++++++++++++------ 1 file changed, 70 insertions(+), 11 deletions(-) diff --git a/internal/db/dameng_impl.go b/internal/db/dameng_impl.go index 5080540..5cceb0a 100644 --- a/internal/db/dameng_impl.go +++ b/internal/db/dameng_impl.go @@ -8,6 +8,7 @@ import ( "fmt" "net" "net/url" + "sort" "strconv" "strings" "time" @@ -204,24 +205,82 @@ func (d *DamengDB) Exec(query string) (int64, error) { } func (d *DamengDB) GetDatabases() ([]string, error) { - // DM: List Users/Schemas - data, _, err := d.Query("SELECT username FROM dba_users") - if err != nil { - // Fallback if dba_users not accessible - data, _, err = d.Query("SELECT username FROM all_users") + // 达梦将「用户/模式」作为数据库列表来源,不同权限下可见口径不同。 + // 这里采用多查询口径聚合,避免仅依赖单一视图导致“少库”。 + queries := []string{ + "SELECT USERNAME AS DATABASE_NAME FROM SYS.DBA_USERS ORDER BY USERNAME", + "SELECT USERNAME AS DATABASE_NAME FROM DBA_USERS ORDER BY USERNAME", + "SELECT USERNAME AS DATABASE_NAME FROM ALL_USERS ORDER BY USERNAME", + "SELECT USERNAME AS DATABASE_NAME FROM USER_USERS", + "SELECT DISTINCT OWNER AS DATABASE_NAME FROM ALL_TABLES ORDER BY OWNER", + } + + seen := make(map[string]struct{}) + dbs := make([]string, 0, 64) + var lastErr error + success := false + + for _, q := range queries { + data, _, err := d.Query(q) if err != nil { - return nil, err + lastErr = err + continue + } + success = true + for _, row := range data { + name := getDamengRowString(row, "DATABASE_NAME", "USERNAME", "OWNER", "SCHEMA_NAME") + if name == "" { + // 回退到第一列,兼容驱动返回列名差异。 + for _, v := range row { + text := strings.TrimSpace(fmt.Sprintf("%v", v)) + if text == "" || strings.EqualFold(text, "") { + continue + } + name = text + break + } + } + if name == "" { + continue + } + key := strings.ToUpper(name) + if _, ok := seen[key]; ok { + continue + } + seen[key] = struct{}{} + dbs = append(dbs, name) } } - var dbs []string - for _, row := range data { - if val, ok := row["USERNAME"]; ok { - dbs = append(dbs, fmt.Sprintf("%v", val)) - } + + if !success && lastErr != nil { + return nil, lastErr } + + sort.Slice(dbs, func(i, j int) bool { + return strings.ToUpper(dbs[i]) < strings.ToUpper(dbs[j]) + }) return dbs, nil } +func getDamengRowString(row map[string]interface{}, keys ...string) string { + if len(row) == 0 { + return "" + } + for _, key := range keys { + for k, v := range row { + if !strings.EqualFold(strings.TrimSpace(k), strings.TrimSpace(key)) { + continue + } + text := strings.TrimSpace(fmt.Sprintf("%v", v)) + if text == "" || strings.EqualFold(text, "") { + return "" + } + return text + } + } + return "" +} + func (d *DamengDB) GetTables(dbName string) ([]string, error) { query := fmt.Sprintf("SELECT owner, table_name FROM all_tables WHERE owner = '%s' ORDER BY table_name", strings.ToUpper(dbName)) if dbName == "" {