package main import ( "context" "fmt" "log/slog" "os" "path/filepath" "sort" "strings" "github.com/easyai/easyai-ai-gateway/apps/api/internal/config" "github.com/jackc/pgx/v5" ) func main() { cfg := config.Load() logger := slog.New(slog.NewTextHandler(os.Stdout, nil)) ctx := context.Background() conn, err := pgx.Connect(ctx, cfg.DatabaseURL) if err != nil { logger.Error("connect postgres failed", "error", err) os.Exit(1) } defer conn.Close(ctx) if _, err := conn.Exec(ctx, ` CREATE TABLE IF NOT EXISTS schema_migrations ( version text PRIMARY KEY, applied_at timestamptz NOT NULL DEFAULT now() );`); err != nil { logger.Error("ensure schema_migrations failed", "error", err) os.Exit(1) } files, err := filepath.Glob("migrations/*.sql") if err != nil { logger.Error("read migrations failed", "error", err) os.Exit(1) } sort.Strings(files) for _, file := range files { version := strings.TrimSuffix(filepath.Base(file), filepath.Ext(file)) var exists bool if err := conn.QueryRow(ctx, "SELECT EXISTS (SELECT 1 FROM schema_migrations WHERE version=$1)", version).Scan(&exists); err != nil { logger.Error("check migration failed", "version", version, "error", err) os.Exit(1) } if exists { logger.Info("migration skipped", "version", version) continue } sqlBytes, err := os.ReadFile(file) if err != nil { logger.Error("read migration file failed", "file", file, "error", err) os.Exit(1) } tx, err := conn.Begin(ctx) if err != nil { logger.Error("begin migration failed", "version", version, "error", err) os.Exit(1) } if _, err := tx.Exec(ctx, string(sqlBytes)); err != nil { _ = tx.Rollback(ctx) logger.Error("execute migration failed", "version", version, "error", err) os.Exit(1) } if _, err := tx.Exec(ctx, "INSERT INTO schema_migrations(version) VALUES($1)", version); err != nil { _ = tx.Rollback(ctx) logger.Error("record migration failed", "version", version, "error", err) os.Exit(1) } if err := tx.Commit(ctx); err != nil { logger.Error("commit migration failed", "version", version, "error", err) os.Exit(1) } logger.Info("migration applied", "version", version) } fmt.Println("migrations complete") }