cala_server/integration/
mod.rs

1use sqlx::PgPool;
2
3use cala_ledger::LedgerOperation;
4
5es_entity::entity_id! { IntegrationId }
6
7pub struct Integration {
8    pub id: IntegrationId,
9    pub name: String,
10    data: serde_json::Value,
11}
12
13impl Integration {
14    fn new(id: IntegrationId, name: String, data: impl serde::Serialize) -> Self {
15        Self {
16            id,
17            name,
18            data: serde_json::to_value(data).expect("Could not serialize data"),
19        }
20    }
21
22    pub fn data<T: serde::de::DeserializeOwned>(&self) -> Result<T, serde_json::Error> {
23        serde_json::from_value(self.data.clone())
24    }
25}
26
27pub struct Integrations {
28    pool: PgPool,
29}
30
31impl Integrations {
32    pub(crate) fn new(pool: &PgPool) -> Self {
33        Self { pool: pool.clone() }
34    }
35
36    pub async fn create_in_op(
37        &self,
38        op: &mut LedgerOperation<'_>,
39        id: impl Into<IntegrationId> + std::fmt::Debug,
40        name: String,
41        data: impl serde::Serialize,
42    ) -> Result<Integration, sqlx::Error> {
43        use es_entity::AtomicOperation;
44
45        let integration = Integration::new(id.into(), name, data);
46        sqlx::query!(
47            r#"INSERT INTO integrations (id, name, data)
48            VALUES ($1, $2, $3)"#,
49            integration.id as IntegrationId,
50            integration.name,
51            integration.data
52        )
53        .execute(op.as_executor())
54        .await?;
55        Ok(integration)
56    }
57
58    pub async fn find_by_id(
59        &self,
60        id: impl Into<IntegrationId>,
61    ) -> Result<Integration, sqlx::Error> {
62        let id = id.into();
63        let row = sqlx::query_as!(
64            Integration,
65            r#"SELECT id, name, data
66            FROM integrations
67            WHERE id = $1"#,
68            id as IntegrationId
69        )
70        .fetch_one(&self.pool)
71        .await?;
72        Ok(row)
73    }
74}