80 lines
1.5 KiB
Go
80 lines
1.5 KiB
Go
|
package database
|
||
|
|
||
|
import (
|
||
|
"context"
|
||
|
|
||
|
"github.com/jackc/pgx/v4"
|
||
|
|
||
|
"github.com/jackc/pgx/v4/pgxpool"
|
||
|
"github.com/pkg/errors"
|
||
|
"gitlab.com/wpetit/goweb/middleware/container"
|
||
|
)
|
||
|
|
||
|
type MigrationFunc func(ctx context.Context, tx pgx.Tx) error
|
||
|
|
||
|
type Migration struct {
|
||
|
version string
|
||
|
up MigrationFunc
|
||
|
down MigrationFunc
|
||
|
}
|
||
|
|
||
|
func (m *Migration) Version() string {
|
||
|
return m.version
|
||
|
}
|
||
|
|
||
|
func (m *Migration) Up(ctx context.Context) error {
|
||
|
pool, err := m.getDatabaseService(ctx)
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
err = WithTx(ctx, pool, func(ctx context.Context, tx pgx.Tx) error {
|
||
|
return m.up(ctx, tx)
|
||
|
})
|
||
|
|
||
|
if err != nil {
|
||
|
return errors.Wrap(err, "could not apply up migration")
|
||
|
}
|
||
|
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
func (m *Migration) Down(ctx context.Context) error {
|
||
|
pool, err := m.getDatabaseService(ctx)
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
err = WithTx(ctx, pool, func(ctx context.Context, tx pgx.Tx) error {
|
||
|
return m.down(ctx, tx)
|
||
|
})
|
||
|
|
||
|
if err != nil {
|
||
|
return errors.Wrap(err, "could not apply down migration")
|
||
|
}
|
||
|
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
func (m *Migration) getDatabaseService(ctx context.Context) (*pgxpool.Pool, error) {
|
||
|
ctn, err := container.From(ctx)
|
||
|
if err != nil {
|
||
|
return nil, errors.Wrap(err, "could not retrieve service container")
|
||
|
}
|
||
|
|
||
|
pool, err := From(ctn)
|
||
|
if err != nil {
|
||
|
return nil, errors.Wrap(err, "could not retrieve database service")
|
||
|
}
|
||
|
|
||
|
return pool, nil
|
||
|
}
|
||
|
|
||
|
func NewMigration(version string, up, down MigrationFunc) *Migration {
|
||
|
return &Migration{
|
||
|
version: version,
|
||
|
up: up,
|
||
|
down: down,
|
||
|
}
|
||
|
}
|