reifydb_engine/transaction/
mod.rs

1// Copyright (c) reifydb.com 2025
2// This file is licensed under the AGPL-3.0-or-later, see license.md file
3
4use reifydb_catalog::MaterializedCatalog;
5use reifydb_core::{
6	CommitVersion, EncodedKey, EncodedKeyRange, TransactionId,
7	interface::{
8		BoxedMultiVersionIter, MultiVersionQueryTransaction, MultiVersionValues, QueryTransaction,
9		SingleVersionTransaction,
10	},
11};
12use reifydb_transaction::single::TransactionSingleVersion;
13
14mod catalog;
15mod command;
16#[allow(dead_code)]
17pub(crate) mod operation;
18mod query;
19
20pub use command::StandardCommandTransaction;
21pub use query::StandardQueryTransaction;
22use reifydb_core::interface::CdcTransaction;
23use reifydb_transaction::cdc::TransactionCdc;
24
25/// An enum that can hold either a command or query transaction for flexible
26/// execution
27pub enum StandardTransaction<'a> {
28	Command(&'a mut StandardCommandTransaction),
29	Query(&'a mut StandardQueryTransaction),
30}
31
32impl<'a> QueryTransaction for StandardTransaction<'a> {
33	type SingleVersionQuery<'b>
34		= <TransactionSingleVersion as SingleVersionTransaction>::Query<'b>
35	where
36		Self: 'b;
37
38	type CdcQuery<'b>
39		= <TransactionCdc as CdcTransaction>::Query<'b>
40	where
41		Self: 'b;
42
43	fn begin_single_query<'k, I>(&self, keys: I) -> crate::Result<Self::SingleVersionQuery<'_>>
44	where
45		I: IntoIterator<Item = &'k EncodedKey>,
46	{
47		match self {
48			Self::Command(txn) => txn.begin_single_query(keys),
49			Self::Query(txn) => txn.begin_single_query(keys),
50		}
51	}
52
53	fn begin_cdc_query(&self) -> crate::Result<Self::CdcQuery<'_>> {
54		match self {
55			Self::Command(txn) => txn.begin_cdc_query(),
56			Self::Query(txn) => txn.begin_cdc_query(),
57		}
58	}
59}
60
61impl<'a> MultiVersionQueryTransaction for StandardTransaction<'a> {
62	fn version(&self) -> CommitVersion {
63		match self {
64			Self::Command(txn) => MultiVersionQueryTransaction::version(*txn),
65			Self::Query(txn) => MultiVersionQueryTransaction::version(*txn),
66		}
67	}
68
69	fn id(&self) -> TransactionId {
70		match self {
71			Self::Command(txn) => txn.id(),
72			Self::Query(txn) => txn.id(),
73		}
74	}
75
76	fn get(&mut self, key: &EncodedKey) -> crate::Result<Option<MultiVersionValues>> {
77		match self {
78			Self::Command(txn) => txn.get(key),
79			Self::Query(txn) => txn.get(key),
80		}
81	}
82
83	fn contains_key(&mut self, key: &EncodedKey) -> crate::Result<bool> {
84		match self {
85			Self::Command(txn) => txn.contains_key(key),
86			Self::Query(txn) => txn.contains_key(key),
87		}
88	}
89
90	fn range_batched(&mut self, range: EncodedKeyRange, batch_size: u64) -> crate::Result<BoxedMultiVersionIter> {
91		match self {
92			Self::Command(txn) => txn.range_batched(range, batch_size),
93			Self::Query(txn) => txn.range_batched(range, batch_size),
94		}
95	}
96
97	fn range_rev_batched(
98		&mut self,
99		range: EncodedKeyRange,
100		batch_size: u64,
101	) -> crate::Result<BoxedMultiVersionIter> {
102		match self {
103			Self::Command(txn) => txn.range_rev_batched(range, batch_size),
104			Self::Query(txn) => txn.range_rev_batched(range, batch_size),
105		}
106	}
107
108	fn prefix(&mut self, prefix: &EncodedKey) -> crate::Result<BoxedMultiVersionIter> {
109		match self {
110			Self::Command(txn) => txn.prefix(prefix),
111			Self::Query(txn) => txn.prefix(prefix),
112		}
113	}
114
115	fn prefix_rev(&mut self, prefix: &EncodedKey) -> crate::Result<BoxedMultiVersionIter> {
116		match self {
117			Self::Command(txn) => txn.prefix_rev(prefix),
118			Self::Query(txn) => txn.prefix_rev(prefix),
119		}
120	}
121
122	fn read_as_of_version_exclusive(&mut self, version: CommitVersion) -> reifydb_core::Result<()> {
123		match self {
124			StandardTransaction::Command(txn) => txn.read_as_of_version_inclusive(version),
125			StandardTransaction::Query(txn) => txn.read_as_of_version_exclusive(version),
126		}
127	}
128}
129
130impl<'a> From<&'a mut StandardCommandTransaction> for StandardTransaction<'a> {
131	fn from(txn: &'a mut StandardCommandTransaction) -> Self {
132		Self::Command(txn)
133	}
134}
135
136impl<'a> From<&'a mut StandardQueryTransaction> for StandardTransaction<'a> {
137	fn from(txn: &'a mut StandardQueryTransaction) -> Self {
138		Self::Query(txn)
139	}
140}
141
142impl<'a> StandardTransaction<'a> {
143	/// Extract the underlying StandardCommandTransaction, panics if this is
144	/// a Query transaction
145	pub fn command(self) -> &'a mut StandardCommandTransaction {
146		match self {
147			Self::Command(txn) => txn,
148			Self::Query(_) => panic!("Expected Command transaction but found Query transaction"),
149		}
150	}
151
152	/// Extract the underlying StandardQueryTransaction, panics if this is a
153	/// Command transaction
154	pub fn query(self) -> &'a mut StandardQueryTransaction {
155		match self {
156			Self::Query(txn) => txn,
157			Self::Command(_) => panic!("Expected Query transaction but found Command transaction"),
158		}
159	}
160
161	/// Get a mutable reference to the underlying
162	/// StandardCommandTransaction, panics if this is a Query transaction
163	pub fn command_mut(&mut self) -> &mut StandardCommandTransaction {
164		match self {
165			Self::Command(txn) => txn,
166			Self::Query(_) => panic!("Expected Command transaction but found Query transaction"),
167		}
168	}
169
170	/// Get a mutable reference to the underlying StandardQueryTransaction,
171	/// panics if this is a Command transaction
172	pub fn query_mut(&mut self) -> &mut StandardQueryTransaction {
173		match self {
174			Self::Query(txn) => txn,
175			Self::Command(_) => panic!("Expected Query transaction but found Command transaction"),
176		}
177	}
178
179	pub fn catalog(&self) -> &MaterializedCatalog {
180		match self {
181			StandardTransaction::Command(txn) => &txn.catalog,
182			StandardTransaction::Query(txn) => &txn.catalog,
183		}
184	}
185
186	pub fn version(&self) -> CommitVersion {
187		match self {
188			StandardTransaction::Command(txn) => MultiVersionQueryTransaction::version(*txn),
189			StandardTransaction::Query(txn) => MultiVersionQueryTransaction::version(*txn),
190		}
191	}
192}