Files
backend/internal/store/db.go

46 lines
1.4 KiB
Go

package store
import (
"fmt"
"gorm.io/driver/sqlite"
"gorm.io/gorm"
"gorm.io/gorm/logger"
)
// Open opens (or creates) the SQLite database at path and runs GORM
// AutoMigrate for all models. SQLite with WAL is used for single-instance
// durability; the abstraction lives entirely in this package so a future
// migration to Postgres stays localised.
func Open(path string) (*gorm.DB, error) {
// _busy_timeout helps under concurrent writes; _foreign_keys enforces FK
// constraints that GORM expects; _journal_mode=WAL improves read/write
// concurrency for the single-file database.
dsn := fmt.Sprintf("%s?_busy_timeout=5000&_foreign_keys=on&_journal_mode=WAL", path)
db, err := gorm.Open(sqlite.Open(dsn), &gorm.Config{
// Silent: our handlers emit their own HTTP errors and frequently run
// "first-or-create" / 404 lookups whose ErrRecordNotFound would
// otherwise spam the operator's logs.
Logger: logger.Default.LogMode(logger.Silent),
})
if err != nil {
return nil, fmt.Errorf("open sqlite: %w", err)
}
if err := db.AutoMigrate(
&AdminUser{},
&App{},
&ModelConfig{},
&Skill{},
&Session{},
&Message{},
&AuditLog{},
); err != nil {
return nil, fmt.Errorf("auto-migrate: %w", err)
}
// Compound uniqueness: a skill slug is unique per app. Enforced in code
// to avoid depending on DB-specific index syntax during migration.
return db, nil
}