Skip to main content

safe_migrate/db/
cache.rs

1// FILE: src/db/cache.rs
2use crate::ast::identifiers::ObjectId;
3use crate::model::relation::RelationState;
4use serde::{Deserialize, Serialize};
5use std::collections::HashMap;
6
7#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
8pub struct ForeignKeyCache {
9    pub constraint_name: String,
10    pub from_table: ObjectId,
11    pub to_table: ObjectId,
12}
13
14#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
15pub struct IndexCache {
16    pub index_id: ObjectId,
17    pub table_id: ObjectId,
18}
19
20#[derive(Debug, Clone, Serialize, Deserialize)]
21pub struct DbCache {
22    pub pg_version_num: Option<u32>,
23
24    // Tell Serde to convert the complex HashMap into a flat JSON array
25    #[serde(with = "vectorize")]
26    pub relations: HashMap<ObjectId, RelationState>,
27
28    #[serde(default)]
29    pub foreign_keys: Vec<ForeignKeyCache>,
30
31    #[serde(default)]
32    pub indexes: Vec<IndexCache>,
33}
34
35impl Default for DbCache {
36    fn default() -> Self {
37        Self::new()
38    }
39}
40
41impl DbCache {
42    pub fn new() -> Self {
43        Self {
44            pg_version_num: None,
45            relations: HashMap::new(),
46            foreign_keys: Vec::new(),
47            indexes: Vec::new(),
48        }
49    }
50
51    pub fn insert_baseline(&mut self, id: ObjectId, state: RelationState) {
52        self.relations.insert(id, state);
53    }
54
55    pub fn baseline_relations(&self) -> impl Iterator<Item = (&ObjectId, &RelationState)> {
56        self.relations.iter()
57    }
58}
59
60// Helper module to let Serde handle Structs as HashMap Keys
61mod vectorize {
62    use serde::{Deserialize, Deserializer, Serialize, Serializer};
63    use std::collections::HashMap;
64    use std::hash::Hash;
65
66    pub fn serialize<K, V, S>(map: &HashMap<K, V>, serializer: S) -> Result<S::Ok, S::Error>
67    where
68        K: Serialize,
69        V: Serialize,
70        S: Serializer,
71    {
72        let vec: Vec<(&K, &V)> = map.iter().collect();
73        vec.serialize(serializer)
74    }
75
76    pub fn deserialize<'de, K, V, D>(deserializer: D) -> Result<HashMap<K, V>, D::Error>
77    where
78        K: Deserialize<'de> + Eq + Hash,
79        V: Deserialize<'de>,
80        D: Deserializer<'de>,
81    {
82        let vec: Vec<(K, V)> = Vec::deserialize(deserializer)?;
83        Ok(vec.into_iter().collect())
84    }
85}