package controllers import ( "fmt" "os" "xg_fetl/internal/db_executor" "xg_fetl/internal/global" "xg_fetl/internal/models" "xg_fetl/internal/services" "xg_fetl/internal/utils" ) func ExportController(tableName []string) { dbType := global.Cfg.ExportConfig.DBConfig.DBType dsn := global.Cfg.ExportConfig.DBConfig.GetDSN() dbName := global.Cfg.ExportConfig.DBConfig.DBName dbIp := global.Cfg.ExportConfig.DBConfig.IP // baseFilePath := global.Cfg.ExportConfig.BaseFilePath delimiter := global.Cfg.ExportConfig.Delimiter maxFileSize := global.Cfg.ExportConfig.MaxFileSize pageSize := global.Cfg.ExportConfig.PageSize // !创建数据库链接 executor, err := db_executor.NewDBExecutor(dbType, dsn) if err != nil { fmt.Println(fmt.Errorf("create db executor failed, err: %v", err)) panic(err) } defer executor.Close() // ! 获取数据库元信息 dbInfo, err := services.GetDBInfoService(dbName, executor) if err != nil { fmt.Println(fmt.Errorf("get db info failed, err: %v", err)) panic(err) } // !创建存放路径 var outputDir string if global.Cfg.ExportConfig.BaseFilePath == "" { outputDir = global.Cfg.ExportConfig.BaseFilePath + "/" + dbName + "_" + dbIp } else { outputDir = "./GTool" + "/" + dbName + "_" + dbIp } if err := utils.CreateDirectory(outputDir); err != nil { fmt.Println(fmt.Errorf("创建文件夹失败,可能已存在同名文件夹 %s, err: %v", outputDir, err)) return } PrintDatabaseInfo(dbInfo) //存放文件夹名字为库名 dbInfoFile := outputDir + "/" + "db_info.txt" WriteDatabaseInfoToFile(dbInfo, dbInfoFile) // !导出 // 创建一个新的 map,将普通表和 LOB 表的信息都放进去 allTables := make(map[string]models.TableInfo, len(dbInfo.Tables)+len(dbInfo.LobTables)) // 将 tableInfoMap 中的表信息添加到 allTables 中 for tableName, tableInfo := range dbInfo.Tables { allTables[tableName] = tableInfo } // 将 lobTableInfoMap 中的表信息添加到 allTables 中 for tableName, tableInfo := range dbInfo.LobTables { allTables[tableName] = tableInfo } if len(tableName) != 0 { // 创建一个新的map来存储根据tableName筛选后的表信息 selectedTables := make(map[string]models.TableInfo) for _, name := range tableName { if tableInfo, ok := allTables[name]; ok { selectedTables[name] = tableInfo } } services.WriteMain(executor, selectedTables, outputDir, delimiter, maxFileSize, pageSize) } else { services.WriteMain(executor, allTables, outputDir, delimiter, maxFileSize, pageSize) } } // 打印 DatabaseInfo 的函数 func PrintDatabaseInfo(dbInfo *models.DatabaseInfo) { if dbInfo == nil { fmt.Println("数据库信息为空") return } fmt.Printf("数据库总大小: %.2f MB\n", dbInfo.SizeMB) fmt.Printf("表的数量: %d\n\n", dbInfo.TableCount) fmt.Println("普通表信息:") for _, table := range dbInfo.Tables { fmt.Printf("表名: %s\n", table.Name) fmt.Printf("大小: %.2f MB\n", table.Size) fmt.Printf("行数: %d\n", table.Count) fmt.Printf("DDL:\n%s\n\n", table.DDL) } fmt.Println("LOB 表信息:") for _, table := range dbInfo.LobTables { fmt.Printf("表名: %s\n", table.Name) fmt.Printf("大小: %.2f MB\n", table.Size) fmt.Printf("行数: %d\n", table.Count) fmt.Printf("DDL:\n%s\n\n", table.DDL) } fmt.Println("存储过程和函数:") for _, function := range dbInfo.Functions { fmt.Printf("名称: %s\n", function.Name) fmt.Printf("类型: %s\n", function.Type) fmt.Printf("定义:\n%s\n\n", function.Definition) } fmt.Println("触发器:") for _, trigger := range dbInfo.Triggers { fmt.Printf("名称: %s\n", trigger.Name) fmt.Printf("事件: %s\n", trigger.Event) fmt.Printf("表: %s\n", trigger.Table) fmt.Printf("时机: %s\n", trigger.Timing) fmt.Printf("语句:\n%s\n\n", trigger.Statement) } } // WriteDatabaseInfoToFile 将 DatabaseInfo 写入文件,并格式化划分信息 func WriteDatabaseInfoToFile(dbInfo *models.DatabaseInfo, filePath string) error { if dbInfo == nil { return fmt.Errorf("数据库信息为空") } // 打开或创建文件 file, err := os.Create(filePath) if err != nil { return fmt.Errorf("无法创建文件: %v", err) } defer file.Close() // 计算表的数量(普通表和 LOB 表) normalTableCount := len(dbInfo.Tables) lobTableCount := len(dbInfo.LobTables) functionCount := len(dbInfo.Functions) triggerCount := len(dbInfo.Triggers) // 写入数据库总大小、表数量以及各类表和对象的数量 fmt.Fprintf(file, "--======== 数据库信息 ========\n") fmt.Fprintf(file, "数据库总大小: %.2f MB\n", dbInfo.SizeMB) fmt.Fprintf(file, "表的总数量: %d\n", dbInfo.TableCount) fmt.Fprintf(file, "普通表的数量: %d\n", normalTableCount) fmt.Fprintf(file, "LOB 表的数量: %d\n", lobTableCount) fmt.Fprintf(file, "存储过程和函数的数量: %d\n", functionCount) fmt.Fprintf(file, "触发器的数量: %d\n\n", triggerCount) // 写入普通表信息 fmt.Fprintf(file, "--======== 普通表信息 ========\n") for _, table := range dbInfo.Tables { fmt.Fprintf(file, "-------- 表名: %s --------\n", table.Name) fmt.Fprintf(file, "大小: %.2f MB\n", table.Size) fmt.Fprintf(file, "行数: %d\n", table.Count) fmt.Fprintf(file, "DDL:\n%s\n\n", table.DDL) } // 写入 LOB 表信息 fmt.Fprintf(file, "--======== LOB 表信息 ========\n") for _, table := range dbInfo.LobTables { fmt.Fprintf(file, "-------- 表名: %s --------\n", table.Name) fmt.Fprintf(file, "大小: %.2f MB\n", table.Size) fmt.Fprintf(file, "行数: %d\n", table.Count) fmt.Fprintf(file, "DDL:\n%s\n\n", table.DDL) } // 写入存储过程和函数信息 fmt.Fprintf(file, "--======== 存储过程和函数 ========\n") for _, function := range dbInfo.Functions { fmt.Fprintf(file, "-------- 名称: %s --------\n", function.Name) fmt.Fprintf(file, "类型: %s\n", function.Type) fmt.Fprintf(file, "定义:\n%s\n\n", function.Definition) } // 写入触发器信息 fmt.Fprintf(file, "--======== 触发器 ========\n") for _, trigger := range dbInfo.Triggers { fmt.Fprintf(file, "-------- 名称: %s --------\n", trigger.Name) fmt.Fprintf(file, "事件: %s\n", trigger.Event) fmt.Fprintf(file, "表: %s\n", trigger.Table) fmt.Fprintf(file, "时机: %s\n", trigger.Timing) fmt.Fprintf(file, "语句:\n%s\n\n", trigger.Statement) } fmt.Fprintf(file, "--============================\n") return nil }