context_harness/
db.rs

1//! SQLite database connection management.
2//!
3//! Provides a connection pool to the SQLite database with WAL mode
4//! enabled for concurrent read/write performance. The database file
5//! and its parent directories are created automatically if they don't exist.
6//!
7//! # Write-Ahead Logging (WAL)
8//!
9//! WAL mode is enabled for all connections, which allows concurrent
10//! readers and a single writer without blocking. This is important for
11//! the MCP server, where search queries and sync operations may overlap.
12//!
13//! # Connection Pool
14//!
15//! Uses `sqlx::SqlitePool` with up to 5 concurrent connections.
16//! Connections are reused across requests for efficiency.
17
18use anyhow::Result;
19use sqlx::sqlite::{SqliteConnectOptions, SqlitePool, SqlitePoolOptions};
20use std::str::FromStr;
21
22use crate::config::Config;
23
24/// Create a connection pool to the configured SQLite database.
25///
26/// - Creates the database file and parent directories if they don't exist.
27/// - Enables WAL journal mode for concurrent read/write.
28/// - Returns a pool with up to 5 connections.
29///
30/// # Arguments
31///
32/// * `config` — Application configuration containing the database path.
33///
34/// # Errors
35///
36/// Returns an error if the database cannot be created or connected to.
37pub async fn connect(config: &Config) -> Result<SqlitePool> {
38    let db_path = &config.db.path;
39
40    // Ensure parent directory exists
41    if let Some(parent) = db_path.parent() {
42        std::fs::create_dir_all(parent)?;
43    }
44
45    let options = SqliteConnectOptions::from_str(&format!("sqlite:{}", db_path.display()))?
46        .create_if_missing(true)
47        .journal_mode(sqlx::sqlite::SqliteJournalMode::Wal);
48
49    let pool = SqlitePoolOptions::new()
50        .max_connections(5)
51        .connect_with(options)
52        .await?;
53
54    Ok(pool)
55}