48 lines
1.1 KiB
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)
|
|
}
|