package subconfigs import ( "fmt" "log" ) type DatabasesConfig struct { BaseConfig Databases map[string]*DatabaseConfig `yaml:"databases"` } // DatabaseConfig 数据库配置 type DatabaseConfig struct { BaseConfig Type string `yaml:"type"` Host string `yaml:"host"` Port int `yaml:"port"` Username string `yaml:"username"` Password string `yaml:"password"` Database string `yaml:"database"` MaxOpenConns int `yaml:"max_open_conns"` MaxIdleConns int `yaml:"max_idle_conns"` ConnMaxLifetime int `yaml:"conn_max_lifetime"` } // ========== DatabasesConfig 实现 ConfigLoader 接口 ========== // SetDefaults 设置默认值 - 实现 ConfigLoader 接口 func (c *DatabasesConfig) SetDefaults() { //因为是多集合,外层调这里赋默认值,这个时候对象还没有建立。赋默认值的地方移到其他地方去 // if c.Databases == nil { // c.Databases = make(map[string]*DatabaseConfig) // log.Println("⚠️ 数据库配置为空,已初始化空的数据库配置") // return // } // // 为每个数据库配置设置默认值 // for _, db := range c.Databases { // if db != nil { // db.SetDefaults() // } // } } func (c *DatabasesConfig) Load(data map[string]interface{}) error { // 初始化 c.Databases = make(map[string]*DatabaseConfig) // 遍历所有数据库配置 for dbName, dbData := range data { dbDataMap, ok := dbData.(map[interface{}]interface{}) if !ok { return fmt.Errorf("database '%s' config is not a map", dbName) } // 转换为 map[string]interface{} stringMap := make(map[string]interface{}) for k, v := range dbDataMap { if key, ok := k.(string); ok { stringMap[key] = v } } dbConfig := &DatabaseConfig{} dbConfig.SetDefaults() // 先设置默认值 // 加载单个数据库配置 if err := dbConfig.Load(stringMap); err != nil { return fmt.Errorf("failed to load database '%s' config: %v", dbName, err) } c.Databases[dbName] = dbConfig } // 设置默认值和验证 c.SetDefaults() return c.Validate() } // ========== DatabaseConfig 实现 ConfigLoader 接口 ========== // SetDefaults 设置默认值 - 实现 ConfigLoader 接口 func (c *DatabaseConfig) SetDefaults() { if c.Type == "" { c.Type = "mysql" } if c.Port == 0 { c.Port = 3306 } if c.MaxOpenConns == 0 { c.MaxOpenConns = 100 } if c.MaxIdleConns == 0 { c.MaxIdleConns = 20 } if c.ConnMaxLifetime == 0 { c.ConnMaxLifetime = 3600 } } // Load 从yaml数据加载 - 实现 ConfigLoader 接口 func (c *DatabaseConfig) Load(data map[string]interface{}) error { // 虽然可能不会被直接调用,但为了接口完整性还是要实现 return c.LoadFromYAML(data, c) } // ========== 业务方法 ========== // Validate 验证配置(数据库配置) func (c *DatabaseConfig) Validate() error { if c.Type == "" { return fmt.Errorf("database type is required") } if c.Host == "" { return fmt.Errorf("database host is required") } if c.Port <= 0 || c.Port > 65535 { return fmt.Errorf("invalid database port: %d", c.Port) } if c.Database == "" { return fmt.Errorf("database name is required") } return nil } // Validate 验证配置(多数据库配置) func (c *DatabasesConfig) Validate() error { if c.Databases == nil { log.Println("❌ 错误: 未找到任何数据库配置,请检查配置文件中的 'databases' 配置") return fmt.Errorf("no databases configurations found") } // 必须要有默认数据库 if _, exists := c.Databases["default"]; !exists { availableDBs := c.GetAllDatabaseNames() log.Printf("❌ 错误: 默认数据库未找到。可用的数据库: %v。请在配置文件中添加 'default' 数据库", availableDBs) return fmt.Errorf("default database not found") } // 验证每个数据库配置 for name, db := range c.Databases { if db == nil { log.Printf("❌ 错误: 数据库 '%s' 配置为空", name) return fmt.Errorf("database '%s' configuration is nil", name) } if err := db.Validate(); err != nil { log.Printf("❌ 错误: 数据库 '%s' 验证失败: %v", name, err) return fmt.Errorf("database '%s' validation failed: %v", name, err) } } log.Printf("✅ 数据库配置验证通过,找到 %d 个数据库配置", len(c.Databases)) return nil } // IsConfigured 判断是否已配置(数据库配置) func (c *DatabaseConfig) IsConfigured() bool { if c.Host == "" { log.Println("⚠️ 警告: 数据库 Host 未配置") return false } if c.Port <= 0 { log.Println("⚠️ 警告: 数据库 Port 未配置或无效") return false } if c.Username == "" { log.Println("⚠️ 警告: 数据库 Username 未配置") return false } if c.Database == "" { log.Println("⚠️ 警告: 数据库名称未配置") return false } return true } // IsConfigured 判断是否已配置(多数据库配置) func (c *DatabasesConfig) IsConfigured() bool { defaultDB := c.GetDefaultDatabase() if defaultDB == nil { log.Println("❌ 错误: 默认数据库不存在") return false } if !defaultDB.IsConfigured() { log.Println("❌ 错误: 默认数据库配置不完整") return false } return true } // GetDefaultDatabase 获取默认数据库(必须存在) func (c *DatabasesConfig) GetDefaultDatabase() *DatabaseConfig { if c.Databases == nil { log.Println("❌ 错误: 尝试获取默认数据库时,数据库配置为空") return nil } if db, exists := c.Databases["default"]; exists { return db } // 如果没有名为default的,尝试返回第一个(但会记录警告) for name, db := range c.Databases { log.Printf("⚠️ 警告: 未找到名为 'default' 的数据库,使用第一个数据库 '%s' 作为默认", name) return db } log.Println("❌ 错误: 数据库中没有任何配置") return nil } // GetDatabase 按名称获取数据库(为空时记录错误) func (c *DatabasesConfig) GetDatabase(name string) *DatabaseConfig { if c.Databases == nil { log.Printf("❌ 错误: 尝试获取数据库 '%s' 时,数据库配置为空", name) return nil } db := c.Databases[name] if db == nil { availableDBs := c.GetAllDatabaseNames() log.Printf("❌ 错误: 数据库 '%s' 不存在。可用的数据库: %v", name, availableDBs) } return db } // GetAllDatabaseNames 获取所有数据库名称 func (c *DatabasesConfig) GetAllDatabaseNames() []string { if c.Databases == nil { log.Println("⚠️ 警告: 尝试获取数据库名称时,数据库配置为空") return []string{} } names := make([]string, 0, len(c.Databases)) for name := range c.Databases { names = append(names, name) } return names } // GetDatabaseNamesWithoutDefault 获取除default外的所有数据库名称 func (c *DatabasesConfig) GetDatabaseNamesWithoutDefault() []string { if c.Databases == nil { return []string{} } names := make([]string, 0, len(c.Databases)-1) for name := range c.Databases { if name != "default" { names = append(names, name) } } return names } // 自动注册 func init() { Register("databases", &DatabasesConfig{}) }