| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364 |
- package db
- import (
- "context"
- "database/sql"
- "fmt"
- "log/slog"
- "path/filepath"
- "github.com/ncruces/go-sqlite3"
- "github.com/ncruces/go-sqlite3/driver"
- _ "github.com/ncruces/go-sqlite3/embed"
- "github.com/pressly/goose/v3"
- )
- func Connect(ctx context.Context, dataDir string) (*sql.DB, error) {
- if dataDir == "" {
- return nil, fmt.Errorf("data.dir is not set")
- }
- dbPath := filepath.Join(dataDir, "crush.db")
- // Set pragmas for better performance
- pragmas := []string{
- "PRAGMA foreign_keys = ON;",
- "PRAGMA journal_mode = WAL;",
- "PRAGMA page_size = 4096;",
- "PRAGMA cache_size = -8000;",
- "PRAGMA synchronous = NORMAL;",
- "PRAGMA secure_delete = ON;",
- }
- db, err := driver.Open(dbPath, func(c *sqlite3.Conn) error {
- for _, pragma := range pragmas {
- if err := c.Exec(pragma); err != nil {
- return fmt.Errorf("failed to set pragma `%s`: %w", pragma, err)
- }
- }
- return nil
- })
- if err != nil {
- return nil, fmt.Errorf("failed to open database: %w", err)
- }
- // Verify connection
- if err = db.PingContext(ctx); err != nil {
- db.Close()
- return nil, fmt.Errorf("failed to connect to database: %w", err)
- }
- goose.SetBaseFS(FS)
- if err := goose.SetDialect("sqlite3"); err != nil {
- slog.Error("Failed to set dialect", "error", err)
- return nil, fmt.Errorf("failed to set dialect: %w", err)
- }
- if err := goose.Up(db, "migrations"); err != nil {
- slog.Error("Failed to apply migrations", "error", err)
- return nil, fmt.Errorf("failed to apply migrations: %w", err)
- }
- return db, nil
- }
|