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") }