1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
use sqlx::{Pool, Postgres};
use tracing::instrument;

use super::{core::*, entity::*};
use crate::{error::*, primitives::*};

#[derive(Debug, Clone)]
pub struct TxTemplates {
    pool: Pool<Postgres>,
}

impl TxTemplates {
    pub fn new(pool: &Pool<Postgres>) -> Self {
        Self { pool: pool.clone() }
    }

    #[instrument(name = "sqlx_ledger.tx_templates.create", skip_all)]
    pub async fn create(
        &self,
        NewTxTemplate {
            code,
            description,
            params,
            tx_input,
            entries,
            metadata,
        }: NewTxTemplate,
    ) -> Result<TxTemplateId, SqlxLedgerError> {
        let params_json = serde_json::to_value(&params)?;
        let tx_input_json = serde_json::to_value(&tx_input)?;
        let entries_json = serde_json::to_value(&entries)?;
        let record = sqlx::query!(
            r#"INSERT INTO sqlx_ledger_tx_templates (id, code, description, params, tx_input, entries, metadata)
            VALUES (gen_random_uuid(), $1, $2, $3, $4, $5, $6)
            RETURNING id, version, created_at"#,
            code,
            description,
            params_json,
            tx_input_json,
            entries_json,
            metadata
        )
        .fetch_one(&self.pool)
        .await?;
        Ok(TxTemplateId::from(record.id))
    }

    pub(crate) async fn find_core(&self, code: &str) -> Result<TxTemplateCore, SqlxLedgerError> {
        let record = sqlx::query!(
            r#"SELECT id, code, params, tx_input, entries FROM sqlx_ledger_tx_templates WHERE code = $1 LIMIT 1"#,
            code
        )
        .fetch_one(&self.pool)
        .await?;
        let params = match record.params {
            Some(serde_json::Value::Null) => None,
            Some(params) => Some(serde_json::from_value(params)?),
            None => None,
        };
        let tx_input = serde_json::from_value(record.tx_input)?;
        Ok(TxTemplateCore {
            id: TxTemplateId::from(record.id),
            _code: record.code,
            params,
            entries: serde_json::from_value(record.entries)?,
            tx_input,
        })
    }
}