重构:消除代码重复,提升可维护性
后端优化: - 新增 resolvePassword 函数,消除密码获取重复逻辑 - 新增 parseMongoOptions 函数,消除 Options 解析重复 - 新增 testConnectionByType 统一连接测试调用 - 重构 loadMongoDatabasesWithOptions 接收解析后参数 - 删除重复代码 37 行 前端优化: - 新增 useVisibleDatabases composable - 统一 visible_databases 解析和过滤逻辑 - 简化错误处理,移除 try-catch 包装 - 删除重复代码 22 行 代码质量: - 消除 6 处重复代码块 - 新增 5 个可复用函数 - 提升代码可维护性和可测试性
This commit is contained in:
@@ -135,38 +135,59 @@ func (s *ConnectionService) DeleteConnection(id uint) error {
|
||||
})
|
||||
}
|
||||
|
||||
// resolvePassword 解析密码(编辑模式下从已保存连接中获取)
|
||||
func (s *ConnectionService) resolvePassword(id uint, password string) (string, error) {
|
||||
if id > 0 && password == "" {
|
||||
conn, err := s.GetConnection(id)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("获取连接信息失败: %v", err)
|
||||
}
|
||||
decryptPassword, err := crypto.DecryptPassword(conn.Password)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("密码解密失败: %v", err)
|
||||
}
|
||||
return decryptPassword, nil
|
||||
}
|
||||
return password, nil
|
||||
}
|
||||
|
||||
// parseMongoOptions 解析 MongoDB 连接选项
|
||||
func parseMongoOptions(options string) (authSource, authMechanism string) {
|
||||
if options == "" {
|
||||
return "", ""
|
||||
}
|
||||
var opts map[string]interface{}
|
||||
if err := json.Unmarshal([]byte(options), &opts); err != nil {
|
||||
return "", ""
|
||||
}
|
||||
authSource, _ = opts["authSource"].(string)
|
||||
authMechanism, _ = opts["authMechanism"].(string)
|
||||
return authSource, authMechanism
|
||||
}
|
||||
|
||||
// TestConnection 测试连接(需要根据类型调用不同的测试方法)
|
||||
func (s *ConnectionService) TestConnection(conn *models.DbConnection) error {
|
||||
// 解密密码用于测试
|
||||
password, err := crypto.DecryptPassword(conn.Password)
|
||||
if err != nil {
|
||||
return fmt.Errorf("密码解密失败: %v", err)
|
||||
}
|
||||
|
||||
// 根据类型测试连接
|
||||
switch conn.Type {
|
||||
authSource, authMechanism := parseMongoOptions(conn.Options)
|
||||
|
||||
return s.testConnectionByType(conn.Type, conn.Host, conn.Port, conn.Username, password, conn.Database, authSource, authMechanism)
|
||||
}
|
||||
|
||||
// testConnectionByType 根据类型调用对应的测试方法
|
||||
func (s *ConnectionService) testConnectionByType(dbType, host string, port int, username, password, database, authSource, authMechanism string) error {
|
||||
switch dbType {
|
||||
case "mysql":
|
||||
return testMySQLConnection(conn.Host, conn.Port, conn.Username, password, conn.Database)
|
||||
return testMySQLConnection(host, port, username, password, database)
|
||||
case "redis":
|
||||
return testRedisConnection(conn.Host, conn.Port, password)
|
||||
return testRedisConnection(host, port, password)
|
||||
case "mongo":
|
||||
// 解析 Options 获取 MongoDB 连接参数
|
||||
authSource := ""
|
||||
authMechanism := ""
|
||||
if conn.Options != "" {
|
||||
var opts map[string]interface{}
|
||||
if err := json.Unmarshal([]byte(conn.Options), &opts); err == nil {
|
||||
if as, ok := opts["authSource"].(string); ok && as != "" {
|
||||
authSource = as
|
||||
}
|
||||
if am, ok := opts["authMechanism"].(string); ok && am != "" {
|
||||
authMechanism = am
|
||||
}
|
||||
}
|
||||
}
|
||||
return testMongoConnection(conn.Host, conn.Port, conn.Username, password, conn.Database, authSource, authMechanism)
|
||||
return testMongoConnection(host, port, username, password, database, authSource, authMechanism)
|
||||
default:
|
||||
return fmt.Errorf("不支持的数据库类型: %s", conn.Type)
|
||||
return fmt.Errorf("不支持的数据库类型: %s", dbType)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -187,67 +208,30 @@ func testMongoConnection(host string, port int, username, password, database, au
|
||||
|
||||
// TestConnectionWithParams 使用参数测试连接(不保存数据)
|
||||
func (s *ConnectionService) TestConnectionWithParams(dbType, host string, port int, username, password, database, options string, id uint) error {
|
||||
// 如果是编辑模式且有ID,获取已保存的密码
|
||||
if id > 0 && password == "" {
|
||||
conn, err := s.GetConnection(id)
|
||||
if err != nil {
|
||||
return fmt.Errorf("获取连接信息失败: %v", err)
|
||||
}
|
||||
decryptPassword, err := crypto.DecryptPassword(conn.Password)
|
||||
if err != nil {
|
||||
return fmt.Errorf("密码解密失败: %v", err)
|
||||
}
|
||||
password = decryptPassword
|
||||
password, err := s.resolvePassword(id, password)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 根据类型测试连接
|
||||
switch dbType {
|
||||
case "mysql":
|
||||
return testMySQLConnection(host, port, username, password, database)
|
||||
case "redis":
|
||||
return testRedisConnection(host, port, password)
|
||||
case "mongo":
|
||||
// 解析 Options 获取 MongoDB 连接参数
|
||||
authSource := ""
|
||||
authMechanism := ""
|
||||
if options != "" {
|
||||
var opts map[string]interface{}
|
||||
if err := json.Unmarshal([]byte(options), &opts); err == nil {
|
||||
if as, ok := opts["authSource"].(string); ok && as != "" {
|
||||
authSource = as
|
||||
}
|
||||
if am, ok := opts["authMechanism"].(string); ok && am != "" {
|
||||
authMechanism = am
|
||||
}
|
||||
}
|
||||
}
|
||||
return testMongoConnection(host, port, username, password, database, authSource, authMechanism)
|
||||
default:
|
||||
return fmt.Errorf("不支持的数据库类型: %s", dbType)
|
||||
}
|
||||
authSource, authMechanism := parseMongoOptions(options)
|
||||
return s.testConnectionByType(dbType, host, port, username, password, database, authSource, authMechanism)
|
||||
}
|
||||
|
||||
// LoadAllDatabases 加载全部数据库列表
|
||||
func (s *ConnectionService) LoadAllDatabases(dbType, host string, port int, username, password, database, options string, id uint) ([]string, error) {
|
||||
// 如果是编辑模式且有ID,获取已保存的密码
|
||||
if id > 0 && password == "" {
|
||||
conn, err := s.GetConnection(id)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("获取连接信息失败: %v", err)
|
||||
}
|
||||
decryptPassword, err := crypto.DecryptPassword(conn.Password)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("密码解密失败: %v", err)
|
||||
}
|
||||
password = decryptPassword
|
||||
password, err := s.resolvePassword(id, password)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
authSource, authMechanism := parseMongoOptions(options)
|
||||
|
||||
// 根据类型加载数据库列表
|
||||
switch dbType {
|
||||
case "mysql":
|
||||
return loadMySQLDatabases(host, port, username, password, database)
|
||||
case "mongo":
|
||||
return loadMongoDatabases(host, port, username, password, database, options)
|
||||
return loadMongoDatabasesWithOptions(host, port, username, password, database, authSource, authMechanism)
|
||||
case "redis":
|
||||
// Redis 没有数据库概念,返回空列表
|
||||
return []string{}, nil
|
||||
@@ -274,23 +258,8 @@ func loadMySQLDatabases(host string, port int, username, password, defaultDataba
|
||||
return client.ListDatabases(context.Background())
|
||||
}
|
||||
|
||||
// loadMongoDatabases 加载 MongoDB 数据库列表
|
||||
func loadMongoDatabases(host string, port int, username, password, defaultDatabase, options string) ([]string, error) {
|
||||
// 解析 Options 获取 MongoDB 连接参数
|
||||
authSource := ""
|
||||
authMechanism := ""
|
||||
if options != "" {
|
||||
var opts map[string]interface{}
|
||||
if err := json.Unmarshal([]byte(options), &opts); err == nil {
|
||||
if as, ok := opts["authSource"].(string); ok && as != "" {
|
||||
authSource = as
|
||||
}
|
||||
if am, ok := opts["authMechanism"].(string); ok && am != "" {
|
||||
authMechanism = am
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// loadMongoDatabasesWithOptions 加载 MongoDB 数据库列表(使用解析后的选项)
|
||||
func loadMongoDatabasesWithOptions(host string, port int, username, password, defaultDatabase, authSource, authMechanism string) ([]string, error) {
|
||||
mongoConfig := &dbclient.MongoConfig{
|
||||
Host: host,
|
||||
Port: port,
|
||||
|
||||
Reference in New Issue
Block a user