mithril_aggregator/database/record/
open_message.rs1use chrono::{DateTime, Utc};
2use sqlite::Row;
3use uuid::Uuid;
4
5use mithril_common::entities::{Epoch, ProtocolMessage, SignedEntityType};
6use mithril_persistence::database::Hydrator;
7use mithril_persistence::sqlite::{HydrationError, Projection, SqLiteEntity};
8
9#[derive(Debug, Clone, PartialEq, Eq)]
15pub struct OpenMessageRecord {
16 pub open_message_id: Uuid,
18
19 pub epoch: Epoch,
21
22 pub signed_entity_type: SignedEntityType,
24
25 pub protocol_message: ProtocolMessage,
27
28 pub is_certified: bool,
30
31 pub is_expired: bool,
33
34 pub created_at: DateTime<Utc>,
36
37 pub expires_at: Option<DateTime<Utc>>,
39}
40
41impl OpenMessageRecord {
42 #[cfg(test)]
43 pub fn dummy() -> Self {
45 let beacon = mithril_common::test_utils::fake_data::beacon();
46 let epoch = beacon.epoch;
47 let signed_entity_type = SignedEntityType::CardanoImmutableFilesFull(beacon);
48
49 Self {
50 open_message_id: Uuid::parse_str("193d1442-e89b-43cf-9519-04d8db9a12ff").unwrap(),
51 epoch,
52 signed_entity_type,
53 protocol_message: ProtocolMessage::new(),
54 is_certified: false,
55 is_expired: false,
56 created_at: Utc::now(),
57 expires_at: None,
58 }
59 }
60}
61
62impl SqLiteEntity for OpenMessageRecord {
63 fn hydrate(row: Row) -> Result<Self, HydrationError>
64 where
65 Self: Sized,
66 {
67 let open_message_id = row.read::<&str, _>(0);
68 let open_message_id = Uuid::parse_str(open_message_id).map_err(|e| {
69 HydrationError::InvalidData(format!(
70 "Invalid UUID in open_message.open_message_id: '{open_message_id}'. Error: {e}"
71 ))
72 })?;
73 let protocol_message = row.read::<&str, _>(4);
74 let protocol_message = serde_json::from_str(protocol_message).map_err(|e| {
75 HydrationError::InvalidData(format!(
76 "Invalid protocol message JSON representation '{protocol_message}'. Error: {e}"
77 ))
78 })?;
79 let epoch_settings_id = row.read::<i64, _>(1);
80 let epoch_val = u64::try_from(epoch_settings_id)
81 .map_err(|e| panic!("Integer field open_message.epoch_setting_id (value={epoch_settings_id}) is incompatible with u64 Epoch representation. Error = {e}"))?;
82 let beacon_str = Hydrator::read_signed_entity_beacon_column(&row, 2);
83 let signed_entity_type_id = usize::try_from(row.read::<i64, _>(3)).map_err(|e| {
84 panic!(
85 "Integer field open_message.signed_entity_type_id cannot be turned into usize: {e}"
86 )
87 })?;
88 let signed_entity_type =
89 Hydrator::hydrate_signed_entity_type(signed_entity_type_id, &beacon_str)?;
90 let is_certified = row.read::<i64, _>(5) != 0;
91 let datetime = &row.read::<&str, _>(7);
92 let created_at =
93 DateTime::parse_from_rfc3339(datetime).map_err(|e| {
94 HydrationError::InvalidData(format!(
95 "Could not turn open_message.created_at field value '{datetime}' to rfc3339 Datetime. Error: {e}"
96 ))
97 })?.with_timezone(&Utc);
98 let is_expired = row.read::<i64, _>(6) != 0;
99 let datetime = &row.read::<Option<&str>, _>(8);
100 let expires_at = datetime.map(|datetime| DateTime::parse_from_rfc3339(datetime).map_err(|e| {
101 HydrationError::InvalidData(format!(
102 "Could not turn open_message.expires_at field value '{datetime}' to rfc3339 Datetime. Error: {e}"
103 ))
104 })).transpose()?.map(|datetime| datetime.with_timezone(&Utc));
105 let open_message = Self {
106 open_message_id,
107 epoch: Epoch(epoch_val),
108 signed_entity_type,
109 protocol_message,
110 is_certified,
111 is_expired,
112 created_at,
113 expires_at,
114 };
115
116 Ok(open_message)
117 }
118
119 fn get_projection() -> Projection {
120 Projection::from(&[
121 (
122 "open_message_id",
123 "{:open_message:}.open_message_id",
124 "text",
125 ),
126 (
127 "epoch_setting_id",
128 "{:open_message:}.epoch_setting_id",
129 "int",
130 ),
131 ("beacon", "{:open_message:}.beacon", "text"),
132 (
133 "signed_entity_type_id",
134 "{:open_message:}.signed_entity_type_id",
135 "int",
136 ),
137 (
138 "protocol_message",
139 "{:open_message:}.protocol_message",
140 "text",
141 ),
142 ("is_certified", "{:open_message:}.is_certified", "bool"),
143 ("is_expired", "{:open_message:}.is_expired", "bool"),
144 ("created_at", "{:open_message:}.created_at", "text"),
145 ("expires_at", "{:open_message:}.expires_at", "text"),
146 ])
147 }
148}