mirror of
https://github.com/Syngnat/GoNavi.git
synced 2026-07-08 03:21:32 +08:00
fix(dameng-databases): 修复显示全部库时数据库列表不完整 refs #154
This commit is contained in:
@@ -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, "<nil>") {
|
||||
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, "<nil>") {
|
||||
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 == "" {
|
||||
|
||||
Reference in New Issue
Block a user