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<'a, I, F, R>(&self, keys: I, f: F) -> crate::Result<R>
48	where
49		I: IntoIterator<Item = &'a EncodedKey>,
50		F: FnOnce(&mut <TransactionSingleVersion as SingleVersionTransaction>::Query<'_>) -> crate::Result<R>,
51	{
52		self.single.with_query(keys, f)
53	}
54
55	/// Execute a function with access to the multi query transaction.
56	/// This operates within the same transaction context.
57	pub fn with_multi_query<F, R>(&mut self, f: F) -> crate::Result<R>
58	where
59		F: FnOnce(&mut <TransactionMultiVersion as MultiVersionTransaction>::Query) -> crate::Result<R>,
60	{
61		f(&mut self.multi)
62	}
63
64	/// Get access to the CDC transaction interface
65	pub fn cdc(&self) -> &TransactionCdc {
66		&self.cdc
67	}
68}
69
70impl MultiVersionQueryTransaction for StandardQueryTransaction {
71	#[inline]
72	fn version(&self) -> CommitVersion {
73		self.multi.version()
74	}
75
76	#[inline]
77	fn id(&self) -> TransactionId {
78		self.multi.id()
79	}
80
81	#[inline]
82	fn get(&mut self, key: &EncodedKey) -> crate::Result<Option<MultiVersionValues>> {
83		self.multi.get(key)
84	}
85
86	#[inline]
87	fn contains_key(&mut self, key: &EncodedKey) -> crate::Result<bool> {
88		self.multi.contains_key(key)
89	}
90
91	#[inline]
92	fn range_batched(&mut self, range: EncodedKeyRange, batch_size: u64) -> crate::Result<BoxedMultiVersionIter> {
93		self.multi.range_batched(range, batch_size)
94	}
95
96	#[inline]
97	fn range_rev_batched(
98		&mut self,
99		range: EncodedKeyRange,
100		batch_size: u64,
101	) -> crate::Result<BoxedMultiVersionIter> {
102		self.multi.range_rev_batched(range, batch_size)
103	}
104
105	#[inline]
106	fn prefix(&mut self, prefix: &EncodedKey) -> crate::Result<BoxedMultiVersionIter> {
107		self.multi.prefix(prefix)
108	}
109
110	#[inline]
111	fn prefix_rev(&mut self, prefix: &EncodedKey) -> crate::Result<BoxedMultiVersionIter> {
112		self.multi.prefix_rev(prefix)
113	}
114
115	#[inline]
116	fn read_as_of_version_exclusive(&mut self, version: CommitVersion) -> crate::Result<()> {
117		self.multi.read_as_of_version_exclusive(version)
118	}
119}
120
121impl QueryTransaction for StandardQueryTransaction {
122	type SingleVersionQuery<'a> = <TransactionSingleVersion as SingleVersionTransaction>::Query<'a>;
123	type CdcQuery<'a>
124		= <TransactionCdc as CdcTransaction>::Query<'a>
125	where
126		Self: 'a;
127
128	fn begin_single_query<'a, I>(&self, keys: I) -> crate::Result<Self::SingleVersionQuery<'_>>
129	where
130		I: IntoIterator<Item = &'a EncodedKey>,
131	{
132		self.single.begin_query(keys)
133	}
134
135	fn begin_cdc_query(&self) -> crate::Result<Self::CdcQuery<'_>> {
136		self.cdc.begin_query()
137	}
138}
139
140impl MaterializedCatalogTransaction for StandardQueryTransaction {
141	fn catalog(&self) -> &MaterializedCatalog {
142		&self.catalog
143	}
144}
145
146impl TransactionalChanges for StandardQueryTransaction {}