Skip to main content

reifydb_transaction/interceptor/
filtered.rs

1// SPDX-License-Identifier: AGPL-3.0-or-later
2// Copyright (c) 2025 ReifyDB
3
4//! Filtered interceptor wrappers that only execute when the filter matches.
5//!
6//! These wrappers check the entity name against the filter before invoking the handler.
7//! Note: Namespace filtering requires namespace name resolution which is currently a TODO.
8
9use super::{
10	filter::InterceptFilter,
11	namespace_def::{
12		NamespaceDefPostCreateContext, NamespaceDefPostCreateInterceptor, NamespaceDefPostUpdateContext,
13		NamespaceDefPostUpdateInterceptor, NamespaceDefPreDeleteContext, NamespaceDefPreDeleteInterceptor,
14		NamespaceDefPreUpdateContext, NamespaceDefPreUpdateInterceptor,
15	},
16	ringbuffer::{
17		RingBufferPostDeleteContext, RingBufferPostDeleteInterceptor, RingBufferPostInsertContext,
18		RingBufferPostInsertInterceptor, RingBufferPostUpdateContext, RingBufferPostUpdateInterceptor,
19		RingBufferPreDeleteContext, RingBufferPreDeleteInterceptor, RingBufferPreInsertContext,
20		RingBufferPreInsertInterceptor, RingBufferPreUpdateContext, RingBufferPreUpdateInterceptor,
21	},
22	ringbuffer_def::{
23		RingBufferDefPostCreateContext, RingBufferDefPostCreateInterceptor, RingBufferDefPostUpdateContext,
24		RingBufferDefPostUpdateInterceptor, RingBufferDefPreDeleteContext, RingBufferDefPreDeleteInterceptor,
25		RingBufferDefPreUpdateContext, RingBufferDefPreUpdateInterceptor,
26	},
27	table::{
28		TablePostDeleteContext, TablePostDeleteInterceptor, TablePostInsertContext, TablePostInsertInterceptor,
29		TablePostUpdateContext, TablePostUpdateInterceptor, TablePreDeleteContext, TablePreDeleteInterceptor,
30		TablePreInsertContext, TablePreInsertInterceptor, TablePreUpdateContext, TablePreUpdateInterceptor,
31	},
32	table_def::{
33		TableDefPostCreateContext, TableDefPostCreateInterceptor, TableDefPostUpdateContext,
34		TableDefPostUpdateInterceptor, TableDefPreDeleteContext, TableDefPreDeleteInterceptor,
35		TableDefPreUpdateContext, TableDefPreUpdateInterceptor,
36	},
37	view::{
38		ViewPostDeleteContext, ViewPostDeleteInterceptor, ViewPostInsertContext, ViewPostInsertInterceptor,
39		ViewPostUpdateContext, ViewPostUpdateInterceptor, ViewPreDeleteContext, ViewPreDeleteInterceptor,
40		ViewPreInsertContext, ViewPreInsertInterceptor, ViewPreUpdateContext, ViewPreUpdateInterceptor,
41	},
42	view_def::{
43		ViewDefPostCreateContext, ViewDefPostCreateInterceptor, ViewDefPostUpdateContext,
44		ViewDefPostUpdateInterceptor, ViewDefPreDeleteContext, ViewDefPreDeleteInterceptor,
45		ViewDefPreUpdateContext, ViewDefPreUpdateInterceptor,
46	},
47};
48
49/// Macro to generate filtered interceptor wrapper types.
50macro_rules! define_filtered_interceptor {
51	(
52		$wrapper_name:ident,
53		$trait_name:ident,
54		$context_type:ident,
55		$entity_field:ident
56	) => {
57		/// Filtered interceptor wrapper that checks entity name before executing.
58		pub struct $wrapper_name<F>
59		where
60			F: for<'a> Fn(&mut $context_type<'a>) -> reifydb_type::Result<()> + Send + Sync,
61		{
62			filter: InterceptFilter,
63			handler: F,
64		}
65
66		impl<F> $wrapper_name<F>
67		where
68			F: for<'a> Fn(&mut $context_type<'a>) -> reifydb_type::Result<()> + Send + Sync,
69		{
70			/// Create a new filtered interceptor.
71			pub fn new(filter: InterceptFilter, handler: F) -> Self {
72				Self {
73					filter,
74					handler,
75				}
76			}
77		}
78
79		impl<F> Clone for $wrapper_name<F>
80		where
81			F: for<'a> Fn(&mut $context_type<'a>) -> reifydb_type::Result<()> + Send + Sync + Clone,
82		{
83			fn clone(&self) -> Self {
84				Self {
85					filter: self.filter.clone(),
86					handler: self.handler.clone(),
87				}
88			}
89		}
90
91		impl<F> $trait_name for $wrapper_name<F>
92		where
93			F: for<'a> Fn(&mut $context_type<'a>) -> reifydb_type::Result<()> + Send + Sync,
94		{
95			fn intercept<'a>(&self, ctx: &mut $context_type<'a>) -> reifydb_type::Result<()> {
96				// TODO: Add namespace matching once we have namespace name resolution.
97				// For now, we only match by entity name if namespace is not specified in filter,
98				// or skip namespace check entirely.
99				let entity_name = &ctx.$entity_field.name;
100
101				// Check if name matches (or filter allows all names)
102				let name_matches = self.filter.name.as_ref().map_or(true, |n| n == entity_name);
103
104				// TODO: Namespace matching - for now we skip namespace check if filter has namespace
105				// This means "ns.table" currently only matches by table name
106				let ns_matches = true; // Placeholder until we add namespace resolution
107
108				if name_matches && ns_matches {
109					(self.handler)(ctx)
110				} else {
111					Ok(())
112				}
113			}
114		}
115	};
116}
117
118// Table filtered interceptors
119define_filtered_interceptor!(
120	FilteredTablePreInsertInterceptor,
121	TablePreInsertInterceptor,
122	TablePreInsertContext,
123	table
124);
125
126define_filtered_interceptor!(
127	FilteredTablePostInsertInterceptor,
128	TablePostInsertInterceptor,
129	TablePostInsertContext,
130	table
131);
132
133define_filtered_interceptor!(
134	FilteredTablePreUpdateInterceptor,
135	TablePreUpdateInterceptor,
136	TablePreUpdateContext,
137	table
138);
139
140define_filtered_interceptor!(
141	FilteredTablePostUpdateInterceptor,
142	TablePostUpdateInterceptor,
143	TablePostUpdateContext,
144	table
145);
146
147define_filtered_interceptor!(
148	FilteredTablePreDeleteInterceptor,
149	TablePreDeleteInterceptor,
150	TablePreDeleteContext,
151	table
152);
153
154define_filtered_interceptor!(
155	FilteredTablePostDeleteInterceptor,
156	TablePostDeleteInterceptor,
157	TablePostDeleteContext,
158	table
159);
160
161// Ring buffer filtered interceptors
162define_filtered_interceptor!(
163	FilteredRingBufferPreInsertInterceptor,
164	RingBufferPreInsertInterceptor,
165	RingBufferPreInsertContext,
166	ringbuffer
167);
168
169define_filtered_interceptor!(
170	FilteredRingBufferPostInsertInterceptor,
171	RingBufferPostInsertInterceptor,
172	RingBufferPostInsertContext,
173	ringbuffer
174);
175
176define_filtered_interceptor!(
177	FilteredRingBufferPreUpdateInterceptor,
178	RingBufferPreUpdateInterceptor,
179	RingBufferPreUpdateContext,
180	ringbuffer
181);
182
183define_filtered_interceptor!(
184	FilteredRingBufferPostUpdateInterceptor,
185	RingBufferPostUpdateInterceptor,
186	RingBufferPostUpdateContext,
187	ringbuffer
188);
189
190define_filtered_interceptor!(
191	FilteredRingBufferPreDeleteInterceptor,
192	RingBufferPreDeleteInterceptor,
193	RingBufferPreDeleteContext,
194	ringbuffer
195);
196
197define_filtered_interceptor!(
198	FilteredRingBufferPostDeleteInterceptor,
199	RingBufferPostDeleteInterceptor,
200	RingBufferPostDeleteContext,
201	ringbuffer
202);
203
204// View data filtered interceptors
205define_filtered_interceptor!(FilteredViewPreInsertInterceptor, ViewPreInsertInterceptor, ViewPreInsertContext, view);
206
207define_filtered_interceptor!(FilteredViewPostInsertInterceptor, ViewPostInsertInterceptor, ViewPostInsertContext, view);
208
209define_filtered_interceptor!(FilteredViewPreUpdateInterceptor, ViewPreUpdateInterceptor, ViewPreUpdateContext, view);
210
211define_filtered_interceptor!(FilteredViewPostUpdateInterceptor, ViewPostUpdateInterceptor, ViewPostUpdateContext, view);
212
213define_filtered_interceptor!(FilteredViewPreDeleteInterceptor, ViewPreDeleteInterceptor, ViewPreDeleteContext, view);
214
215define_filtered_interceptor!(FilteredViewPostDeleteInterceptor, ViewPostDeleteInterceptor, ViewPostDeleteContext, view);
216
217// View definition filtered interceptors
218define_filtered_interceptor!(
219	FilteredViewDefPostCreateInterceptor,
220	ViewDefPostCreateInterceptor,
221	ViewDefPostCreateContext,
222	post
223);
224
225define_filtered_interceptor!(
226	FilteredViewDefPreUpdateInterceptor,
227	ViewDefPreUpdateInterceptor,
228	ViewDefPreUpdateContext,
229	pre
230);
231
232define_filtered_interceptor!(
233	FilteredViewDefPostUpdateInterceptor,
234	ViewDefPostUpdateInterceptor,
235	ViewDefPostUpdateContext,
236	pre
237);
238
239define_filtered_interceptor!(
240	FilteredViewDefPreDeleteInterceptor,
241	ViewDefPreDeleteInterceptor,
242	ViewDefPreDeleteContext,
243	pre
244);
245
246// Table definition filtered interceptors
247define_filtered_interceptor!(
248	FilteredTableDefPostCreateInterceptor,
249	TableDefPostCreateInterceptor,
250	TableDefPostCreateContext,
251	post
252);
253
254define_filtered_interceptor!(
255	FilteredTableDefPreUpdateInterceptor,
256	TableDefPreUpdateInterceptor,
257	TableDefPreUpdateContext,
258	pre
259);
260
261define_filtered_interceptor!(
262	FilteredTableDefPostUpdateInterceptor,
263	TableDefPostUpdateInterceptor,
264	TableDefPostUpdateContext,
265	pre
266);
267
268define_filtered_interceptor!(
269	FilteredTableDefPreDeleteInterceptor,
270	TableDefPreDeleteInterceptor,
271	TableDefPreDeleteContext,
272	pre
273);
274
275// Ring buffer definition filtered interceptors
276define_filtered_interceptor!(
277	FilteredRingBufferDefPostCreateInterceptor,
278	RingBufferDefPostCreateInterceptor,
279	RingBufferDefPostCreateContext,
280	post
281);
282
283define_filtered_interceptor!(
284	FilteredRingBufferDefPreUpdateInterceptor,
285	RingBufferDefPreUpdateInterceptor,
286	RingBufferDefPreUpdateContext,
287	pre
288);
289
290define_filtered_interceptor!(
291	FilteredRingBufferDefPostUpdateInterceptor,
292	RingBufferDefPostUpdateInterceptor,
293	RingBufferDefPostUpdateContext,
294	pre
295);
296
297define_filtered_interceptor!(
298	FilteredRingBufferDefPreDeleteInterceptor,
299	RingBufferDefPreDeleteInterceptor,
300	RingBufferDefPreDeleteContext,
301	pre
302);
303
304// Namespace definition filtered interceptors
305define_filtered_interceptor!(
306	FilteredNamespaceDefPostCreateInterceptor,
307	NamespaceDefPostCreateInterceptor,
308	NamespaceDefPostCreateContext,
309	post
310);
311
312define_filtered_interceptor!(
313	FilteredNamespaceDefPreUpdateInterceptor,
314	NamespaceDefPreUpdateInterceptor,
315	NamespaceDefPreUpdateContext,
316	pre
317);
318
319define_filtered_interceptor!(
320	FilteredNamespaceDefPostUpdateInterceptor,
321	NamespaceDefPostUpdateInterceptor,
322	NamespaceDefPostUpdateContext,
323	pre
324);
325
326define_filtered_interceptor!(
327	FilteredNamespaceDefPreDeleteInterceptor,
328	NamespaceDefPreDeleteInterceptor,
329	NamespaceDefPreDeleteContext,
330	pre
331);