sqlx_ledger/tx_template/
repo.rs1use cached::proc_macro::cached;
2use sqlx::{Pool, Postgres};
3use std::sync::Arc;
4use tracing::instrument;
5
6use super::{core::*, entity::*};
7use crate::{error::*, primitives::*};
8
9#[derive(Debug, Clone)]
11pub struct TxTemplates {
12 pool: Pool<Postgres>,
13}
14
15impl TxTemplates {
16 pub fn new(pool: &Pool<Postgres>) -> Self {
17 Self { pool: pool.clone() }
18 }
19
20 #[instrument(name = "sqlx_ledger.tx_templates.create", skip_all)]
21 pub async fn create(
22 &self,
23 NewTxTemplate {
24 id,
25 code,
26 description,
27 params,
28 tx_input,
29 entries,
30 metadata,
31 }: NewTxTemplate,
32 ) -> Result<TxTemplateId, SqlxLedgerError> {
33 let params_json = serde_json::to_value(¶ms)?;
34 let tx_input_json = serde_json::to_value(&tx_input)?;
35 let entries_json = serde_json::to_value(&entries)?;
36 let record = sqlx::query!(
37 r#"INSERT INTO sqlx_ledger_tx_templates (id, code, description, params, tx_input, entries, metadata)
38 VALUES ($1, $2, $3, $4, $5, $6, $7)
39 RETURNING id, version, created_at"#,
40 id as TxTemplateId,
41 code,
42 description,
43 params_json,
44 tx_input_json,
45 entries_json,
46 metadata
47 )
48 .fetch_one(&self.pool)
49 .await?;
50 Ok(TxTemplateId::from(record.id))
51 }
52
53 #[instrument(level = "trace", name = "sqlx_ledger.tx_templates.find_core", skip_all)]
54 pub(crate) async fn find_core(
55 &self,
56 code: &str,
57 ) -> Result<Arc<TxTemplateCore>, SqlxLedgerError> {
58 cached_find_core(&self.pool, code).await
59 }
60}
61
62#[cached(
63 key = "String",
64 convert = r#"{ code.to_string() }"#,
65 result = true,
66 sync_writes = true
67)]
68async fn cached_find_core(
69 pool: &Pool<Postgres>,
70 code: &str,
71) -> Result<Arc<TxTemplateCore>, SqlxLedgerError> {
72 let record = sqlx::query!(
73 r#"SELECT id, code, params, tx_input, entries FROM sqlx_ledger_tx_templates WHERE code = $1 LIMIT 1"#,
74 code
75 )
76 .fetch_one(pool)
77 .await?;
78 let params = match record.params {
79 Some(serde_json::Value::Null) => None,
80 Some(params) => Some(serde_json::from_value(params)?),
81 None => None,
82 };
83 let tx_input = serde_json::from_value(record.tx_input)?;
84 Ok(Arc::new(TxTemplateCore {
85 id: TxTemplateId::from(record.id),
86 _code: record.code,
87 params,
88 entries: serde_json::from_value(record.entries)?,
89 tx_input,
90 }))
91}