reifydb_engine/transaction/
query.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 std::marker::PhantomData;
5
6use reifydb_catalog::{MaterializedCatalog, transaction::MaterializedCatalogTransaction};
7use reifydb_core::{
8	CommitVersion, EncodedKey, EncodedKeyRange,
9	interface::{
10		BoxedMultiVersionIter, CdcTransaction, MultiVersionQueryTransaction, MultiVersionTransaction,
11		MultiVersionValues, QueryTransaction, SingleVersionTransaction, TransactionId, TransactionalChanges,
12	},
13};
14use reifydb_transaction::{multi::TransactionMultiVersion, single::TransactionSingleVersion};
15
16use crate::transaction::TransactionCdc;
17
18/// An active query transaction that holds a multi query transaction
19/// and provides query-only access to single storage.
20pub struct StandardQueryTransaction {
21	pub(crate) multi: <TransactionMultiVersion as MultiVersionTransaction>::Query,
22	pub(crate) single: TransactionSingleVersion,
23	pub(crate) cdc: TransactionCdc,
24	pub(crate) catalog: MaterializedCatalog,
25	// Marker to prevent Send and Sync
26	_not_send_sync: PhantomData<*const ()>,
27}
28
29impl StandardQueryTransaction {
30	/// Creates a new active query transaction
31	pub fn new(
32		multi: <TransactionMultiVersion as MultiVersionTransaction>::Query,
33		single: TransactionSingleVersion,
34		cdc: TransactionCdc,
35		catalog: MaterializedCatalog,
36	) -> Self {
37		Self {
38			multi,
39			single,
40			cdc,
41			catalog,
42			_not_send_sync: PhantomData,
43		}
44	}
45
46	/// Execute a function with query access to the single transaction.
47	pub fn with_single_query<F, R>(&self, f: F) -> crate::Result<R>
48	where
49		F: FnOnce(&mut <TransactionSingleVersion as SingleVersionTransaction>::Query<'_>) -> crate::Result<R>,
50	{
51		self.single.with_query(f)
52	}
53
54	/// Execute a function with access to the multi query transaction.
55	/// This operates within the same transaction context.
56	pub fn with_multi_query<F, R>(&mut self, f: F) -> crate::Result<R>
57	where
58		F: FnOnce(&mut <TransactionMultiVersion as MultiVersionTransaction>::Query) -> crate::Result<R>,
59	{
60		f(&mut self.multi)
61	}
62
63	/// Get access to the CDC transaction interface
64	pub fn cdc(&self) -> &TransactionCdc {
65		&self.cdc
66	}
67}
68
69impl MultiVersionQueryTransaction for StandardQueryTransaction {
70	#[inline]
71	fn version(&self) -> CommitVersion {
72		self.multi.version()
73	}
74
75	#[inline]
76	fn id(&self) -> TransactionId {
77		self.multi.id()
78	}
79
80	#[inline]
81	fn get(&mut self, key: &EncodedKey) -> crate::Result<Option<MultiVersionValues>> {
82		self.multi.get(key)
83	}
84
85	#[inline]
86	fn contains_key(&mut self, key: &EncodedKey) -> crate::Result<bool> {
87		self.multi.contains_key(key)
88	}
89
90	#[inline]
91	fn range_batched(&mut self, range: EncodedKeyRange, batch_size: u64) -> crate::Result<BoxedMultiVersionIter> {
92		self.multi.range_batched(range, batch_size)
93	}
94
95	#[inline]
96	fn range_rev_batched(
97		&mut self,
98		range: EncodedKeyRange,
99		batch_size: u64,
100	) -> crate::Result<BoxedMultiVersionIter> {
101		self.multi.range_rev_batched(range, batch_size)
102	}
103
104	#[inline]
105	fn prefix(&mut self, prefix: &EncodedKey) -> crate::Result<BoxedMultiVersionIter> {
106		self.multi.prefix(prefix)
107	}
108
109	#[inline]
110	fn prefix_rev(&mut self, prefix: &EncodedKey) -> crate::Result<BoxedMultiVersionIter> {
111		self.multi.prefix_rev(prefix)
112	}
113
114	#[inline]
115	fn read_as_of_version_exclusive(&mut self, version: CommitVersion) -> crate::Result<()> {
116		self.multi.read_as_of_version_exclusive(version)
117	}
118}
119
120impl QueryTransaction for StandardQueryTransaction {
121	type SingleVersionQuery<'a> = <TransactionSingleVersion as SingleVersionTransaction>::Query<'a>;
122	type CdcQuery<'a>
123		= <TransactionCdc as CdcTransaction>::Query<'a>
124	where
125		Self: 'a;
126
127	fn begin_single_query(&self) -> crate::Result<Self::SingleVersionQuery<'_>> {
128		self.single.begin_query()
129	}
130
131	fn begin_cdc_query(&self) -> crate::Result<Self::CdcQuery<'_>> {
132		self.cdc.begin_query()
133	}
134}
135
136impl MaterializedCatalogTransaction for StandardQueryTransaction {
137	fn catalog(&self) -> &MaterializedCatalog {
138		&self.catalog
139	}
140}
141
142impl TransactionalChanges for StandardQueryTransaction {}