1use codex_utils_absolute_path::AbsolutePathBuf;
4use log::LevelFilter;
5use sqlx::ConnectOptions;
6use sqlx::Error;
7use sqlx::SqlitePool;
8use sqlx::sqlite::SqliteAutoVacuum;
9use sqlx::sqlite::SqliteConnectOptions;
10use sqlx::sqlite::SqliteJournalMode;
11use sqlx::sqlite::SqlitePoolOptions;
12use sqlx::sqlite::SqliteSynchronous;
13use std::path::Path;
14use std::time::Duration;
15
16#[derive(Clone, Debug, Eq, PartialEq)]
18pub struct SqliteConfig {
19 sqlite_home: AbsolutePathBuf,
20}
21
22impl SqliteConfig {
23 pub fn from_sqlite_home(sqlite_home: AbsolutePathBuf) -> Self {
24 Self { sqlite_home }
25 }
26
27 pub fn new_for_testing(sqlite_home: AbsolutePathBuf) -> Self {
28 Self::from_sqlite_home(sqlite_home)
29 }
30
31 pub fn home(&self) -> &Path {
32 self.sqlite_home.as_path()
33 }
34
35 pub async fn open_read_write_pool(&self, path: &Path) -> Result<SqlitePool, Error> {
37 let options = SqliteConnectOptions::new()
38 .filename(path)
39 .create_if_missing(true)
40 .journal_mode(SqliteJournalMode::Wal)
41 .synchronous(SqliteSynchronous::Normal)
42 .auto_vacuum(SqliteAutoVacuum::Incremental)
43 .busy_timeout(Duration::from_secs(5))
44 .log_statements(LevelFilter::Off);
45 SqlitePoolOptions::new()
46 .max_connections(5)
47 .connect_with(options)
48 .await
49 }
50
51 pub async fn open_read_only_pool(&self, path: &Path) -> Result<SqlitePool, Error> {
53 let options = SqliteConnectOptions::new()
54 .filename(path)
55 .create_if_missing(false)
56 .read_only(true)
57 .log_statements(LevelFilter::Off);
58 SqlitePoolOptions::new()
59 .max_connections(1)
60 .connect_with(options)
61 .await
62 }
63}