65 lines
1.6 KiB
Go
65 lines
1.6 KiB
Go
package db
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
|
|
"server/internal/models"
|
|
|
|
"gorm.io/driver/postgres"
|
|
"gorm.io/driver/sqlite"
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
type Config struct {
|
|
Driver string
|
|
DSN string
|
|
}
|
|
|
|
// 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)
|
|
}
|
|
if err := db.AutoMigrate(&models.User{}, &models.UserDetails{}, &models.UserPreferences{}, &models.Session{}, &models.PasswordResetToken{}); err != nil {
|
|
return nil, fmt.Errorf("migrate user: %w", err)
|
|
}
|
|
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)
|
|
}
|
|
if err := db.AutoMigrate(&models.User{}, &models.UserDetails{}, &models.UserPreferences{}, &models.Session{}, &models.PasswordResetToken{}); err != nil {
|
|
return nil, fmt.Errorf("migrate user: %w", err)
|
|
}
|
|
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)
|
|
}
|