1use crate::error::{QuillSQLError, QuillSQLResult};
2use crate::transaction::{IsolationLevel, Transaction};
3use sqlparser::ast::TransactionAccessMode;
4pub struct SessionContext {
6 default_isolation: IsolationLevel,
7 default_access_mode: TransactionAccessMode,
8 autocommit: bool,
9 active_txn: Option<Transaction>,
10 pending_session_isolation: Option<IsolationLevel>,
11 pending_session_access: Option<TransactionAccessMode>,
12}
13
14impl SessionContext {
15 pub fn new(default_isolation: IsolationLevel) -> Self {
16 Self {
17 default_isolation,
18 default_access_mode: TransactionAccessMode::ReadWrite,
19 autocommit: true,
20 active_txn: None,
21 pending_session_isolation: None,
22 pending_session_access: None,
23 }
24 }
25
26 pub fn default_isolation(&self) -> IsolationLevel {
27 self.default_isolation
28 }
29
30 pub fn set_default_isolation(&mut self, isolation: IsolationLevel) {
31 self.default_isolation = isolation;
32 }
33
34 pub fn default_access_mode(&self) -> TransactionAccessMode {
35 self.default_access_mode
36 }
37
38 pub fn set_default_access_mode(&mut self, mode: TransactionAccessMode) {
39 self.default_access_mode = mode;
40 }
41
42 pub fn set_active_isolation(&mut self, isolation: IsolationLevel) {
44 if let Some(txn) = self.active_txn.as_mut() {
45 txn.set_isolation_level(isolation);
46 }
47 }
48
49 pub fn autocommit(&self) -> bool {
50 self.autocommit
51 }
52
53 pub fn set_autocommit(&mut self, enabled: bool) {
54 self.autocommit = enabled;
55 }
56
57 pub fn pending_session_isolation(&self) -> Option<IsolationLevel> {
59 self.pending_session_isolation
60 }
61
62 pub fn set_pending_session_isolation(&mut self, isolation: Option<IsolationLevel>) {
64 self.pending_session_isolation = isolation;
65 }
66
67 pub fn pending_session_access(&self) -> Option<TransactionAccessMode> {
68 self.pending_session_access
69 }
70
71 pub fn set_pending_session_access(&mut self, mode: Option<TransactionAccessMode>) {
72 self.pending_session_access = mode;
73 }
74
75 pub fn has_active_transaction(&self) -> bool {
76 self.active_txn.is_some()
77 }
78
79 pub fn active_txn(&self) -> Option<&Transaction> {
80 self.active_txn.as_ref()
81 }
82
83 pub fn active_txn_mut(&mut self) -> Option<&mut Transaction> {
84 self.active_txn.as_mut()
85 }
86
87 pub fn set_active_transaction(&mut self, mut txn: Transaction) -> QuillSQLResult<()> {
88 if self.active_txn.is_some() {
89 return Err(QuillSQLError::Execution(
90 "transaction already active in session".to_string(),
91 ));
92 }
93 if let Some(isolation) = self.pending_session_isolation.take() {
94 self.default_isolation = isolation;
95 txn.set_isolation_level(isolation);
96 } else {
97 self.default_isolation = txn.isolation_level();
98 }
99
100 if let Some(mode) = self.pending_session_access.take() {
101 self.default_access_mode = mode;
102 txn.update_access_mode(mode);
103 } else {
104 self.default_access_mode = txn.access_mode();
105 }
106
107 self.active_txn = Some(txn);
108 Ok(())
109 }
110
111 pub fn take_active_transaction(&mut self) -> Option<Transaction> {
112 self.active_txn.take()
113 }
114
115 pub fn clear_active_transaction(&mut self) {
116 self.active_txn = None;
117 }
118
119 pub fn apply_transaction_modes(&mut self, modes: &crate::plan::logical_plan::TransactionModes) {
121 if let Some(level) = modes.isolation_level {
122 if let Some(txn) = self.active_txn.as_mut() {
123 txn.set_isolation_level(level);
124 }
125 }
126 if let Some(mode) = modes.access_mode {
127 if let Some(txn) = self.active_txn.as_mut() {
128 txn.update_access_mode(mode);
129 }
130 }
131 }
132
133 pub fn apply_session_modes(&mut self, modes: &crate::plan::logical_plan::TransactionModes) {
135 if let Some(level) = modes.isolation_level {
136 self.default_isolation = level;
137 self.pending_session_isolation = Some(level);
138 }
139 if let Some(mode) = modes.access_mode {
140 self.default_access_mode = mode;
141 self.pending_session_access = Some(mode);
142 }
143 }
144}