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(
91		&mut self,
92		range: EncodedKeyRange,
93		batch_size: u64,
94	) -> crate::Result<BoxedMultiVersionIter<'_>> {
95		match self {
96			Self::Command(txn) => txn.range_batched(range, batch_size),
97			Self::Query(txn) => txn.range_batched(range, batch_size),
98		}
99	}
100
101	fn range_rev_batched(
102		&mut self,
103		range: EncodedKeyRange,
104		batch_size: u64,
105	) -> crate::Result<BoxedMultiVersionIter<'_>> {
106		match self {
107			Self::Command(txn) => txn.range_rev_batched(range, batch_size),
108			Self::Query(txn) => txn.range_rev_batched(range, batch_size),
109		}
110	}
111
112	fn prefix(&mut self, prefix: &EncodedKey) -> crate::Result<BoxedMultiVersionIter<'_>> {
113		match self {
114			Self::Command(txn) => txn.prefix(prefix),
115			Self::Query(txn) => txn.prefix(prefix),
116		}
117	}
118
119	fn prefix_rev(&mut self, prefix: &EncodedKey) -> crate::Result<BoxedMultiVersionIter<'_>> {
120		match self {
121			Self::Command(txn) => txn.prefix_rev(prefix),
122			Self::Query(txn) => txn.prefix_rev(prefix),
123		}
124	}
125
126	fn read_as_of_version_exclusive(&mut self, version: CommitVersion) -> reifydb_core::Result<()> {
127		match self {
128			StandardTransaction::Command(txn) => txn.read_as_of_version_inclusive(version),
129			StandardTransaction::Query(txn) => txn.read_as_of_version_exclusive(version),
130		}
131	}
132}
133
134impl<'a> From<&'a mut StandardCommandTransaction> for StandardTransaction<'a> {
135	fn from(txn: &'a mut StandardCommandTransaction) -> Self {
136		Self::Command(txn)
137	}
138}
139
140impl<'a> From<&'a mut StandardQueryTransaction> for StandardTransaction<'a> {
141	fn from(txn: &'a mut StandardQueryTransaction) -> Self {
142		Self::Query(txn)
143	}
144}
145
146impl<'a> StandardTransaction<'a> {
147	/// Extract the underlying StandardCommandTransaction, panics if this is
148	/// a Query transaction
149	pub fn command(self) -> &'a mut StandardCommandTransaction {
150		match self {
151			Self::Command(txn) => txn,
152			Self::Query(_) => panic!("Expected Command transaction but found Query transaction"),
153		}
154	}
155
156	/// Extract the underlying StandardQueryTransaction, panics if this is a
157	/// Command transaction
158	pub fn query(self) -> &'a mut StandardQueryTransaction {
159		match self {
160			Self::Query(txn) => txn,
161			Self::Command(_) => panic!("Expected Query transaction but found Command transaction"),
162		}
163	}
164
165	/// Get a mutable reference to the underlying
166	/// StandardCommandTransaction, panics if this is a Query transaction
167	pub fn command_mut(&mut self) -> &mut StandardCommandTransaction {
168		match self {
169			Self::Command(txn) => txn,
170			Self::Query(_) => panic!("Expected Command transaction but found Query transaction"),
171		}
172	}
173
174	/// Get a mutable reference to the underlying StandardQueryTransaction,
175	/// panics if this is a Command transaction
176	pub fn query_mut(&mut self) -> &mut StandardQueryTransaction {
177		match self {
178			Self::Query(txn) => txn,
179			Self::Command(_) => panic!("Expected Query transaction but found Command transaction"),
180		}
181	}
182
183	pub fn catalog(&self) -> &MaterializedCatalog {
184		match self {
185			StandardTransaction::Command(txn) => &txn.catalog,
186			StandardTransaction::Query(txn) => &txn.catalog,
187		}
188	}
189
190	pub fn version(&self) -> CommitVersion {
191		match self {
192			StandardTransaction::Command(txn) => MultiVersionQueryTransaction::version(*txn),
193			StandardTransaction::Query(txn) => MultiVersionQueryTransaction::version(*txn),
194		}
195	}
196}