meteologica/service_a/internal/app/db.go

66 lines
1.6 KiB
Go

package app
import (
"context"
"database/sql"
"embed"
"errors"
"fmt"
"log/slog"
"os"
mig "github.com/golang-migrate/migrate/v4"
_ "github.com/golang-migrate/migrate/v4/database/postgres"
"github.com/golang-migrate/migrate/v4/source/iofs"
"github.com/jackc/pgx/v5/pgxpool"
_ "github.com/jackc/pgx/v5/stdlib"
)
func NewPGXPool(datasource string) *pgxpool.Pool {
dbPool, err := pgxpool.New(context.Background(), datasource)
if err != nil {
slog.Error("error connecting to database", "error", err, "datasource", datasource)
panic(err)
}
if err := dbPool.Ping(context.Background()); err != nil {
slog.Error("error pinging database, maybe incorrect datasource", "error", err, "datasource", datasource)
panic(err)
}
slog.Info("connected to database", "datasource", datasource)
return dbPool
}
func Migrate(database embed.FS) {
dbConn, err := sql.Open("pgx", os.Getenv("DATASOURCE"))
if err != nil {
slog.Error("error opening database connection", "error", err)
return
}
defer dbConn.Close()
d, err := iofs.New(database, "database/migrations")
if err != nil {
slog.Error("error creating migration source", "error", err)
return
}
m, err := mig.NewWithSourceInstance("iofs", d, fmt.Sprintf("postgres://%s:%s@%s", os.Getenv("POSTGRES_USER"), os.Getenv("POSTGRES_PASSWORD"), os.Getenv("DSN")))
if err != nil {
slog.Error("error creating migration instance", "error", err)
return
}
err = m.Up()
if err != nil && !errors.Is(err, mig.ErrNoChange) {
slog.Error("cannot migrate", "error", err)
panic(err)
}
if errors.Is(err, mig.ErrNoChange) {
slog.Info("migration has no changes")
return
}
slog.Info("migration done")
}