Initial commit: CarrotAssistant backend (Go + Gin + SQLite, OpenAI-compatible agent runtime)
This commit is contained in:
45
internal/store/db.go
Normal file
45
internal/store/db.go
Normal file
@@ -0,0 +1,45 @@
|
||||
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
|
||||
}
|
||||
Reference in New Issue
Block a user