use deadpool_postgres::{Manager, Object, Pool}; use dropshot::{ApiDescription, ConfigLogging, ConfigLoggingLevel, HttpError}; use eyre::Context; use slog::Logger; use std::env::var; use std::str::FromStr; use tokio_postgres::{Config, NoTls}; mod api; mod db; pub mod import; mod types; mod utils; #[derive(Clone)] pub struct ApiContext { pub pool: Pool, } impl ApiContext { pub async fn get_conn(&self) -> Result { self.pool .get() .await .map_err(|err| HttpError::for_internal_error(err.to_string())) } } pub fn create_logger() -> eyre::Result { let log = ConfigLogging::StderrTerminal { level: ConfigLoggingLevel::Info, } .to_logger("plc-mirror")?; Ok(log) } pub fn create_api() -> eyre::Result> { let mut api_desc = ApiDescription::new(); api_desc.register(api::get_plc_op_log)?; api_desc.register(api::get_plc_audit_log)?; api_desc.register(api::get_last_op)?; api_desc.register(api::resolve_did)?; api_desc.register(api::index)?; Ok(api_desc) } pub async fn connect_db() -> eyre::Result { let db_uri = var("PLC_DB_URI").wrap_err("PLC_DB_URI missing")?; let cfg = Config::from_str(&db_uri)?; let mgr = Manager::from_config(cfg, NoTls, Default::default()); let pool = Pool::builder(mgr).build()?; // run the init script let init_conn = pool.get().await?; init_conn.simple_query(include_str!("sql/init.sql")).await?; Ok(pool) } pub async fn get_start_after(pool: &Pool) -> eyre::Result> { if let Some(env_start_after) = var("PLC_START_AFTER").ok() { return Ok(Some(env_start_after)); } let obj = pool.get().await?; let last_ts = db::get_last_operation_ts(&obj) .await? .map(|v| v.to_rfc3339_opts(chrono::SecondsFormat::Millis, true)); Ok(last_ts) }