package main import ( "database/sql" "fmt" "io/ioutil" "log" "os" "path/filepath" "strings" _ "modernc.org/sqlite" ) func main() { if len(os.Args) < 2 { log.Fatal("Usage: go run cmd/migrate/main.go [up|down]") } command := os.Args[1] dbPath := "./messenger.db" db, err := sql.Open("sqlite", dbPath) if err != nil { log.Fatal(err) } defer db.Close() switch command { case "up": if err := migrateUp(db); err != nil { log.Fatal(err) } fmt.Println("Migrations completed successfully") case "down": if err := migrateDown(db); err != nil { log.Fatal(err) } fmt.Println("Rollback completed successfully") default: log.Fatal("Unknown command. Use 'up' or 'down'") } } func migrateUp(db *sql.DB) error { files, err := filepath.Glob("migrations/*.up.sql") if err != nil { return err } for _, file := range files { fmt.Printf("Applying migration: %s\n", file) content, err := ioutil.ReadFile(file) if err != nil { return err } // Разделяем по ";" statements := strings.Split(string(content), ";") for _, stmt := range statements { stmt = strings.TrimSpace(stmt) if stmt == "" { continue } if _, err := db.Exec(stmt); err != nil { return fmt.Errorf("failed to execute %s: %v\nStatement: %s", file, err, stmt) } } } return nil } func migrateDown(db *sql.DB) error { files, err := filepath.Glob("migrations/*.down.sql") if err != nil { return err } for _, file := range files { fmt.Printf("Rolling back: %s\n", file) content, err := ioutil.ReadFile(file) if err != nil { return err } statements := strings.Split(string(content), ";") for _, stmt := range statements { stmt = strings.TrimSpace(stmt) if stmt == "" { continue } if _, err := db.Exec(stmt); err != nil { return fmt.Errorf("failed to execute %s: %v", file, err) } } } return nil }