package main import ( "fmt" "os" "strconv" "github.com/gochat/gochat/internal/config" "github.com/gochat/gochat/internal/database" ) func main() { if len(os.Args) < 2 { printUsage() os.Exit(1) } command := os.Args[1] // Load config to get database connection info cfg, err := config.Load() if err != nil { fmt.Fprintf(os.Stderr, "Error loading config: %v\n", err) os.Exit(1) } dbURL := cfg.Database.MigrateDSN() migrationsPath := cfg.Database.GetMigrationsPath() switch command { case "up": if err := database.RunMigrations(dbURL, migrationsPath); err != nil { fmt.Fprintf(os.Stderr, "Error running migrations up: %v\n", err) os.Exit(1) } fmt.Println("Migrations applied successfully (up)") case "down": if err := database.RollbackMigrations(dbURL, migrationsPath); err != nil { fmt.Fprintf(os.Stderr, "Error running migrations down: %v\n", err) os.Exit(1) } fmt.Println("Migrations rolled back successfully (down)") case "force": if len(os.Args) < 3 { fmt.Fprintf(os.Stderr, "Error: 'force' requires a version argument\n") printUsage() os.Exit(1) } version, err := strconv.Atoi(os.Args[2]) if err != nil { fmt.Fprintf(os.Stderr, "Error: invalid version number '%s': %v\n", os.Args[2], err) os.Exit(1) } if err := database.ForceVersion(dbURL, migrationsPath, version); err != nil { fmt.Fprintf(os.Stderr, "Error forcing version %d: %v\n", version, err) os.Exit(1) } fmt.Printf("Migration version forced to %d\n", version) case "version": version, dirty, err := database.CurrentVersion(dbURL, migrationsPath) if err != nil { fmt.Fprintf(os.Stderr, "Error getting current version: %v\n", err) os.Exit(1) } if dirty { fmt.Printf("Current version: %d (DIRTY — a migration partially failed)\n", version) } else { fmt.Printf("Current version: %d\n", version) } case "steps": if len(os.Args) < 3 { fmt.Fprintf(os.Stderr, "Error: 'steps' requires a step count argument\n") printUsage() os.Exit(1) } steps, err := strconv.Atoi(os.Args[2]) if err != nil { fmt.Fprintf(os.Stderr, "Error: invalid step count '%s': %v\n", os.Args[2], err) os.Exit(1) } if err := database.MigrateSteps(dbURL, migrationsPath, steps); err != nil { fmt.Fprintf(os.Stderr, "Error running %d migration steps: %v\n", steps, err) os.Exit(1) } fmt.Printf("Applied %d migration steps successfully\n", steps) default: fmt.Fprintf(os.Stderr, "Unknown command: %s\n", command) printUsage() os.Exit(1) } } func printUsage() { fmt.Println("Usage: migrate [args]") fmt.Println("") fmt.Println("Commands:") fmt.Println(" up Apply all pending migrations") fmt.Println(" down Rollback all migrations") fmt.Println(" force Force version to v (fix dirty state)") fmt.Println(" version Show current migration version") fmt.Println(" steps Apply n steps (positive=up, negative=down)") fmt.Println("") fmt.Println("Environment: Uses database config from Viper (config.yaml)") }