mithril_persistence/database/query/block_range_root/
insert_block_range.rs

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