mod sqlite;
use anyhow::bail;
use anyhow::Result;
use async_trait::async_trait;
use enum_dispatch::enum_dispatch;
pub use self::sqlite::SqliteDb;
#[async_trait]
#[enum_dispatch]
pub trait Db {
async fn save_ping(&self, entry: &PingEntry) -> Result<()>;
async fn load_ping(&self, job_id: &str) -> Result<Vec<PingEntry>>;
async fn save_exec(&self, entry: &ExecEntry) -> Result<()>;
async fn load_exec(&self, job_id: &str) -> Result<Vec<ExecEntry>>;
async fn migrate(&self) -> Result<()> {
Ok(())
}
}
#[enum_dispatch(Db)]
#[derive(Clone)]
pub enum DbImpl {
Sqlite(SqliteDb),
}
impl DbImpl {
pub async fn try_new(connection_string: &str) -> Result<Self> {
if connection_string.contains("sqlite") || connection_string.contains(".db") {
let db = SqliteDb::try_new(connection_string).await?;
return Ok(db.into());
}
bail!("unable to build a db impl");
}
}
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, sqlx::FromRow)]
pub struct PingEntry {
pub job_id: String,
pub target: String,
pub error: Option<String>,
pub message: Option<Vec<u8>>,
}
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, sqlx::FromRow)]
pub struct ExecEntry {
pub job_id: String,
pub target: String,
pub error: Option<String>,
pub exit_status: Option<u32>,
pub stdout: Option<Vec<u8>>,
pub stderr: Option<Vec<u8>>,
}