1mod sqlite;
2
3use anyhow::bail;
4use anyhow::Result;
5use async_trait::async_trait;
6use enum_dispatch::enum_dispatch;
7
8pub use self::sqlite::SqliteDb;
9
10#[async_trait]
11#[enum_dispatch]
12pub trait Db {
13 async fn save_ping(&self, entry: &PingEntry) -> Result<()>;
17
18 async fn load_ping(&self, job_id: &str) -> Result<Vec<PingEntry>>;
20
21 async fn save_exec(&self, entry: &ExecEntry) -> Result<()>;
23
24 async fn load_exec(&self, job_id: &str) -> Result<Vec<ExecEntry>>;
26
27 async fn migrate(&self) -> Result<()> {
33 Ok(())
34 }
35}
36
37#[enum_dispatch(Db)]
38#[derive(Clone)]
39pub enum DbImpl {
40 Sqlite(SqliteDb),
41}
42
43impl DbImpl {
44 pub async fn try_new(connection_string: &str) -> Result<Self> {
48 if connection_string.contains("sqlite") || connection_string.contains(".db") {
49 let db = SqliteDb::try_new(connection_string).await?;
50 return Ok(db.into());
51 }
52
53 bail!("unable to build a db impl");
54 }
55}
56
57#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, sqlx::FromRow)]
59pub struct PingEntry {
60 pub job_id: String,
61 pub target: String,
62 pub error: Option<String>,
63 pub message: Option<Vec<u8>>,
64}
65
66#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, sqlx::FromRow)]
68pub struct ExecEntry {
69 pub job_id: String,
70 pub target: String,
71 pub error: Option<String>,
72 pub exit_status: Option<u32>,
73 pub stdout: Option<Vec<u8>>,
74 pub stderr: Option<Vec<u8>>,
75}