Skip to main content

qcraft_core/ast/
tcl.rs

1use super::custom::CustomTransaction;
2
3/// Transaction control statements.
4#[derive(Debug, Clone)]
5pub enum TransactionStmt {
6    Begin(BeginStmt),
7    Commit(CommitStmt),
8    Rollback(RollbackStmt),
9    Savepoint(SavepointStmt),
10    ReleaseSavepoint(ReleaseSavepointStmt),
11    SetTransaction(SetTransactionStmt),
12    LockTable(LockTableStmt),
13    /// PG: PREPARE TRANSACTION 'id'
14    PrepareTransaction(PrepareTransactionStmt),
15    /// PG: COMMIT PREPARED 'id'
16    CommitPrepared(CommitPreparedStmt),
17    /// PG: ROLLBACK PREPARED 'id'
18    RollbackPrepared(RollbackPreparedStmt),
19    Custom(Box<dyn CustomTransaction>),
20}
21
22impl TransactionStmt {
23    pub fn begin() -> Self {
24        Self::Begin(BeginStmt::default())
25    }
26
27    pub fn commit() -> Self {
28        Self::Commit(CommitStmt::default())
29    }
30
31    pub fn rollback() -> Self {
32        Self::Rollback(RollbackStmt::default())
33    }
34
35    pub fn savepoint(name: impl Into<String>) -> Self {
36        Self::Savepoint(SavepointStmt { name: name.into() })
37    }
38
39    pub fn release(name: impl Into<String>) -> Self {
40        Self::ReleaseSavepoint(ReleaseSavepointStmt { name: name.into() })
41    }
42
43    pub fn rollback_to(name: impl Into<String>) -> Self {
44        Self::Rollback(RollbackStmt {
45            to_savepoint: Some(name.into()),
46            ..Default::default()
47        })
48    }
49}
50
51// ---------------------------------------------------------------------------
52// BEGIN / START TRANSACTION
53// ---------------------------------------------------------------------------
54
55#[derive(Debug, Clone, Default)]
56pub struct BeginStmt {
57    /// Transaction modes (isolation level, access mode, deferrable).
58    pub modes: Option<Vec<TransactionMode>>,
59    /// SQLite: DEFERRED / IMMEDIATE / EXCLUSIVE.
60    pub lock_type: Option<SqliteLockType>,
61    /// SQL Server: named transaction.
62    pub name: Option<String>,
63    /// SQL Server: WITH MARK 'description'.
64    pub with_mark: Option<String>,
65}
66
67impl BeginStmt {
68    pub fn with_isolation(level: IsolationLevel) -> Self {
69        Self {
70            modes: Some(vec![TransactionMode::IsolationLevel(level)]),
71            ..Default::default()
72        }
73    }
74
75    pub fn read_only() -> Self {
76        Self {
77            modes: Some(vec![TransactionMode::ReadOnly]),
78            ..Default::default()
79        }
80    }
81
82    pub fn sqlite_deferred() -> Self {
83        Self {
84            lock_type: Some(SqliteLockType::Deferred),
85            ..Default::default()
86        }
87    }
88
89    pub fn sqlite_immediate() -> Self {
90        Self {
91            lock_type: Some(SqliteLockType::Immediate),
92            ..Default::default()
93        }
94    }
95
96    pub fn sqlite_exclusive() -> Self {
97        Self {
98            lock_type: Some(SqliteLockType::Exclusive),
99            ..Default::default()
100        }
101    }
102}
103
104/// SQLite BEGIN lock type.
105#[derive(Debug, Clone, Copy, PartialEq, Eq)]
106pub enum SqliteLockType {
107    Deferred,
108    Immediate,
109    Exclusive,
110}
111
112// ---------------------------------------------------------------------------
113// COMMIT
114// ---------------------------------------------------------------------------
115
116#[derive(Debug, Clone, Default)]
117pub struct CommitStmt {
118    /// PG/MySQL: AND CHAIN — start new transaction immediately.
119    pub and_chain: bool,
120    /// MySQL: RELEASE — disconnect session after commit.
121    pub release: bool,
122    /// SQL Server: transaction name.
123    pub name: Option<String>,
124    /// Oracle: COMMENT 'text'.
125    pub comment: Option<String>,
126    /// Oracle: WRITE mode (sync/async).
127    pub write_mode: Option<OracleWriteMode>,
128    /// Oracle: FORCE 'transaction_id' for in-doubt distributed txns.
129    pub force: Option<String>,
130}
131
132/// Oracle COMMIT WRITE options.
133#[derive(Debug, Clone, Copy, PartialEq, Eq)]
134pub struct OracleWriteMode {
135    pub wait: OracleWriteWait,
136    pub flush: OracleWriteFlush,
137}
138
139#[derive(Debug, Clone, Copy, PartialEq, Eq)]
140pub enum OracleWriteWait {
141    Wait,
142    NoWait,
143}
144
145#[derive(Debug, Clone, Copy, PartialEq, Eq)]
146pub enum OracleWriteFlush {
147    Immediate,
148    Batch,
149}
150
151// ---------------------------------------------------------------------------
152// ROLLBACK
153// ---------------------------------------------------------------------------
154
155#[derive(Debug, Clone, Default)]
156pub struct RollbackStmt {
157    /// Roll back to a savepoint instead of the whole transaction.
158    pub to_savepoint: Option<String>,
159    /// PG/MySQL: AND CHAIN — start new transaction immediately.
160    pub and_chain: bool,
161    /// MySQL: RELEASE — disconnect session after rollback.
162    pub release: bool,
163    /// SQL Server: transaction name (rolls back entire txn, not a savepoint).
164    pub name: Option<String>,
165    /// Oracle: FORCE 'transaction_id' for in-doubt distributed txns.
166    pub force: Option<String>,
167}
168
169// ---------------------------------------------------------------------------
170// SAVEPOINT
171// ---------------------------------------------------------------------------
172
173#[derive(Debug, Clone)]
174pub struct SavepointStmt {
175    pub name: String,
176}
177
178// ---------------------------------------------------------------------------
179// RELEASE SAVEPOINT
180// ---------------------------------------------------------------------------
181
182/// Supported by PG, SQLite, MySQL. Not supported by Oracle, SQL Server.
183#[derive(Debug, Clone)]
184pub struct ReleaseSavepointStmt {
185    pub name: String,
186}
187
188// ---------------------------------------------------------------------------
189// SET TRANSACTION
190// ---------------------------------------------------------------------------
191
192#[derive(Debug, Clone)]
193pub struct SetTransactionStmt {
194    /// Isolation level, access mode, deferrable.
195    pub modes: Vec<TransactionMode>,
196    /// Scope: current transaction (default), session, or global.
197    pub scope: Option<TransactionScope>,
198    /// PG: SET TRANSACTION SNAPSHOT snapshot_id.
199    pub snapshot_id: Option<String>,
200    /// Oracle: transaction name.
201    pub name: Option<String>,
202}
203
204/// Transaction mode options used in BEGIN and SET TRANSACTION.
205#[derive(Debug, Clone, PartialEq, Eq)]
206pub enum TransactionMode {
207    IsolationLevel(IsolationLevel),
208    ReadOnly,
209    ReadWrite,
210    /// PG only: DEFERRABLE (only with SERIALIZABLE READ ONLY).
211    Deferrable,
212    /// PG only: NOT DEFERRABLE.
213    NotDeferrable,
214    /// MySQL only: WITH CONSISTENT SNAPSHOT.
215    WithConsistentSnapshot,
216}
217
218#[derive(Debug, Clone, Copy, PartialEq, Eq)]
219pub enum IsolationLevel {
220    ReadUncommitted,
221    ReadCommitted,
222    RepeatableRead,
223    Serializable,
224    /// SQL Server only.
225    Snapshot,
226}
227
228/// Scope for SET TRANSACTION.
229#[derive(Debug, Clone, Copy, PartialEq, Eq)]
230pub enum TransactionScope {
231    /// PG: SET SESSION CHARACTERISTICS AS TRANSACTION ...
232    /// MySQL: SET SESSION TRANSACTION ...
233    Session,
234    /// MySQL: SET GLOBAL TRANSACTION ...
235    Global,
236}
237
238// ---------------------------------------------------------------------------
239// LOCK TABLE
240// ---------------------------------------------------------------------------
241
242#[derive(Debug, Clone)]
243pub struct LockTableStmt {
244    pub tables: Vec<LockTableDef>,
245    /// PG: NOWAIT — error immediately if lock unavailable.
246    pub nowait: bool,
247}
248
249#[derive(Debug, Clone)]
250pub struct LockTableDef {
251    pub table: String,
252    /// Optional schema prefix.
253    pub schema: Option<String>,
254    pub mode: LockMode,
255    /// PG: ONLY (exclude inherited tables).
256    pub only: bool,
257    /// MySQL: table alias.
258    pub alias: Option<String>,
259    /// Oracle: WAIT N seconds.
260    pub wait: Option<u64>,
261    /// Oracle: partition targeting.
262    pub partition: Option<String>,
263}
264
265/// Lock modes across all databases.
266#[derive(Debug, Clone, Copy, PartialEq, Eq)]
267pub enum LockMode {
268    // PG modes (8 levels)
269    AccessShare,
270    RowShare,
271    RowExclusive,
272    ShareUpdateExclusive,
273    Share,
274    ShareRowExclusive,
275    Exclusive,
276    AccessExclusive,
277    // MySQL modes
278    Read,
279    ReadLocal,
280    Write,
281    LowPriorityWrite,
282}
283
284// ---------------------------------------------------------------------------
285// Two-Phase Commit (PG)
286// ---------------------------------------------------------------------------
287
288/// PREPARE TRANSACTION 'transaction_id'
289#[derive(Debug, Clone)]
290pub struct PrepareTransactionStmt {
291    pub transaction_id: String,
292}
293
294/// COMMIT PREPARED 'transaction_id'
295#[derive(Debug, Clone)]
296pub struct CommitPreparedStmt {
297    pub transaction_id: String,
298}
299
300/// ROLLBACK PREPARED 'transaction_id'
301#[derive(Debug, Clone)]
302pub struct RollbackPreparedStmt {
303    pub transaction_id: String,
304}