pub mod abuse;
pub mod agents;
pub mod ann;
pub mod approvals;
pub mod backend;
pub mod cache;
pub mod checkpoint;
pub mod cron;
pub mod delegation;
pub mod delivery_queue;
pub mod efficiency;
pub mod embeddings;
mod ext;
pub use ext::*;
pub mod hippocampus;
pub mod hygiene_log;
pub mod learned_skills;
pub mod memory;
pub mod metrics;
pub mod model_selection;
pub mod policy;
pub mod revenue_accounting;
pub mod revenue_feedback;
pub mod revenue_introspection;
pub mod revenue_opportunity_queries;
pub mod revenue_scoring;
pub mod revenue_strategy_summary;
pub mod revenue_swap_tasks;
pub mod revenue_tax_tasks;
pub mod routing_dataset;
pub mod schema;
pub mod service_revenue;
pub mod sessions;
pub mod shadow_routing;
pub mod skills;
pub mod task_events;
pub mod tasks;
pub mod tool_embeddings;
pub mod tools;
pub mod traces;
use std::sync::{Arc, Mutex};
use rusqlite::Connection;
pub use rusqlite::params_from_iter;
use roboticus_core::Result;
#[derive(Clone)]
pub struct Database {
conn: Arc<Mutex<Connection>>,
}
impl Database {
pub fn new(path: &str) -> Result<Self> {
let conn = if path == ":memory:" {
Connection::open_in_memory()
} else {
Connection::open(path)
}
.db_err()?;
conn.execute_batch(
"PRAGMA journal_mode=WAL; \
PRAGMA foreign_keys=ON; \
PRAGMA synchronous=NORMAL; \
PRAGMA auto_vacuum=INCREMENTAL;",
)
.db_err()?;
let current_auto_vacuum: i64 = conn
.query_row("PRAGMA auto_vacuum", [], |row| row.get(0))
.unwrap_or(0);
if current_auto_vacuum == 0 {
let _ = conn.execute_batch("PRAGMA auto_vacuum=INCREMENTAL; VACUUM;");
}
let db = Self {
conn: Arc::new(Mutex::new(conn)),
};
schema::initialize_db(&db)?;
Ok(db)
}
pub fn conn(&self) -> std::sync::MutexGuard<'_, Connection> {
self.conn.lock().unwrap_or_else(|e| e.into_inner())
}
}
impl std::fmt::Debug for Database {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("Database").finish()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn database_debug_impl() {
let db = Database::new(":memory:").expect("in-memory db");
let s = format!("{:?}", db);
assert_eq!(s, "Database");
}
#[test]
fn database_new_in_memory() {
let db = Database::new(":memory:").expect("in-memory db");
let _guard = db.conn();
}
#[test]
fn database_new_invalid_path_returns_error() {
let result = Database::new("/");
assert!(result.is_err(), "opening \"/\" as database should fail");
}
}