bsv_wallet_toolbox/storage/sync/
sync_map.rs1use std::collections::HashMap;
8
9use chrono::NaiveDateTime;
10use serde::{Deserialize, Serialize};
11
12use crate::tables::*;
13
14#[derive(Debug, Clone, Serialize, Deserialize)]
19#[serde(rename_all = "camelCase")]
20pub struct SyncChunk {
21 pub from_storage_identity_key: String,
23 pub to_storage_identity_key: String,
25 pub user_identity_key: String,
27 #[serde(skip_serializing_if = "Option::is_none")]
29 pub user: Option<User>,
30 #[serde(skip_serializing_if = "Option::is_none")]
32 pub proven_txs: Option<Vec<ProvenTx>>,
33 #[serde(skip_serializing_if = "Option::is_none")]
35 pub output_baskets: Option<Vec<OutputBasket>>,
36 #[serde(skip_serializing_if = "Option::is_none")]
38 pub transactions: Option<Vec<Transaction>>,
39 #[serde(skip_serializing_if = "Option::is_none")]
41 pub outputs: Option<Vec<Output>>,
42 #[serde(skip_serializing_if = "Option::is_none")]
44 pub tx_labels: Option<Vec<TxLabel>>,
45 #[serde(skip_serializing_if = "Option::is_none")]
47 pub tx_label_maps: Option<Vec<TxLabelMap>>,
48 #[serde(skip_serializing_if = "Option::is_none")]
50 pub output_tags: Option<Vec<OutputTag>>,
51 #[serde(skip_serializing_if = "Option::is_none")]
53 pub output_tag_maps: Option<Vec<OutputTagMap>>,
54 #[serde(skip_serializing_if = "Option::is_none")]
56 pub certificates: Option<Vec<Certificate>>,
57 #[serde(skip_serializing_if = "Option::is_none")]
59 pub certificate_fields: Option<Vec<CertificateField>>,
60 #[serde(skip_serializing_if = "Option::is_none")]
62 pub commissions: Option<Vec<Commission>>,
63 #[serde(skip_serializing_if = "Option::is_none")]
65 pub proven_tx_reqs: Option<Vec<ProvenTxReq>>,
66}
67
68#[derive(Debug, Clone, Serialize, Deserialize)]
73#[serde(rename_all = "camelCase")]
74pub struct EntitySyncMap {
75 pub entity_name: String,
77 pub id_map: HashMap<i64, i64>,
79 #[serde(default, with = "crate::serde_datetime::option")]
81 pub max_updated_at: Option<NaiveDateTime>,
82 pub count: i64,
84}
85
86impl EntitySyncMap {
87 pub fn new(entity_name: &str) -> Self {
89 Self {
90 entity_name: entity_name.to_string(),
91 id_map: HashMap::new(),
92 max_updated_at: None,
93 count: 0,
94 }
95 }
96
97 pub fn update_max(&mut self, updated_at: NaiveDateTime) {
99 match self.max_updated_at {
100 Some(current) if current >= updated_at => {}
101 _ => {
102 self.max_updated_at = Some(updated_at);
103 }
104 }
105 }
106
107 pub fn map_id(&mut self, foreign_id: i64, local_id: i64) -> Result<(), String> {
110 if let Some(existing) = self.id_map.get(&foreign_id) {
111 if *existing != local_id {
112 return Err(format!(
113 "EntitySyncMap[{}]: cannot override mapping {}=>{} with {}",
114 self.entity_name, foreign_id, existing, local_id
115 ));
116 }
117 }
118 self.id_map.insert(foreign_id, local_id);
119 Ok(())
120 }
121
122 pub fn get_local_id(&self, foreign_id: i64) -> Option<i64> {
124 self.id_map.get(&foreign_id).copied()
125 }
126}
127
128#[derive(Debug, Clone, Serialize, Deserialize)]
133#[serde(rename_all = "camelCase")]
134pub struct SyncMap {
135 pub proven_tx: EntitySyncMap,
137 pub output_basket: EntitySyncMap,
139 pub transaction: EntitySyncMap,
141 pub output: EntitySyncMap,
143 pub tx_label: EntitySyncMap,
145 pub tx_label_map: EntitySyncMap,
147 pub output_tag: EntitySyncMap,
149 pub output_tag_map: EntitySyncMap,
151 pub certificate: EntitySyncMap,
153 pub certificate_field: EntitySyncMap,
155 pub commission: EntitySyncMap,
157 pub proven_tx_req: EntitySyncMap,
159}
160
161impl SyncMap {
162 pub fn new() -> Self {
164 Self {
165 proven_tx: EntitySyncMap::new("provenTx"),
166 output_basket: EntitySyncMap::new("outputBasket"),
167 transaction: EntitySyncMap::new("transaction"),
168 output: EntitySyncMap::new("output"),
169 tx_label: EntitySyncMap::new("txLabel"),
170 tx_label_map: EntitySyncMap::new("txLabelMap"),
171 output_tag: EntitySyncMap::new("outputTag"),
172 output_tag_map: EntitySyncMap::new("outputTagMap"),
173 certificate: EntitySyncMap::new("certificate"),
174 certificate_field: EntitySyncMap::new("certificateField"),
175 commission: EntitySyncMap::new("commission"),
176 proven_tx_req: EntitySyncMap::new("provenTxReq"),
177 }
178 }
179}
180
181impl Default for SyncMap {
182 fn default() -> Self {
183 Self::new()
184 }
185}