package main import ( "butterfliu/migrations" "database/sql" "fmt" "log" "os" _ "github.com/mattn/go-sqlite3" ) func main() { if len(os.Args) < 2 { printUsage() os.Exit(1) } command := os.Args[1] // Database file path dbPath := "./butterfliu.db" if len(os.Args) > 3 && os.Args[1] == "db" { dbPath = os.Args[3] } log.Printf("Using database: %s", dbPath) // Open database connection db, err := sql.Open("sqlite3", dbPath) if err != nil { log.Fatalf("Error opening database %s: %v", dbPath, err) } defer db.Close() // Test connection if err = db.Ping(); err != nil { log.Fatalf("Error connecting to database %s: %v", dbPath, err) } // Initialize migration table if err = migrations.InitMigrationTable(db); err != nil { log.Fatalf("Error initializing migration table: %v", err) } switch command { case "up": // Run all pending migrations if err := migrations.MigrateUp(db); err != nil { log.Fatalf("Error applying migrations: %v", err) } log.Println("All migrations applied successfully") case "down": if len(os.Args) < 3 { log.Println("Error: Missing target version") printUsage() os.Exit(1) } targetVersion, err := parseVersion(os.Args[2]) if err != nil { log.Fatalf("Error parsing target version: %v", err) } // Roll back migrations to target version if err := migrations.MigrateDown(db, targetVersion); err != nil { log.Fatalf("Error rolling back migrations: %v", err) } log.Printf("Migrations rolled back to version %d successfully\n", targetVersion) case "reset": // Roll back all migrations if err := migrations.MigrateDown(db, 0); err != nil { log.Fatalf("Error rolling back migrations: %v", err) } log.Println("All migrations rolled back successfully") case "refresh": // Roll back all migrations and then apply them again if err := migrations.MigrateDown(db, 0); err != nil { log.Fatalf("Error rolling back migrations: %v", err) } if err := migrations.MigrateUp(db); err != nil { log.Fatalf("Error applying migrations: %v", err) } log.Println("All migrations refreshed successfully") case "status": // Show migration status migrationList, err := migrations.ListMigrations(db) if err != nil { log.Fatalf("Error listing migrations: %v", err) } log.Println("Migration Status:") log.Println("=================") for _, migration := range migrationList { status := "Pending" appliedAt := "" if applied, ok := migration["applied"].(bool); ok && applied { status = "Applied" appliedAt = migration["applied_at"].(string) } log.Printf("%d: %s - %s %s\n", migration["version"], migration["description"], status, appliedAt) } case "create": if len(os.Args) < 3 { log.Println("Error: Missing migration name") printUsage() os.Exit(1) } name := os.Args[2] if err := migrations.CreateMigration(name); err != nil { log.Fatalf("Error creating migration: %v", err) } default: log.Printf("Error: Unknown command '%s'\n", command) printUsage() os.Exit(1) } } func printUsage() { log.Println("Usage: go run cmd/migrate/main.go [args]") log.Println("") log.Println("Commands:") log.Println(" up Apply all pending migrations") log.Println(" down Roll back migrations to specified version") log.Println(" reset Roll back all migrations") log.Println(" refresh Roll back all migrations and apply them again") log.Println(" status Show migration status") log.Println(" create Create a new migration") } func parseVersion(s string) (int, error) { var v int _, err := fmt.Sscanf(s, "%d", &v) return v, err }