use core::time::Duration;
use diesel::{RunQueryDsl, SqliteConnection, connection::SimpleConnection, dsl::sql, sql_types::Text};
use log::trace;
use crate::connection::DbConnection;
const LOG_TARGET: &str = "common_sqlite::connection_options";
pub const PRAGMA_BUSY_TIMEOUT: Duration = Duration::from_secs(60);
#[derive(Debug, Clone)]
pub struct ConnectionOptions {
enable_wal: bool,
enable_foreign_keys: bool,
busy_timeout: Option<Duration>,
}
impl ConnectionOptions {
pub fn new(enable_wal: bool, enable_foreign_keys: bool, busy_timeout: Duration) -> Self {
Self {
enable_wal,
enable_foreign_keys,
busy_timeout: Some(busy_timeout),
}
}
pub fn get_busy_timeout(&self) -> Option<Duration> {
self.busy_timeout
}
}
impl diesel::r2d2::CustomizeConnection<SqliteConnection, diesel::r2d2::Error> for ConnectionOptions {
fn on_acquire(&self, conn: &mut SqliteConnection) -> Result<(), diesel::r2d2::Error> {
(|| {
let start = std::time::Instant::now();
if let Some(d) = self.busy_timeout {
conn.batch_execute(&format!("PRAGMA busy_timeout = {};", d.as_millis()))?;
}
if self.enable_wal {
let current: String = sql::<Text>("PRAGMA journal_mode;").get_result(conn)?;
if current.eq_ignore_ascii_case("wal") {
conn.batch_execute("PRAGMA synchronous = NORMAL;")?;
} else if DbConnection::migration_lock_active() {
conn.batch_execute("PRAGMA journal_mode = WAL; PRAGMA synchronous = NORMAL;")?;
} else {
}
}
if self.enable_foreign_keys {
conn.batch_execute("PRAGMA foreign_keys = ON;")?;
}
trace!(target: LOG_TARGET, "Applied SQLite PRAGMAs on_acquire in {:.2?}", start.elapsed());
Ok(())
})()
.map_err(diesel::r2d2::Error::QueryError)
}
}