connect_ncruces.go

 1//go:build !((darwin && (amd64 || arm64)) || (freebsd && (amd64 || arm64)) || (linux && (386 || amd64 || arm || arm64 || loong64 || ppc64le || riscv64 || s390x)) || (windows && (386 || amd64 || arm64)))
 2
 3package db
 4
 5import (
 6	"database/sql"
 7	"fmt"
 8
 9	"github.com/ncruces/go-sqlite3"
10	"github.com/ncruces/go-sqlite3/driver"
11)
12
13func openDB(dbPath string) (*sql.DB, error) {
14	// Use BEGIN IMMEDIATE so writers acquire the reserved lock up front,
15	// preventing deferred-to-writer upgrade deadlocks. The "file:" prefix
16	// is required for the ncruces driver to parse query parameters.
17	dsn := fmt.Sprintf("file:%s?_txlock=immediate", dbPath)
18	db, err := driver.Open(dsn, func(c *sqlite3.Conn) error {
19		// Set pragmas for better performance via _pragma query params.
20		// Format: PRAGMA name = value;
21		for name, value := range pragmas {
22			if err := c.Exec(fmt.Sprintf("PRAGMA %s = %s;", name, value)); err != nil {
23				return fmt.Errorf("failed to set pragma %q: %w", name, err)
24			}
25		}
26		return nil
27	})
28	if err != nil {
29		return nil, fmt.Errorf("failed to open database: %w", err)
30	}
31
32	return db, nil
33}