package main import ( "flag" "fmt" "os" "git.toowon.com/jimmy/go-common/migration" ) // 数据库迁移工具(黑盒模式) // // 工作原理: // 此工具调用 migration.RunMigrationsFromConfigWithCommand() 方法, // 内部自动处理配置加载、数据库连接、迁移执行等所有细节。 // 你只需要提供配置文件和SQL迁移文件即可。 // // 使用方式: // 基本用法: // ./migrate up # 使用默认配置 // ./migrate up -config /path/to/config.json # 指定配置文件 // ./migrate up -config config.json -dir db/migrations # 指定配置和迁移目录 // ./migrate status # 查看迁移状态 // ./migrate down # 回滚最后一个迁移 // // Docker 中使用: // # 方式1:挂载配置文件 // docker run -v /host/config.json:/app/config.json myapp ./migrate up // // # 方式2:使用环境变量 // docker run -e DATABASE_URL="mysql://..." myapp ./migrate up // // # 方式3:指定容器内的配置文件路径 // docker run myapp ./migrate up -config /etc/app/config.json // // 支持的命令: // up - 执行所有待执行的迁移 // down - 回滚最后一个迁移 // status - 查看迁移状态 // // 配置优先级(从高到低): // 1. 命令行参数 -config 和 -dir // 2. 环境变量 CONFIG_FILE 和 MIGRATIONS_DIR // 3. 环境变量 DATABASE_URL(直接连接,无需配置文件) // 4. 默认值(config.json 和 migrations) var ( configFile string migrationsDir string showHelp bool ) func init() { flag.StringVar(&configFile, "config", "", "配置文件路径(默认:config.json 或环境变量 CONFIG_FILE)") flag.StringVar(&configFile, "c", "", "配置文件路径(简写)") flag.StringVar(&migrationsDir, "dir", "", "迁移文件目录(默认:migrations 或环境变量 MIGRATIONS_DIR)") flag.StringVar(&migrationsDir, "d", "", "迁移文件目录(简写)") flag.BoolVar(&showHelp, "help", false, "显示帮助信息") flag.BoolVar(&showHelp, "h", false, "显示帮助信息(简写)") } func main() { flag.Parse() // 显示帮助 if showHelp { printHelp() os.Exit(0) } // 获取命令(默认up) command := "up" args := flag.Args() if len(args) > 0 { command = args[0] } // 验证命令 if command != "up" && command != "down" && command != "status" { fmt.Fprintf(os.Stderr, "错误:未知命令 '%s'\n\n", command) printHelp() os.Exit(1) } // 获取配置文件路径(优先级:命令行 > 环境变量 > 默认值) if configFile == "" { configFile = getEnv("CONFIG_FILE", "config.json") } // 获取迁移目录(优先级:命令行 > 环境变量 > 默认值) if migrationsDir == "" { migrationsDir = getEnv("MIGRATIONS_DIR", "migrations") } // 执行迁移 if err := migration.RunMigrationsFromConfigWithCommand(configFile, migrationsDir, command); err != nil { fmt.Fprintf(os.Stderr, "错误: %v\n", err) os.Exit(1) } } func getEnv(key, defaultValue string) string { if value := os.Getenv(key); value != "" { return value } return defaultValue } func printHelp() { fmt.Println("数据库迁移工具") fmt.Println() fmt.Println("用法:") fmt.Println(" migrate [命令] [选项]") fmt.Println() fmt.Println("命令:") fmt.Println(" up 执行所有待执行的迁移(默认)") fmt.Println(" down 回滚最后一个迁移") fmt.Println(" status 查看迁移状态") fmt.Println() fmt.Println("选项:") fmt.Println(" -config, -c 配置文件路径(默认: config.json)") fmt.Println(" -dir, -d 迁移文件目录(默认: migrations)") fmt.Println(" -help, -h 显示帮助信息") fmt.Println() fmt.Println("示例:") fmt.Println(" # 使用默认配置") fmt.Println(" migrate up") fmt.Println() fmt.Println(" # 指定配置文件") fmt.Println(" migrate up -config /etc/app/config.json") fmt.Println() fmt.Println(" # 指定配置和迁移目录") fmt.Println(" migrate up -c config.json -d db/migrations") fmt.Println() fmt.Println(" # 使用环境变量") fmt.Println(" DATABASE_URL='mysql://...' migrate up") fmt.Println() fmt.Println(" # Docker 中使用") fmt.Println(" docker run -v /host/config.json:/app/config.json myapp migrate up") fmt.Println() fmt.Println("配置优先级(从高到低):") fmt.Println(" 1. 命令行参数 -config 和 -dir") fmt.Println(" 2. 环境变量 CONFIG_FILE 和 MIGRATIONS_DIR") fmt.Println(" 3. 环境变量 DATABASE_URL") fmt.Println(" 4. 默认值(config.json 和 migrations)") }