56 lines
1.5 KiB
Go
56 lines
1.5 KiB
Go
package postgres
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"net/url"
|
|
|
|
"drive.local/drivev2/db/migrations"
|
|
"github.com/golang-migrate/migrate/v4"
|
|
pgx5migrate "github.com/golang-migrate/migrate/v4/database/pgx/v5"
|
|
"github.com/golang-migrate/migrate/v4/source/iofs"
|
|
)
|
|
|
|
// Migrate applies every pending forward migration using an advisory lock.
|
|
func Migrate(databaseURL string) (returnErr error) {
|
|
sourceDriver, err := iofs.New(migrations.Files, ".")
|
|
if err != nil {
|
|
return fmt.Errorf("open embedded migrations: %w", err)
|
|
}
|
|
|
|
migrationURL, err := url.Parse(databaseURL)
|
|
if err != nil {
|
|
return fmt.Errorf("parse database URL for migrations: %w", err)
|
|
}
|
|
migrationURL.Scheme = "pgx5"
|
|
query := migrationURL.Query()
|
|
query.Set("x-multi-statement", "true")
|
|
query.Set("x-statement-timeout", "30000")
|
|
if query.Get("connect_timeout") == "" {
|
|
query.Set("connect_timeout", "30")
|
|
}
|
|
migrationURL.RawQuery = query.Encode()
|
|
|
|
databaseDriver, err := (&pgx5migrate.Postgres{}).Open(migrationURL.String())
|
|
if err != nil {
|
|
return fmt.Errorf("open migration database: %w", err)
|
|
}
|
|
|
|
runner, err := migrate.NewWithInstance("iofs", sourceDriver, "pgx5", databaseDriver)
|
|
if err != nil {
|
|
return errors.Join(
|
|
fmt.Errorf("create migration runner: %w", err),
|
|
sourceDriver.Close(),
|
|
databaseDriver.Close(),
|
|
)
|
|
}
|
|
defer func() {
|
|
sourceErr, databaseErr := runner.Close()
|
|
returnErr = errors.Join(returnErr, sourceErr, databaseErr)
|
|
}()
|
|
|
|
if err := runner.Up(); err != nil && !errors.Is(err, migrate.ErrNoChange) {
|
|
return fmt.Errorf("apply database migrations: %w", err)
|
|
}
|
|
return nil
|
|
}
|