go-quasar-partial-ssr/backend/internal/db/db.go

76 lines
1.6 KiB
Go

package db
import (
"fmt"
"os"
"path/filepath"
"strings"
"github.com/gofiber/fiber/v3"
"gorm.io/driver/postgres"
"gorm.io/driver/sqlite"
"gorm.io/gorm"
)
type Config struct {
Driver string
DSN string
}
var DB *gorm.DB
// Init opens the configured database connection and runs schema migrations.
func Init(cfg Config) (*gorm.DB, error) {
switch cfg.Driver {
case "sqlite":
if err := ensureSQLiteDir(cfg.DSN); err != nil {
return nil, fmt.Errorf("prepare sqlite path: %w", err)
}
db, err := gorm.Open(sqlite.Open(cfg.DSN), &gorm.Config{})
if err != nil {
return nil, fmt.Errorf("open sqlite: %w", err)
}
DB = db
return db, nil
case "postgres":
db, err := gorm.Open(postgres.Open(cfg.DSN), &gorm.Config{})
if err != nil {
return nil, fmt.Errorf("open postgres: %w", err)
}
DB = db
return db, nil
default:
return nil, fmt.Errorf("unsupported driver %q", cfg.Driver)
}
}
func ensureSQLiteDir(dsn string) error {
pathSpec := dsn
if idx := strings.Index(pathSpec, "?"); idx >= 0 {
pathSpec = pathSpec[:idx]
}
pathSpec = strings.TrimPrefix(pathSpec, "file:")
if pathSpec == "" || strings.Contains(pathSpec, ":memory:") {
return nil
}
dir := filepath.Dir(pathSpec)
if dir == "." || dir == "" {
return nil
}
return os.MkdirAll(dir, 0o755)
}
// dbFromCtx extracts *gorm.DB from Fiber context.
func dbFromCtx(c fiber.Ctx) (*gorm.DB, error) {
dbVal := c.Locals("db")
db, ok := dbVal.(*gorm.DB)
if !ok || db == nil {
return nil, fiber.NewError(fiber.StatusInternalServerError, "database unavailable")
}
return db, nil
}
func DBFromCtx(c fiber.Ctx) (*gorm.DB, error) {
return dbFromCtx(c)
}