69 lines
2.2 KiB
Go
69 lines
2.2 KiB
Go
// Package database owns the Bun connection and the migration registry.
|
|
package database
|
|
|
|
import (
|
|
"database/sql"
|
|
"fmt"
|
|
"strings"
|
|
|
|
"github.com/uptrace/bun"
|
|
"github.com/uptrace/bun/dialect/pgdialect"
|
|
"github.com/uptrace/bun/dialect/sqlitedialect"
|
|
"github.com/uptrace/bun/driver/pgdriver"
|
|
"github.com/uptrace/bun/driver/sqliteshim"
|
|
"github.com/uptrace/bun/extra/bundebug"
|
|
"github.com/uptrace/bun/migrate"
|
|
"github.com/uptrace/bun/schema"
|
|
|
|
"git.k6n.net/mats/fullstack-template/internal/config"
|
|
migrations "git.k6n.net/mats/fullstack-template/internal/database/migrations"
|
|
)
|
|
|
|
// Open connects to the database named by cfg.DatabaseURL:
|
|
//
|
|
// sqlite:FILE?params Bun + modernc sqlite (pure Go, no CGO) — dev default
|
|
// postgres://… Bun + pgdriver against Postgres
|
|
//
|
|
// It does not ping — call PingContext during startup to fail fast.
|
|
func Open(cfg config.Config) (*bun.DB, error) {
|
|
var sqldb *sql.DB
|
|
var dialect schema.Dialect
|
|
|
|
switch {
|
|
case strings.HasPrefix(cfg.DatabaseURL, "sqlite:"):
|
|
dsn := strings.TrimPrefix(cfg.DatabaseURL, "sqlite:")
|
|
// Sensible dev defaults when the DSN brings no pragmas of its own:
|
|
// WAL keeps readers unblocked during writes, busy_timeout waits out
|
|
// the remaining write locks instead of erroring, foreign_keys is
|
|
// what everyone expects to be on.
|
|
if !strings.Contains(dsn, "_pragma") {
|
|
sep := "?"
|
|
if strings.Contains(dsn, "?") {
|
|
sep = "&"
|
|
}
|
|
dsn += sep + "_pragma=busy_timeout(5000)&_pragma=journal_mode(WAL)&_pragma=foreign_keys(1)"
|
|
}
|
|
var err error
|
|
sqldb, err = sql.Open(sqliteshim.ShimName, dsn)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("open sqlite %q: %w", dsn, err)
|
|
}
|
|
dialect = sqlitedialect.New()
|
|
default:
|
|
sqldb = sql.OpenDB(pgdriver.NewConnector(pgdriver.WithDSN(cfg.DatabaseURL)))
|
|
dialect = pgdialect.New()
|
|
}
|
|
|
|
db := bun.NewDB(sqldb, dialect)
|
|
if cfg.DebugQueries {
|
|
db.AddQueryHook(bundebug.NewQueryHook(bundebug.WithVerbose(true)))
|
|
}
|
|
return db, nil
|
|
}
|
|
|
|
// NewMigrator returns a bun migrator over the migrations registered in
|
|
// internal/database/migrations. See cmd/migrate for the CLI around it.
|
|
func NewMigrator(db *bun.DB) *migrate.Migrator {
|
|
return migrate.NewMigrator(db, migrations.Migrations)
|
|
}
|