stillbox/pkg/gordio/database/database.go

80 lines
1.7 KiB
Go
Raw Normal View History

2024-07-15 10:12:53 -04:00
package database
import (
"context"
"errors"
"strings"
"dynatron.me/x/stillbox/pkg/gordio/config"
sqlembed "dynatron.me/x/stillbox/sql"
"github.com/golang-migrate/migrate/v4"
_ "github.com/golang-migrate/migrate/v4/database/pgx/v5"
"github.com/golang-migrate/migrate/v4/source/iofs"
"github.com/jackc/pgx/v5/pgxpool"
)
2024-08-06 11:19:30 -04:00
// This file will eventually turn into a postgres driver.
2024-07-29 00:29:16 -04:00
// DB is a database handle.
2024-07-23 21:35:02 -04:00
type DB struct {
*pgxpool.Pool
*Queries
}
2024-07-15 10:12:53 -04:00
2024-07-29 00:29:16 -04:00
// NewClient creates a new DB using the provided config.
2024-10-21 14:11:08 -04:00
func NewClient(ctx context.Context, conf config.DB) (*DB, error) {
2024-07-15 10:12:53 -04:00
dir, err := iofs.New(sqlembed.Migrations, "postgres/migrations")
if err != nil {
return nil, err
}
m, err := migrate.NewWithSourceInstance("iofs", dir, strings.Replace(conf.Connect, "postgres://", "pgx5://", 1)) // yech
if err != nil {
return nil, err
}
err = m.Up()
if err != nil && !errors.Is(err, migrate.ErrNoChange) {
return nil, err
}
m.Close()
2024-10-21 14:11:08 -04:00
pool, err := pgxpool.New(ctx, conf.Connect)
2024-07-15 10:12:53 -04:00
if err != nil {
return nil, err
}
2024-07-23 21:35:02 -04:00
db := &DB{
Pool: pool,
Queries: New(pool),
}
2024-07-15 10:12:53 -04:00
return db, nil
}
type DBCtxKey string
const DBCTXKeyValue DBCtxKey = "dbctx"
2024-07-29 00:29:16 -04:00
// FromCtx returns the database handle from the provided Context.
2024-07-24 07:55:36 -04:00
func FromCtx(ctx context.Context) *DB {
c, ok := ctx.Value(DBCTXKeyValue).(*DB)
2024-07-15 10:12:53 -04:00
if !ok {
panic("no DB in context")
}
return c
}
2024-07-29 00:29:16 -04:00
// CtxWithDB returns a Context with the provided database handle.
2024-07-24 07:55:36 -04:00
func CtxWithDB(ctx context.Context, conn *DB) context.Context {
2024-07-15 10:12:53 -04:00
return context.WithValue(ctx, DBCTXKeyValue, conn)
}
2024-07-23 21:35:02 -04:00
2024-07-29 00:29:16 -04:00
// IsNoRows is a convenience function that returns whether a returned error is a database
// no rows error.
2024-07-23 21:35:02 -04:00
func IsNoRows(err error) bool {
return strings.Contains(err.Error(), "no rows in result set")
}