Files

86 lines
2.6 KiB
Go
Raw Permalink Normal View History

2026-08-14 21:50:48 +08:00
// 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
}