(ctx context.Context, pool *pgxpool.Pool)
| 75 | } |
| 76 | |
| 77 | func runMigrations(ctx context.Context, pool *pgxpool.Pool) error { |
| 78 | migrationsDir := filepath.Join(projectRoot(), "migrations") |
| 79 | entries, err := os.ReadDir(migrationsDir) |
| 80 | if err != nil { |
| 81 | return err |
| 82 | } |
| 83 | for _, entry := range entries { |
| 84 | if entry.IsDir() || filepath.Ext(entry.Name()) != ".sql" { |
| 85 | continue |
| 86 | } |
| 87 | migration, err := os.ReadFile(filepath.Join(migrationsDir, entry.Name())) |
| 88 | if err != nil { |
| 89 | return err |
| 90 | } |
| 91 | if _, err := pool.Exec(ctx, string(migration)); err != nil { |
| 92 | // Existing tables / repeated extensions are expected when a |
| 93 | // previous run already applied the schema; ignoring those is |
| 94 | // the established convention here. But we log to stderr so a |
| 95 | // genuine SQL error in a new migration surfaces during |
| 96 | // `go test` instead of being absorbed silently — that would |
| 97 | // otherwise let a broken migration ship and only fail later |
| 98 | // in the real RunMigrations path. |
| 99 | fmt.Fprintf(os.Stderr, "[testutil] migration %s: %v\n", entry.Name(), err) |
| 100 | } |
| 101 | } |
| 102 | return nil |
| 103 | } |
| 104 | |
| 105 | func truncateAll(ctx context.Context, pool *pgxpool.Pool) error { |
| 106 | _, err := pool.Exec(ctx, ` |
no test coverage detected