Short and single-letter names in application code become full words (tests keep theirs). Wrapped calls, signatures and composite literals put one item per line, and one-line function bodies are expanded. Exported names and groups of constants get doc comments, and comments refer to the renamed identifiers.
46 lines
1.4 KiB
Go
46 lines
1.4 KiB
Go
package store
|
|
|
|
import (
|
|
"database/sql"
|
|
"fmt"
|
|
)
|
|
|
|
// Option configures Open.
|
|
type Option func(*options)
|
|
|
|
type options struct {
|
|
autoMigrate bool
|
|
}
|
|
|
|
// OpenDB opens the SQLite database at path with the store's connection
|
|
// settings (foreign keys, WAL, busy timeout, immediate transactions). The
|
|
// file is created on first use. Use it for anything that works on the store's
|
|
// database directly, such as running migrations.
|
|
func OpenDB(path string) (*sql.DB, error) {
|
|
return sql.Open("sqlite3", dsn(path))
|
|
}
|
|
|
|
// WithAutoMigrate makes Open apply pending migrations instead of returning
|
|
// ErrNeedsMigration. Intended for tests and throwaway databases; applications
|
|
// should migrate explicitly with the migrate command.
|
|
func WithAutoMigrate() Option {
|
|
return func(opts *options) {
|
|
opts.autoMigrate = true
|
|
}
|
|
}
|
|
|
|
// dsn builds the mattn/go-sqlite3 connection string.
|
|
//
|
|
// - _foreign_keys: SQLite ignores REFERENCES clauses unless this is on.
|
|
// - _journal_mode=WAL: readers don't block the writer or each other.
|
|
// - _busy_timeout: wait for a lock rather than failing immediately.
|
|
// - _txlock=immediate: transactions take the write lock at BEGIN, so a
|
|
// read-then-write transaction (as in SaveOpportunity) can't fail with
|
|
// SQLITE_BUSY halfway through.
|
|
func dsn(path string) string {
|
|
return fmt.Sprintf(
|
|
"file:%s?_foreign_keys=on&_journal_mode=WAL&_busy_timeout=5000&_txlock=immediate",
|
|
path,
|
|
)
|
|
}
|