Skip to main content

safe_migrate/analysis/
transaction.rs

1// FILE: src/analysis/transaction.rs
2
3use crate::analysis::graph::DependencyEdge;
4use crate::ast::identifiers::ObjectId;
5use crate::model::relation::RelationOverlay;
6use crate::model::schema::SchemaOverlay;
7use crate::model::sequence::SequenceOverlay;
8use crate::model::types::TypeOverlay;
9use std::collections::{HashMap, HashSet};
10
11#[derive(Debug, Clone)]
12pub struct NamespaceSnapshot {
13    pub schemas: HashMap<String, SchemaOverlay>,
14    pub relations: HashMap<ObjectId, RelationOverlay>,
15    pub types: HashMap<ObjectId, TypeOverlay>,
16    pub functions: HashMap<ObjectId, crate::model::function::FunctionOverlay>,
17    pub sequences: HashMap<ObjectId, SequenceOverlay>,
18    pub publications: HashMap<String, crate::model::replication::PublicationOverlay>,
19    pub triggers: HashMap<ObjectId, crate::model::trigger::TriggerOverlay>,
20    pub constraints: HashMap<(ObjectId, String), crate::model::constraint::ConstraintState>,
21    pub graph: Vec<DependencyEdge>,
22    pub pending_validation: HashSet<(ObjectId, String)>,
23    pub baseline_relations: HashSet<ObjectId>,
24    pub baseline_indexes: HashSet<ObjectId>,
25    pub baseline_foreign_keys: HashSet<(ObjectId, String)>,
26    pub baseline_fk_dependencies: HashSet<ObjectId>,
27    pub baseline_sequences: HashSet<ObjectId>,
28}
29
30#[derive(Debug, Clone)]
31pub enum StateChange {
32    SchemaSnapshot {
33        name: String,
34        previous: Option<SchemaOverlay>,
35    },
36    NamespaceSnapshot(Box<NamespaceSnapshot>),
37    RelationSnapshot {
38        id: ObjectId,
39        previous: Box<Option<RelationOverlay>>,
40    },
41    TypeSnapshot {
42        id: ObjectId,
43        previous: Option<TypeOverlay>,
44    },
45    SequenceSnapshot {
46        id: ObjectId,
47        previous: Option<SequenceOverlay>,
48    },
49    SearchPathSnapshot {
50        previous: Vec<String>,
51        previous_template: Vec<String>,
52    },
53    GenerationCounterSnapshot {
54        previous: u64,
55    },
56    PendingValidationSnapshot {
57        previous: HashSet<(ObjectId, String)>,
58    },
59    GraphLengthMarker {
60        len: usize,
61    },
62    GraphSnapshot {
63        previous: Vec<DependencyEdge>,
64    },
65    FunctionSnapshot {
66        id: ObjectId,
67        previous: Option<crate::model::function::FunctionOverlay>,
68    },
69    PublicationSnapshot {
70        id: ObjectId,
71        previous: Option<crate::model::replication::PublicationOverlay>,
72    },
73    SubscriptionSnapshot {
74        id: ObjectId,
75        previous: Option<crate::model::replication::SubscriptionOverlay>,
76    },
77    RoleSnapshot {
78        id: ObjectId,
79        previous: Option<crate::model::role::RoleOverlay>,
80    },
81    TriggerSnapshot {
82        id: ObjectId,
83        previous: Option<crate::model::trigger::TriggerOverlay>,
84    },
85    ConstraintSnapshot {
86        table_id: ObjectId,
87        name: String,
88        previous: Option<crate::model::constraint::ConstraintState>,
89    },
90    RoleContextSnapshot {
91        current_role: String,
92        current_role_known: bool,
93        persistent_current_role: String,
94        persistent_current_role_known: bool,
95        session_role: String,
96        session_role_known: bool,
97        persistent_session_role: String,
98        persistent_session_role_known: bool,
99    },
100    ConfidenceSnapshot {
101        previous: crate::analysis::state::Confidence,
102    },
103}
104
105#[derive(Debug, Clone, PartialEq, Eq)]
106pub enum TransactionFrameKind {
107    Root,
108    Savepoint(String),
109}
110
111#[derive(Debug, Clone)]
112pub struct TransactionFrame {
113    pub kind: TransactionFrameKind,
114    pub undo_log: Vec<StateChange>,
115}
116
117impl TransactionFrame {
118    pub fn root() -> Self {
119        Self {
120            kind: TransactionFrameKind::Root,
121            undo_log: Vec::new(),
122        }
123    }
124
125    pub fn savepoint(name: impl Into<String>) -> Self {
126        Self {
127            kind: TransactionFrameKind::Savepoint(name.into()),
128            undo_log: Vec::new(),
129        }
130    }
131
132    pub fn is_named_savepoint(&self, name: &str) -> bool {
133        matches!(&self.kind, TransactionFrameKind::Savepoint(candidate) if candidate == name)
134    }
135}