Files

150 lines
4.9 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.

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 CONFIG_FILE=/etc/app/config.json 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. 默认值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
// 支持两种方式:
// 1. 位置参数:./migrate up
// 2. 标志参数:./migrate -cmd=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)
}
// 获取配置文件路径(优先级:命令行 > 环境变量 > 默认值)
// 如果未指定RunMigrationsFromConfigWithCommand 会自动查找
if configFile == "" {
configFile = getEnv("CONFIG_FILE", "")
}
// 获取迁移目录(优先级:命令行 > 环境变量 > 默认值)
// 如果未指定RunMigrationsFromConfigWithCommand 会使用默认值 "migrations"
if migrationsDir == "" {
migrationsDir = getEnv("MIGRATIONS_DIR", "")
}
// 执行迁移(黑盒模式:内部自动处理所有细节)
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(" CONFIG_FILE=/etc/app/config.json 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. 默认值config.json 和 migrations")
}