proxy-pool/internal/adapters/postgresadmin/migrate.go

48 lines
1.1 KiB
Go

package postgresadmin
import (
"context"
"errors"
"fmt"
"time"
"github.com/jackc/pgx/v5/pgxpool"
"proxy-pool/internal/domain/adminstate"
)
// ApplyMigrations runs every embedded idempotent migration on one physical connection.
func ApplyMigrations(ctx context.Context, pool *pgxpool.Pool) error {
if err := contextError(ctx); err != nil {
return err
}
if isNil(pool) {
return adminstate.ErrInvalidCommand
}
connection, err := pool.Acquire(ctx)
if err != nil {
return migrationError(ctx, err)
}
defer connection.Release()
for _, migration := range Migrations() {
if _, err := connection.Exec(ctx, migration.SQL); err != nil {
rollbackContext, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
_, _ = connection.Exec(rollbackContext, "ROLLBACK")
return migrationError(ctx, err)
}
}
return nil
}
func migrationError(ctx context.Context, err error) error {
if ctx != nil && ctx.Err() != nil {
return ctx.Err()
}
if errors.Is(err, context.Canceled) || errors.Is(err, context.DeadlineExceeded) {
return err
}
return fmt.Errorf("postgresadmin: apply migrations: %w", adminstate.ErrUnavailable)
}