mithril_persistence/database/query/cardano_transaction/
insert_cardano_transaction.rs

1use std::iter::repeat_n;
2
3use sqlite::Value;
4
5use mithril_common::StdResult;
6
7use crate::database::record::CardanoTransactionRecord;
8use crate::sqlite::{Query, SourceAlias, SqLiteEntity, WhereCondition};
9
10/// Query to insert [CardanoTransactionRecord] in the sqlite database
11pub struct InsertCardanoTransactionQuery {
12    condition: WhereCondition,
13}
14
15impl InsertCardanoTransactionQuery {
16    /// Query that insert one record.
17    pub fn insert_one(record: &CardanoTransactionRecord) -> StdResult<Self> {
18        Self::insert_many(vec![record.clone()])
19    }
20
21    /// Query that insert multiples records.
22    pub fn insert_many(transactions_records: Vec<CardanoTransactionRecord>) -> StdResult<Self> {
23        let columns = "(transaction_hash, block_number, slot_number, block_hash)";
24        let values_columns: Vec<&str> =
25            repeat_n("(?*, ?*, ?*, ?*)", transactions_records.len()).collect();
26
27        let values: StdResult<Vec<Value>> =
28            transactions_records
29                .into_iter()
30                .try_fold(vec![], |mut vec, record| {
31                    vec.append(&mut vec![
32                        Value::String(record.transaction_hash),
33                        Value::Integer(record.block_number.try_into()?),
34                        Value::Integer(record.slot_number.try_into()?),
35                        Value::String(record.block_hash.clone()),
36                    ]);
37                    Ok(vec)
38                });
39        let condition = WhereCondition::new(
40            format!("{columns} values {}", values_columns.join(", ")).as_str(),
41            values?,
42        );
43
44        Ok(Self { condition })
45    }
46}
47
48impl Query for InsertCardanoTransactionQuery {
49    type Entity = CardanoTransactionRecord;
50
51    fn filters(&self) -> WhereCondition {
52        self.condition.clone()
53    }
54
55    fn get_definition(&self, condition: &str) -> String {
56        let aliases = SourceAlias::new(&[("{:cardano_tx:}", "cardano_tx")]);
57        let projection = Self::Entity::get_projection().expand(aliases);
58
59        format!("insert or ignore into cardano_tx {condition} returning {projection}")
60    }
61}