mithril_persistence/database/record/
cardano_block.rs

1use sqlite::Row;
2
3use mithril_common::entities::{BlockHash, BlockNumber, CardanoBlockWithTransactions, SlotNumber};
4
5use crate::database::Hydrator;
6use crate::sqlite::{HydrationError, Projection, SqLiteEntity};
7
8/// Cardano block record is the representation of a cardano block stored in the sqlite database.
9#[derive(Debug, PartialEq, Clone)]
10pub struct CardanoBlockRecord {
11    /// Hash of the block
12    pub block_hash: BlockHash,
13
14    /// Number of the block
15    pub block_number: BlockNumber,
16
17    /// Slot number of the block
18    pub slot_number: SlotNumber,
19}
20
21impl CardanoBlockRecord {
22    /// SQLite max variables per prepared query are `32 766`, given each record needs to bind three variables and to leave some
23    /// room for other variables (i.e. in WHERE clause) we fix this limit to 10k, meaning 30 000 binds at once maximum
24    pub const MAX_PER_INSERT: usize = 10_000;
25
26    /// CardanoBlockRecord factory
27    pub fn new<T: Into<BlockHash>>(
28        block_hash: T,
29        block_number: BlockNumber,
30        slot_number: SlotNumber,
31    ) -> Self {
32        Self {
33            block_hash: block_hash.into(),
34            block_number,
35            slot_number,
36        }
37    }
38}
39
40impl SqLiteEntity for CardanoBlockRecord {
41    fn hydrate(row: Row) -> Result<Self, HydrationError>
42    where
43        Self: Sized,
44    {
45        let block_hash = row.read::<&str, _>(0);
46        let block_number =
47            Hydrator::try_to_u64("cardano_block.block_number", row.read::<i64, _>(1))?;
48        let slot_number = Hydrator::try_to_u64("cardano_block.slot_number", row.read::<i64, _>(2))?;
49
50        Ok(Self {
51            block_hash: block_hash.to_string(),
52            block_number: BlockNumber(block_number),
53            slot_number: SlotNumber(slot_number),
54        })
55    }
56
57    fn get_projection() -> Projection {
58        Projection::from(&[
59            ("block_hash", "{:cardano_block:}.block_hash", "text"),
60            ("block_number", "{:cardano_block:}.block_number", "int"),
61            ("slot_number", "{:cardano_block:}.slot_number", "int"),
62        ])
63    }
64}
65
66impl From<CardanoBlockWithTransactions> for CardanoBlockRecord {
67    fn from(block: CardanoBlockWithTransactions) -> Self {
68        Self::new(block.block_hash, block.block_number, block.slot_number)
69    }
70}