// Package db opens the SQLite database and applies goose migrations. package db import ( "database/sql" "embed" "fmt" "github.com/pressly/goose/v3" _ "modernc.org/sqlite" ) //go:embed migrations/*.sql var migrations embed.FS // Open opens (creating if needed) the SQLite file at path and migrates it // to the latest schema. WAL + busy_timeout keep reads snappy under writes. func Open(path string) (*sql.DB, error) { dsn := fmt.Sprintf("file:%s?_pragma=busy_timeout(5000)&_pragma=journal_mode(WAL)&_pragma=foreign_keys(1)", path) sqlDB, err := sql.Open("sqlite", dsn) if err != nil { return nil, fmt.Errorf("open sqlite: %w", err) } goose.SetBaseFS(migrations) if err := goose.SetDialect("sqlite3"); err != nil { return nil, fmt.Errorf("goose dialect: %w", err) } if err := goose.Up(sqlDB, "migrations"); err != nil { return nil, fmt.Errorf("migrate: %w", err) } return sqlDB, nil }