Files
2026-08-14 21:50:48 +08:00

86 lines
2.6 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// applysql —— 开发辅助工具:把 SQL 文件应用到 z_xk 库
//
// 为什么需要它Windows 开发机没有 mysql 客户端,而 Go 项目本身带着
// GORM 依赖与 config.Load() 的 DSN 解析逻辑,直接复用即可执行 DDL
// 且凭据不经过命令行/控制台(从 manifest/config/config.yaml 读取)。
//
// 用法(必须在 nl-tcm-agent 项目根目录执行,保证能读到配置文件):
// go run ./tools/applysql <sql文件1> [sql文件2 ...]
//
// 说明:
// - 按 ";\n" 粗粒度拆分语句(我们自己的 SQL 文件都是规范的分号+换行结尾)
// - "--" 开头的注释行会被剥掉
// - 任一语句失败立即退出DDL 顺序有依赖,跳过会导致后续更混乱)
package main
import (
"fmt"
"log"
"os"
"strings"
"tcm-agent/internal/config"
"tcm-agent/internal/dao"
)
func main() {
if len(os.Args) < 2 {
log.Fatal("用法: go run ./tools/applysql <sql文件...>")
}
cfg := config.Load()
if cfg.DB.DSN == "" {
log.Fatal("配置缺少 db.dsn检查 manifest/config/config.yaml")
}
if err := dao.Init(cfg.DB.DSN); err != nil {
log.Fatalf("连接数据库失败: %v", err)
}
for _, path := range os.Args[1:] {
raw, err := os.ReadFile(path)
if err != nil {
log.Fatalf("读取 %s 失败: %v", path, err)
}
stmts := splitStatements(string(raw))
fmt.Printf("== %s%d 条语句 ==\n", path, len(stmts))
for i, stmt := range stmts {
if err := dao.DB.Exec(stmt).Error; err != nil {
log.Fatalf("第 %d 条语句执行失败: %v\n语句片段: %.120s", i+1, err, stmt)
}
fmt.Printf(" [%d/%d] OK %.60s...\n", i+1, len(stmts), firstLine(stmt))
}
}
fmt.Println("全部执行完成")
}
// splitStatements 把 SQL 文本拆成可执行语句:剥注释行后按分号结尾切分
func splitStatements(sqlText string) []string {
// Windows 编辑器写出的文件是 CRLF先统一成 LF否则 ";\n" 切分匹配不到
sqlText = strings.ReplaceAll(sqlText, "\r\n", "\n")
var sb strings.Builder
for _, line := range strings.Split(sqlText, "\n") {
trimmed := strings.TrimSpace(line)
// 剥掉整行注释(字段内注释在行中不受影响)
if strings.HasPrefix(trimmed, "--") || trimmed == "" {
continue
}
sb.WriteString(line)
sb.WriteString("\n")
}
parts := strings.Split(sb.String(), ";\n")
out := make([]string, 0, len(parts))
for _, p := range parts {
p = strings.TrimSpace(p)
if p != "" {
out = append(out, p)
}
}
return out
}
// firstLine 取语句首行用于进度展示
func firstLine(stmt string) string {
if i := strings.Index(stmt, "\n"); i > 0 {
return stmt[:i]
}
return stmt
}