Skip to content
Snippets Groups Projects
Commit 0350ac95 authored by Tobias Meisel's avatar Tobias Meisel Committed by Michael Zigldrum
Browse files

Moved and fixed postgres migration

parent 73123952
No related branches found
No related tags found
No related merge requests found
# Postgres
### Using Config
```golang
// config.go
pkg config
type Config struct {
cfgPkg.BaseConfig `mapstructure:",squash"`
Postgres postgresPkg.Config `mapstructure:"postgres"`
}
// main.go
var conf config.Config
config.LoadConfig("WELLKNOWN", &conf, nil)
pgDb, err := postgresPkg.ConnectRetry(ctx, conf.Postgres, time.Minute)
```
### Using ConnectRetry
`ConnectRetry` is a function that tries to establish a db connection for the given
`maxDuration time.Duration`. It will periodically retry, using a fibonacci backoff
pattern.
For usage example, see above.
### Using MigrateUp
Given the following folder structure:
```
src/
├─ postgres/
│ ├─ postgres.go
│ ├─ migrations/
│ │ ├─ 001_init.down.sql
│ │ ├─ 001_init.up.sql
├─ main.go
```
First, create a variable of type `embed.FS` and annotate it with `//go:embed relative-path`,
pointing to the folder containing the migration files (no `.` or `..` allowed):
```golang
// postgres/postgres.go
pkg postgres
//go:embed migrations
var Migrations embed.FS
```
Then, when you established the DB connection (here in `main.go`), pass
the variable and path to `MigrateUP()`
```golang
// main.go
pkg main
func main() {
// ...
pgDb, _ := postgresPkg.ConnectRetry(...)
postgres.MigrateUP(pgDb, postgres.Migrations, "migrations")
}
```
The last parameter is the path relative to the embedded file system.
\ No newline at end of file
package migration
import (
"embed"
"errors"
"fmt"
"net/http"
"github.com/golang-migrate/migrate/v4"
"github.com/golang-migrate/migrate/v4/source/httpfs"
"github.com/jackc/pgx/v5/pgxpool"
)
func MigrateUP(pool *pgxpool.Pool, migrations embed.FS, migrationsPath string) error {
source, err := httpfs.New(http.FS(migrations), migrationsPath)
if err != nil {
return nil
}
m, err := migrate.NewWithSourceInstance("httpfs", source, pool.Config().ConnString())
if err != nil {
return fmt.Errorf("failed to init migration: %w", err)
}
if err := m.Up(); err != nil && errors.Is(err, migrate.ErrNoChange) {
return err
}
return nil
}
......@@ -2,8 +2,15 @@ package postgres
import (
"context"
"embed"
"errors"
"fmt"
"net/http"
"time"
"github.com/golang-migrate/migrate/v4"
_ "github.com/golang-migrate/migrate/v4/database/postgres"
"github.com/golang-migrate/migrate/v4/source/httpfs"
"github.com/jackc/pgx/v5/pgconn"
"github.com/jackc/pgx/v5/pgxpool"
"github.com/sethvargo/go-retry"
......@@ -48,6 +55,24 @@ func ConnectRetry(ctx context.Context, conf Config, maxDuration time.Duration, e
return
}
func MigrateUP(pool *pgxpool.Pool, migrations embed.FS, migrationsPath string) error {
source, err := httpfs.New(http.FS(migrations), migrationsPath)
if err != nil {
return fmt.Errorf("could not initialize source: %w", err)
}
m, err := migrate.NewWithSourceInstance("httpfs", source, pool.Config().ConnString())
if err != nil {
return fmt.Errorf("failed to init migration: %w", err)
}
if err := m.Up(); err != nil && !errors.Is(err, migrate.ErrNoChange) {
return err
}
return nil
}
func isRetryableError(err error) bool {
if _, ok := err.(*pgconn.ConnectError); ok {
return true
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment