mod actions;
mod annotations;
mod auth_blobs;
mod marks;
mod pages;
mod refs;
mod sessions;
mod skill_cache;
#[cfg(test)]
mod tests;
use std::path::Path;
use std::time::{SystemTime, UNIX_EPOCH};
use rusqlite::{Connection, OpenFlags};
use crate::error::Result;
use crate::migrate;
pub const IDEMPOTENCY_TTL_SECS: i64 = 30;
pub struct Store {
conn: Connection,
}
impl Store {
pub fn open(path: impl AsRef<Path>) -> Result<Self> {
let conn = Connection::open(path.as_ref())?;
configure(&conn)?;
migrate::apply(&conn)?;
Ok(Self { conn })
}
pub fn open_in_memory() -> Result<Self> {
let conn = Connection::open_in_memory()?;
configure(&conn)?;
migrate::apply(&conn)?;
Ok(Self { conn })
}
pub fn open_read_only(path: impl AsRef<Path>) -> Result<Self> {
let conn = Connection::open_with_flags(
path.as_ref(),
OpenFlags::SQLITE_OPEN_READ_ONLY | OpenFlags::SQLITE_OPEN_NO_MUTEX,
)?;
Ok(Self { conn })
}
#[must_use]
pub fn conn(&self) -> &Connection {
&self.conn
}
}
fn configure(conn: &Connection) -> Result<()> {
conn.pragma_update(None, "journal_mode", "WAL")?;
conn.pragma_update(None, "synchronous", "NORMAL")?;
conn.pragma_update(None, "foreign_keys", "ON")?;
Ok(())
}
#[must_use]
pub fn epoch_secs() -> i64 {
SystemTime::now()
.duration_since(UNIX_EPOCH)
.map_or(0, |d| i64::try_from(d.as_secs()).unwrap_or(i64::MAX))
}