|
@@ -8,14 +8,12 @@ import (
|
|
|
"sort"
|
|
|
"xg_dba/internal/models"
|
|
|
|
|
|
- "github.com/BurntSushi/toml"
|
|
|
+ "github.com/mitchellh/mapstructure"
|
|
|
+ "github.com/spf13/viper"
|
|
|
)
|
|
|
|
|
|
-func Cache() {
|
|
|
-
|
|
|
- // 指定需要查找的根文件夹路径
|
|
|
- folderPath := "C:\\Program_GT\\Code\\Go\\Work\\xugu\\xg_dba\\config"
|
|
|
-
|
|
|
+// InitCache 初始化缓存,从指定目录中读取 TOML 文件内容并存储到 packageModels 映射中。
|
|
|
+func InitCache(folderPath string) {
|
|
|
packageModels := make(map[string]models.Cache)
|
|
|
|
|
|
err := filepath.Walk(folderPath, func(path string, info os.FileInfo, err error) error {
|
|
@@ -29,23 +27,27 @@ func Cache() {
|
|
|
var connectInfo models.ConnectInfo
|
|
|
var systemMetaInfo models.SystemMetaInfo
|
|
|
|
|
|
+ // 如果 listen.toml 文件存在,解析它到 connectInfo 结构体中
|
|
|
if fileExists(listenFilePath) {
|
|
|
- if _, err := parseTomlFile(listenFilePath, &connectInfo); err != nil {
|
|
|
+ if err := parseTomlFile(listenFilePath, &connectInfo); err != nil {
|
|
|
return err
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ // 获取目录中最新的 os_info.toml 文件
|
|
|
latestOsInfoFilePath, err := getLatestOsInfoFile(path)
|
|
|
if err != nil {
|
|
|
return err
|
|
|
}
|
|
|
|
|
|
+ // 如果找到最新的 os_info.toml 文件,解析它到 systemMetaInfo 结构体中
|
|
|
if latestOsInfoFilePath != "" {
|
|
|
- if _, err := parseTomlFile(latestOsInfoFilePath, &systemMetaInfo); err != nil {
|
|
|
+ if err := parseTomlFile(latestOsInfoFilePath, &systemMetaInfo); err != nil {
|
|
|
return err
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ // 使用主机地址作为键,将解析的信息存储到 packageModels 映射中
|
|
|
host := connectInfo.Ssh.Host
|
|
|
if host != "" {
|
|
|
packageModels[host] = models.Cache{
|
|
@@ -58,15 +60,17 @@ func Cache() {
|
|
|
})
|
|
|
|
|
|
if err != nil {
|
|
|
- fmt.Printf("Error walking the path %q: %v\n", folderPath, err)
|
|
|
+ fmt.Printf("遍历路径 %q 时出错: %v\n", folderPath, err)
|
|
|
return
|
|
|
}
|
|
|
|
|
|
+ // 打印每个主机的缓存数据
|
|
|
for host, cache := range packageModels {
|
|
|
- fmt.Printf("Host: %s, Cache: %+v\n", host, cache)
|
|
|
+ fmt.Printf("主机: %s, 缓存: %+v\n", host, cache)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+// fileExists 检查给定路径的文件是否存在。
|
|
|
func fileExists(filename string) bool {
|
|
|
info, err := os.Stat(filename)
|
|
|
if os.IsNotExist(err) {
|
|
@@ -75,21 +79,42 @@ func fileExists(filename string) bool {
|
|
|
return !info.IsDir()
|
|
|
}
|
|
|
|
|
|
-func parseTomlFile(filePath string, v interface{}) (toml.MetaData, error) {
|
|
|
- file, err := os.Open(filePath)
|
|
|
- if err != nil {
|
|
|
- return toml.MetaData{}, err
|
|
|
+// parseTomlFile 使用 viper 解析 TOML 文件到提供的结构体中。
|
|
|
+func parseTomlFile(filePath string, v interface{}) error {
|
|
|
+ // 为了防止 viper 的全局状态干扰解析结果,使用新的 viper 实例
|
|
|
+ vp := viper.New()
|
|
|
+ vp.SetConfigFile(filePath)
|
|
|
+ vp.SetConfigType("toml")
|
|
|
+
|
|
|
+ if err := vp.ReadInConfig(); err != nil {
|
|
|
+ return err
|
|
|
}
|
|
|
- defer file.Close()
|
|
|
|
|
|
- decoder := toml.NewDecoder(file)
|
|
|
- metaData, err := decoder.Decode(v)
|
|
|
+ // 使用 `vp.AllSettings()` 将配置映射到提供的结构体
|
|
|
+ settings := vp.AllSettings()
|
|
|
+ if err := decodeSettings(settings, v); err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+
|
|
|
+ return nil
|
|
|
+}
|
|
|
+
|
|
|
+// decodeSettings 将 viper 的设置映射解码到目标结构体。
|
|
|
+func decodeSettings(settings map[string]interface{}, v interface{}) error {
|
|
|
+ decoderConfig := &mapstructure.DecoderConfig{
|
|
|
+ Result: v,
|
|
|
+ TagName: "toml",
|
|
|
+ WeaklyTypedInput: true,
|
|
|
+ }
|
|
|
+ decoder, err := mapstructure.NewDecoder(decoderConfig)
|
|
|
if err != nil {
|
|
|
- return toml.MetaData{}, err
|
|
|
+ return err
|
|
|
}
|
|
|
- return metaData, nil
|
|
|
+ return decoder.Decode(settings)
|
|
|
}
|
|
|
|
|
|
+// getLatestOsInfoFile 在给定目录中查找最新的 os_info TOML 文件。
|
|
|
+// 它查找匹配模式 "os_info_<timestamp>.toml" 的文件,并返回最新的一个。
|
|
|
func getLatestOsInfoFile(dirPath string) (string, error) {
|
|
|
pattern := regexp.MustCompile(`^os_info(?:_\d{8}_\d{6})?\.toml$`)
|
|
|
files, err := os.ReadDir(dirPath)
|
|
@@ -104,10 +129,12 @@ func getLatestOsInfoFile(dirPath string) (string, error) {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ // 如果没有找到匹配的文件,返回空字符串
|
|
|
if len(matchingFiles) == 0 {
|
|
|
return "", nil
|
|
|
}
|
|
|
|
|
|
+ // 将匹配的文件按降序排序,以获取最新的文件
|
|
|
sort.Slice(matchingFiles, func(i, j int) bool {
|
|
|
return matchingFiles[i] > matchingFiles[j]
|
|
|
})
|