Documentation
¶
Overview ¶
Package db owns the process-wide SQLite connection lifecycle.
Database access outside schema migrations should go through this package and a DAO. Only this package may open, configure, cache, or close the underlying SQLite connection; table operations belong to internal/dao.
Index ¶
- Constants
- func BeginSQLTx(ctx context.Context, connection *sql.DB, opts *sql.TxOptions) (*sql.Tx, error)
- func BeginTx(ctx context.Context, connection *bun.DB, opts *sql.TxOptions) (bun.Tx, error)
- func BeginWaitQuantiles() (p50, p99 time.Duration)
- func BeginWaitStats() (count uint64, total, max time.Duration)
- func BusyRetryStats() (hits uint64, totalWait time.Duration)
- func CanonicalPath(path string) (string, error)
- func CheckpointStats() (attempts, failures uint64, busyFrames, logFrames, checkpointed int64)
- func Close(path string) error
- func CloseAll() error
- func DSNForOS(path string, windows bool) string
- func IsCached(path string) bool
- func IsIntegrityError(err error) bool
- func IsSchemaIncompatible(err error) bool
- func Open(path string, migrate Migrator) (*bun.DB, error)
- func OpenReadOnlyStandalone(path string) (*bun.DB, error)
- func OpenStandalone(path string, migrate Migrator) (*bun.DB, error)
- func OpenWithOptions(path string, migrate Migrator, opts Options) (*bun.DB, error)
- func Query(path string, migrate Migrator, fn func(*bun.DB) error) error
- func RunInTx(ctx context.Context, connection *bun.DB, opts *sql.TxOptions, ...) error
- func SchemaIncompatible(err error) error
- func SetMigrationRecoveryNotifier(fn func(MigrationRecovery))
- func Write(ctx context.Context, path string, migrate Migrator, ...) error
- type DatabasePoolStat
- type DatabaseWalStat
- type IndexRepair
- type IntegrityError
- type MigrationRecovery
- type Migrator
- type Options
Constants ¶
const BusyTimeout = 10 * time.Second
BusyTimeout is the SQLite busy_timeout applied to every managed connection: a writer waits this long for the single writer lock before returning SQLITE_BUSY. It is the per-statement stall budget that callers which must tolerate transient contention (for example the session runtime heartbeat) need to exceed to absorb one contended begin within a single attempt.
Variables ¶
This section is empty.
Functions ¶
func BeginSQLTx ¶
BeginSQLTx begins a transaction on a raw *sql.DB handle with the same begin retry. Raw-SQL owners (schema initialization and migrations) use it so concurrent startup on one session directory cannot fail on a transient writer conflict.
func BeginTx ¶
BeginTx begins a Bun transaction on a managed (or caller-owned) connection, retrying a transient SQLITE_BUSY/SQLITE_LOCKED begin within the shared budget.
func BeginWaitQuantiles ¶ added in v1.3.103
BeginWaitQuantiles returns bucket-approximated p50 and p99 transaction begin waits. A quantile in a bounded bucket reports that bucket's inclusive upper bound, so the value is never an understatement; a quantile in the overflow bucket (a single begin slower than the last bound) reports the observed maximum rather than the last bound, so the slow tail is not understated either. Both are zero until the first begin is recorded.
func BeginWaitStats ¶
BeginWaitStats returns the cumulative transaction begin attempt count, the total wall time spent inside begin calls, and the slowest single begin since process start.
func BusyRetryStats ¶
BusyRetryStats returns the cumulative begin-retry hit count and the total backoff time slept between attempts since process start. The wait total counts the scheduled backoff delays only; time blocked inside a begin call (busy_timeout) belongs to the driver and is reported by BeginWaitStats.
func CanonicalPath ¶
CanonicalPath returns the absolute, cleaned database path used as the cache key. Keeping this in one package prevents duplicate connections to the same SQLite file through differently spelled paths.
func CheckpointStats ¶ added in v1.3.103
CheckpointStats returns the cumulative checkpoint attempt/failure counts and the accumulated (busy, log, checkpointed) frame counts since process start.
func Close ¶
Close releases one process-owned SQLite connection. It is used by resource stores that own a whole database file and need to remove that exact file after their data has been deleted. General callers should normally keep using CloseAll at process shutdown.
func CloseAll ¶
func CloseAll() error
CloseAll checkpoints and closes all process-owned connections.
func DSNForOS ¶
DSNForOS returns the configured SQLite file URI with foreign key enforcement disabled, which is the canonical session database policy. It is exported for platform-specific integration tests.
func IsCached ¶ added in v1.3.103
IsCached reports whether this process currently holds a cached connection for the database file at path. Advisory consumers (the UDP lease bus database_rebuilt watcher) use it to ignore notices for files they never opened, so a forged or stale packet cannot trigger a close/checkpoint of an unrelated database.
func IsIntegrityError ¶ added in v1.3.105
IsIntegrityError reports whether err describes structural SQLite corruption.
func IsSchemaIncompatible ¶
IsSchemaIncompatible reports whether err was marked by SchemaIncompatible.
func Open ¶
Open returns the process-wide Bun connection for path with foreign key enforcement disabled (the canonical session database policy). Callers must not close it; CloseAll owns the lifecycle. Derived stores that need cascade behavior use OpenWithOptions.
func OpenReadOnlyStandalone ¶
OpenReadOnlyStandalone opens an uncached, read-only connection without running integrity repair, WAL setup, or migrations. It is for safety preflights that must inspect an existing database without changing it. The caller owns the returned connection and must close it.
func OpenStandalone ¶
OpenStandalone opens an uncached connection for callers that explicitly own its lifecycle, such as offline integrity checks. Foreign key enforcement stays disabled to match the canonical session database policy.
func OpenWithOptions ¶
OpenWithOptions returns the process-wide Bun connection for path, applying per-database Options. The connection is cached by canonical path, so the options for a given file must be stable across callers.
func RunInTx ¶
func RunInTx(ctx context.Context, connection *bun.DB, opts *sql.TxOptions, fn func(context.Context, bun.Tx) error) error
RunInTx mirrors (*bun.DB).RunInTx with the shared begin retry: the callback runs in one transaction that is committed on success and rolled back otherwise (including a panic).
func SchemaIncompatible ¶
SchemaIncompatible marks a migration failure caused by a schema this build cannot upgrade in place. internal/db reacts by backing up and rebuilding the database; any other migration error is reported to the caller unchanged.
Migration owners (internal/session) call this for the failures that a rebuild genuinely fixes - an unappliable migration or an incompatible legacy schema - and must not use it for transient or resource failures such as writer contention, cancellation, or a read-only file. internal/db additionally refuses to rebuild for those cases, because rebuilding deletes the database file and must never be triggered by a healthy database under pressure.
func SetMigrationRecoveryNotifier ¶
func SetMigrationRecoveryNotifier(fn func(MigrationRecovery))
SetMigrationRecoveryNotifier registers a hook invoked for every completed recovery, after the recovery has been recorded and logged. Passing nil clears it. It is called once per recovery and must not block: the bus publisher is best-effort and only announces an advisory wake-up.
Types ¶
type DatabasePoolStat ¶ added in v1.3.103
type DatabasePoolStat struct {
Path string `json:"path"`
MaxOpenConnections int `json:"maxOpenConnections"`
OpenConnections int `json:"openConnections"`
InUse int `json:"inUse"`
Idle int `json:"idle"`
WaitCount int64 `json:"waitCount"`
WaitDurationMillis int64 `json:"waitDurationMs"`
MaxIdleClosed int64 `json:"maxIdleClosed"`
MaxIdleTimeClosed int64 `json:"maxIdleTimeClosed"`
MaxLifetimeClosed int64 `json:"maxLifetimeClosed"`
}
DatabasePoolStat reports one open database's connection-pool counters. Every managed connection uses SetMaxOpenConns(1), so WaitCount/WaitDuration is the direct measure of how often and how long a transaction or query had to queue for the single connection: a growing value under concurrent sessions is the baseline that would justify (or rule out) a separate read connection pool. Path is the database file's base name so the local /debug/vars surface does not expose absolute filesystem paths.
func PoolStats ¶ added in v1.3.103
func PoolStats() []DatabasePoolStat
PoolStats reports the connection-pool counters for every database this process currently holds open, sorted by path. It is the measurement half of deciding whether the single-writer connection model needs a read pool; it changes no behavior.
type DatabaseWalStat ¶ added in v1.3.103
DatabaseWalStat reports one cached database's on-disk write-ahead log size. Path is the database file's base name: the /debug/vars endpoint is a local diagnostic surface, so it does not expose absolute filesystem paths.
func WalStats ¶ added in v1.3.103
func WalStats() []DatabaseWalStat
WalStats reports the write-ahead log size for every database this process currently holds open. A WAL that grows without shrinking between checkpoints is the direct signal that write pressure outpaces checkpointing.
type IndexRepair ¶
type IndexRepair struct {
// Path is the canonical database path whose indexes were rebuilt.
Path string
// Cause is the integrity-check line that triggered the repair, which names
// the affected index.
Cause string
// At is when the repair happened.
At time.Time
}
IndexRepair records a secondary index internal/db rebuilt while opening a database. An interrupted write can leave an index disagreeing with the table rows it derives from; rebuilding it is lossless, so the open succeeds instead of refusing a database whose canonical pages are intact.
The repair is reported rather than hidden: a database that needed one has already survived a failed write, and front-ends drain these records through TakeIndexRepairs so the user learns about it exactly once.
func TakeIndexRepairs ¶
func TakeIndexRepairs() []IndexRepair
TakeIndexRepairs returns the repairs recorded since the last call and clears them.
func (IndexRepair) Describe ¶
func (r IndexRepair) Describe() string
Describe returns the one-line operator-facing summary of a repair.
type IntegrityError ¶ added in v1.3.105
IntegrityError means SQLite found structural corruption while opening a database. The database is deliberately left untouched: unlike a stale derived index, a damaged b-tree may contain canonical session data.
func (*IntegrityError) Error ¶ added in v1.3.105
func (e *IntegrityError) Error() string
type MigrationRecovery ¶
type MigrationRecovery struct {
// Path is the canonical database path that was replaced.
Path string
// BackupPath is the snapshot of the pre-recovery database. It is empty only
// when the database file did not exist and nothing needed to be preserved,
// or when the recovery was performed by another process.
BackupPath string
// Err is the migration failure that triggered the recovery. It is nil for a
// recovery another process announced over the advisory inter-process bus.
Err error
// Peer reports that another process performed the recovery, so the database
// file was replaced while this process may still hold it open.
Peer bool
// At is when the recovery happened.
At time.Time
}
MigrationRecovery records a schema migration failure that internal/db recovered from by snapshotting the unrecoverable database and starting a new empty one in its place.
The previous data is not deleted: it stays in BackupPath, which callers should surface to the user (front-ends drain the records with TakeMigrationRecoveries so the notice is shown exactly once).
func MigrationRecoveries ¶
func MigrationRecoveries() []MigrationRecovery
MigrationRecoveries returns the recoveries recorded in this process without clearing them.
func TakeMigrationRecoveries ¶
func TakeMigrationRecoveries() []MigrationRecovery
TakeMigrationRecoveries returns the recoveries recorded since the last call and clears them, so a front-end can tell the user exactly once.
func (MigrationRecovery) Describe ¶
func (r MigrationRecovery) Describe() string
Describe returns the one-line operator-facing summary of a recovery. Callers that want a richer message use the fields directly.
type Migrator ¶
Migrator initializes or validates a database. It is intentionally kept compatible with the existing session migration implementation; migrations are the one place where schema SQL is required.
type Options ¶
type Options struct {
ForeignKeys bool
}
Options configures per-database SQLite connection behavior.
ForeignKeys enables SQLite foreign key enforcement for one database file. The canonical session database must keep it disabled: project policy enforces referential integrity in the repository layer (transactional writes, centralized deletion cleanup lists, and integrity tests such as TestDeleteSessionRemovesEveryChildRow), not in the database engine, so that cross-version recovery and partially corrupted canonical stores are never amplified by hard constraints.
A private, rebuildable derived store may opt in. The per-knowledge-base graph/FTS database (see docs/proposal/desktop-knowledge-base-agent-proposal.md) designs its snapshot lifecycle around ON DELETE CASCADE pruning and can always be rebuilt from its source directory, so it enables enforcement without exposing canonical session data to it. Options must be consistent for a given file path because connections are cached per path.