Skip to main content

safe_migrate/analysis/
transaction.rs

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