1use std::{mem::take, sync::Arc};
5
6use reifydb_core::{
7 common::CommitVersion,
8 encoded::{
9 key::{EncodedKey, EncodedKeyRange},
10 row::EncodedRow,
11 },
12 event::EventBus,
13 execution::ExecutionResult,
14 interface::{
15 WithEventBus,
16 change::{Change, ChangeOrigin},
17 store::{MultiVersionBatch, MultiVersionRow},
18 },
19};
20use reifydb_runtime::context::clock::Clock;
21use reifydb_type::{
22 Result,
23 error::Diagnostic,
24 params::Params,
25 value::{datetime::DateTime, identity::IdentityId},
26};
27use tracing::instrument;
28
29use crate::{
30 TransactionId,
31 change::{RowChange, TransactionalCatalogChanges, TransactionalChanges},
32 change_accumulator::ChangeAccumulator,
33 error::TransactionError,
34 interceptor::{
35 WithInterceptors,
36 authentication::{AuthenticationPostCreateInterceptor, AuthenticationPreDeleteInterceptor},
37 chain::InterceptorChain as Chain,
38 dictionary::{
39 DictionaryPostCreateInterceptor, DictionaryPostUpdateInterceptor,
40 DictionaryPreDeleteInterceptor, DictionaryPreUpdateInterceptor,
41 },
42 dictionary_row::{
43 DictionaryRowPostDeleteInterceptor, DictionaryRowPostInsertInterceptor,
44 DictionaryRowPostUpdateInterceptor, DictionaryRowPreDeleteInterceptor,
45 DictionaryRowPreInsertInterceptor, DictionaryRowPreUpdateInterceptor,
46 },
47 granted_role::{GrantedRolePostCreateInterceptor, GrantedRolePreDeleteInterceptor},
48 identity::{
49 IdentityPostCreateInterceptor, IdentityPostUpdateInterceptor, IdentityPreDeleteInterceptor,
50 IdentityPreUpdateInterceptor,
51 },
52 interceptors::Interceptors,
53 namespace::{
54 NamespacePostCreateInterceptor, NamespacePostUpdateInterceptor, NamespacePreDeleteInterceptor,
55 NamespacePreUpdateInterceptor,
56 },
57 ringbuffer::{
58 RingBufferPostCreateInterceptor, RingBufferPostUpdateInterceptor,
59 RingBufferPreDeleteInterceptor, RingBufferPreUpdateInterceptor,
60 },
61 ringbuffer_row::{
62 RingBufferRowPostDeleteInterceptor, RingBufferRowPostInsertInterceptor,
63 RingBufferRowPostUpdateInterceptor, RingBufferRowPreDeleteInterceptor,
64 RingBufferRowPreInsertInterceptor, RingBufferRowPreUpdateInterceptor,
65 },
66 role::{
67 RolePostCreateInterceptor, RolePostUpdateInterceptor, RolePreDeleteInterceptor,
68 RolePreUpdateInterceptor,
69 },
70 series::{
71 SeriesPostCreateInterceptor, SeriesPostUpdateInterceptor, SeriesPreDeleteInterceptor,
72 SeriesPreUpdateInterceptor,
73 },
74 series_row::{
75 SeriesRowPostDeleteInterceptor, SeriesRowPostInsertInterceptor, SeriesRowPostUpdateInterceptor,
76 SeriesRowPreDeleteInterceptor, SeriesRowPreInsertInterceptor, SeriesRowPreUpdateInterceptor,
77 },
78 table::{
79 TablePostCreateInterceptor, TablePostUpdateInterceptor, TablePreDeleteInterceptor,
80 TablePreUpdateInterceptor,
81 },
82 table_row::{
83 TableRowPostDeleteInterceptor, TableRowPostInsertInterceptor, TableRowPostUpdateInterceptor,
84 TableRowPreDeleteInterceptor, TableRowPreInsertInterceptor, TableRowPreUpdateInterceptor,
85 },
86 transaction::{PostCommitContext, PostCommitInterceptor, PreCommitContext, PreCommitInterceptor},
87 view::{
88 ViewPostCreateInterceptor, ViewPostUpdateInterceptor, ViewPreDeleteInterceptor,
89 ViewPreUpdateInterceptor,
90 },
91 view_row::{
92 ViewRowPostDeleteInterceptor, ViewRowPostInsertInterceptor, ViewRowPostUpdateInterceptor,
93 ViewRowPreDeleteInterceptor, ViewRowPreInsertInterceptor, ViewRowPreUpdateInterceptor,
94 },
95 },
96 multi::{
97 pending::PendingWrites,
98 transaction::{MultiTransaction, write::MultiWriteTransaction},
99 },
100 single::{SingleTransaction, read::SingleReadTransaction, write::SingleWriteTransaction},
101 transaction::{
102 RqlExecutor, Transaction, apply_pre_commit_writes, collect_transaction_writes, query::QueryTransaction,
103 write::Write,
104 },
105};
106
107pub struct AdminTransaction {
108 pub multi: MultiTransaction,
109 pub single: SingleTransaction,
110 state: TransactionState,
111
112 pub cmd: Option<MultiWriteTransaction>,
113 pub event_bus: EventBus,
114 pub changes: TransactionalCatalogChanges,
115
116 pub(crate) row_changes: Vec<RowChange>,
117 pub interceptors: Interceptors,
118
119 pub(crate) accumulator: ChangeAccumulator,
120
121 pub identity: IdentityId,
122
123 pub(crate) executor: Option<Arc<dyn RqlExecutor>>,
124
125 pub(crate) clock: Clock,
126
127 poison_cause: Option<Diagnostic>,
128}
129
130#[derive(Clone, Copy, PartialEq)]
131enum TransactionState {
132 Active,
133 Committed,
134 RolledBack,
135 Poisoned,
136}
137
138impl AdminTransaction {
139 #[instrument(name = "transaction::admin::new", level = "debug", skip_all)]
140 pub fn new(
141 multi: MultiTransaction,
142 single: SingleTransaction,
143 event_bus: EventBus,
144 interceptors: Interceptors,
145 identity: IdentityId,
146 clock: Clock,
147 ) -> Result<Self> {
148 let cmd = multi.begin_command()?;
149 let txn_id = cmd.id();
150 Ok(Self {
151 cmd: Some(cmd),
152 multi,
153 single,
154 state: TransactionState::Active,
155 event_bus,
156 interceptors,
157 changes: TransactionalCatalogChanges::new(txn_id),
158 row_changes: Vec::new(),
159 accumulator: ChangeAccumulator::new(),
160 identity,
161 executor: None,
162 clock,
163 poison_cause: None,
164 })
165 }
166
167 pub fn set_executor(&mut self, executor: Arc<dyn RqlExecutor>) {
168 self.executor = Some(executor);
169 }
170
171 pub fn rql(&mut self, rql: &str, params: Params) -> ExecutionResult {
172 if let Err(e) = self.check_active() {
173 return ExecutionResult {
174 frames: vec![],
175 error: Some(e),
176 metrics: Default::default(),
177 };
178 }
179 let executor = self.executor.clone().expect("RqlExecutor not set");
180 let result = executor.rql(&mut Transaction::Admin(self), rql, params);
181 if let Some(ref e) = result.error {
182 self.poison(*e.0.clone());
183 }
184 result
185 }
186
187 #[instrument(name = "transaction::admin::event_bus", level = "trace", skip(self))]
188 pub fn event_bus(&self) -> &EventBus {
189 &self.event_bus
190 }
191
192 pub(crate) fn check_active(&self) -> Result<()> {
193 match self.state {
194 TransactionState::Active => Ok(()),
195 TransactionState::Committed => Err(TransactionError::AlreadyCommitted.into()),
196 TransactionState::RolledBack => Err(TransactionError::AlreadyRolledBack.into()),
197 TransactionState::Poisoned => Err(TransactionError::Poisoned {
198 cause: Box::new(self.poison_cause.clone().unwrap()),
199 }
200 .into()),
201 }
202 }
203
204 pub(crate) fn poison(&mut self, cause: Diagnostic) {
205 self.state = TransactionState::Poisoned;
206 self.poison_cause = Some(cause);
207 }
208
209 pub(crate) fn unpoison(&mut self) {
210 self.state = TransactionState::Active;
211 self.poison_cause = None;
212 }
213
214 #[instrument(name = "transaction::admin::commit", level = "debug", skip(self))]
215 pub fn commit(&mut self) -> Result<CommitVersion> {
216 self.check_active()?;
217 let mut ctx = self.build_pre_commit_context()?;
218 self.interceptors.pre_commit.execute(&mut ctx)?;
219 self.finalize_commit(ctx)
220 }
221
222 #[inline]
223 fn build_pre_commit_context(&mut self) -> Result<PreCommitContext> {
224 let transaction_writes = collect_transaction_writes(self.pending_writes());
225 Ok(PreCommitContext {
226 flow_changes: self
227 .accumulator
228 .take_changes(CommitVersion(0), DateTime::from_nanos(self.clock.now_nanos()))?,
229 pending_writes: Vec::new(),
230 pending_shapes: Vec::new(),
231 transaction_writes,
232 view_entries: Vec::new(),
233 })
234 }
235
236 fn finalize_commit(&mut self, ctx: PreCommitContext) -> Result<CommitVersion> {
237 let Some(mut multi) = self.cmd.take() else {
238 unreachable!("Transaction state inconsistency")
239 };
240 apply_pre_commit_writes(&mut multi, &ctx.pending_writes)?;
241 let id = multi.id();
242 self.state = TransactionState::Committed;
243
244 let changes = take(&mut self.changes);
245 let row_changes = take(&mut self.row_changes);
246 let version = multi.commit()?;
247 self.interceptors.post_commit.execute(PostCommitContext::new(id, version, changes, row_changes))?;
248 Ok(version)
249 }
250
251 #[instrument(name = "transaction::admin::rollback", level = "debug", skip(self))]
252 pub fn rollback(&mut self) -> Result<()> {
253 self.check_active()?;
254 if let Some(mut multi) = self.cmd.take() {
255 self.state = TransactionState::RolledBack;
256 multi.rollback()
257 } else {
258 unreachable!("Transaction state inconsistency")
259 }
260 }
261
262 #[instrument(name = "transaction::admin::pending_writes", level = "trace", skip(self))]
263 pub fn pending_writes(&self) -> &PendingWrites {
264 self.cmd.as_ref().unwrap().pending_writes()
265 }
266
267 #[instrument(name = "transaction::admin::with_single_query", level = "trace", skip(self, keys, f))]
268 pub fn with_single_query<'a, I, F, R>(&self, keys: I, f: F) -> Result<R>
269 where
270 I: IntoIterator<Item = &'a EncodedKey> + Send,
271 F: FnOnce(&mut SingleReadTransaction<'_>) -> Result<R> + Send,
272 R: Send,
273 {
274 self.check_active()?;
275 self.single.with_query(keys, f)
276 }
277
278 #[instrument(name = "transaction::admin::with_single_command", level = "trace", skip(self, keys, f))]
279 pub fn with_single_command<'a, I, F, R>(&self, keys: I, f: F) -> Result<R>
280 where
281 I: IntoIterator<Item = &'a EncodedKey> + Send,
282 F: FnOnce(&mut SingleWriteTransaction<'_>) -> Result<R> + Send,
283 R: Send,
284 {
285 self.check_active()?;
286 self.single.with_command(keys, f)
287 }
288
289 #[instrument(name = "transaction::admin::with_multi_query", level = "trace", skip(self, f))]
290 pub fn with_multi_query<F, R>(&self, f: F) -> Result<R>
291 where
292 F: FnOnce(&mut QueryTransaction) -> Result<R>,
293 {
294 self.check_active()?;
295
296 let mut query_txn =
297 QueryTransaction::new(self.multi.begin_query()?, self.single.clone(), self.identity);
298
299 f(&mut query_txn)
300 }
301
302 #[instrument(name = "transaction::admin::with_multi_query_as_of_exclusive", level = "trace", skip(self, f))]
303 pub fn with_multi_query_as_of_exclusive<F, R>(&self, version: CommitVersion, f: F) -> Result<R>
304 where
305 F: FnOnce(&mut QueryTransaction) -> Result<R>,
306 {
307 self.check_active()?;
308
309 let mut query_txn =
310 QueryTransaction::new(self.multi.begin_query()?, self.single.clone(), self.identity);
311
312 query_txn.read_as_of_version_exclusive(version)?;
313
314 f(&mut query_txn)
315 }
316
317 #[instrument(name = "transaction::admin::with_multi_query_as_of_inclusive", level = "trace", skip(self, f))]
318 pub fn with_multi_query_as_of_inclusive<F, R>(&self, version: CommitVersion, f: F) -> Result<R>
319 where
320 F: FnOnce(&mut QueryTransaction) -> Result<R>,
321 {
322 self.check_active()?;
323
324 let mut query_txn =
325 QueryTransaction::new(self.multi.begin_query()?, self.single.clone(), self.identity);
326
327 query_txn.multi.read_as_of_version_inclusive(version);
328
329 f(&mut query_txn)
330 }
331
332 #[instrument(name = "transaction::admin::begin_single_query", level = "trace", skip(self, keys))]
333 pub fn begin_single_query<'a, I>(&self, keys: I) -> Result<SingleReadTransaction<'_>>
334 where
335 I: IntoIterator<Item = &'a EncodedKey>,
336 {
337 self.check_active()?;
338 self.single.begin_query(keys)
339 }
340
341 #[instrument(name = "transaction::admin::begin_single_command", level = "trace", skip(self, keys))]
342 pub fn begin_single_command<'a, I>(&self, keys: I) -> Result<SingleWriteTransaction<'_>>
343 where
344 I: IntoIterator<Item = &'a EncodedKey>,
345 {
346 self.check_active()?;
347 self.single.begin_command(keys)
348 }
349
350 pub fn get_changes(&self) -> &TransactionalCatalogChanges {
351 &self.changes
352 }
353
354 pub fn track_row_change(&mut self, changes: &[RowChange]) {
355 self.row_changes.extend_from_slice(changes);
356 }
357
358 pub fn track_flow_change(&mut self, change: Change) {
359 if let ChangeOrigin::Shape(id) = change.origin {
360 for diff in change.diffs {
361 self.accumulator.track(id, diff);
362 }
363 }
364 }
365
366 #[inline]
367 pub fn version(&self) -> CommitVersion {
368 self.cmd.as_ref().unwrap().version()
369 }
370
371 #[inline]
372 pub fn id(&self) -> TransactionId {
373 self.cmd.as_ref().unwrap().id()
374 }
375
376 #[inline]
377 pub fn get(&mut self, key: &EncodedKey) -> Result<Option<MultiVersionRow>> {
378 self.check_active()?;
379 Ok(self.cmd.as_mut().unwrap().get(key)?.map(|v| v.into_multi_version_row()))
380 }
381
382 #[inline]
383 pub fn get_committed(&mut self, key: &EncodedKey) -> Result<Option<MultiVersionRow>> {
384 self.check_active()?;
385 Ok(self.cmd.as_mut().unwrap().get_committed(key)?.map(|v| v.into_multi_version_row()))
386 }
387
388 #[inline]
389 pub fn contains_key(&mut self, key: &EncodedKey) -> Result<bool> {
390 self.check_active()?;
391 self.cmd.as_mut().unwrap().contains_key(key)
392 }
393
394 #[inline]
395 pub fn prefix(&mut self, prefix: &EncodedKey) -> Result<MultiVersionBatch> {
396 self.check_active()?;
397 self.cmd.as_mut().unwrap().prefix(prefix)
398 }
399
400 #[inline]
401 pub fn prefix_rev(&mut self, prefix: &EncodedKey) -> Result<MultiVersionBatch> {
402 self.check_active()?;
403 self.cmd.as_mut().unwrap().prefix_rev(prefix)
404 }
405
406 #[inline]
407 pub fn read_as_of_version_exclusive(&mut self, version: CommitVersion) -> Result<()> {
408 self.check_active()?;
409 self.cmd.as_mut().unwrap().read_as_of_version_exclusive(version);
410 Ok(())
411 }
412
413 #[inline]
414 pub fn set(&mut self, key: &EncodedKey, row: EncodedRow) -> Result<()> {
415 self.check_active()?;
416 self.cmd.as_mut().unwrap().set(key, row)
417 }
418
419 #[inline]
420 pub fn unset(&mut self, key: &EncodedKey, row: EncodedRow) -> Result<()> {
421 self.check_active()?;
422 self.cmd.as_mut().unwrap().unset(key, row)
423 }
424
425 #[inline]
426 pub fn remove(&mut self, key: &EncodedKey) -> Result<()> {
427 self.check_active()?;
428 self.cmd.as_mut().unwrap().remove(key)
429 }
430
431 #[inline]
432 pub fn mark_preexisting(&mut self, key: &EncodedKey) -> Result<()> {
433 self.check_active()?;
434 self.cmd.as_mut().unwrap().mark_preexisting(key);
435 Ok(())
436 }
437
438 #[inline]
439 pub fn range(
440 &mut self,
441 range: EncodedKeyRange,
442 batch_size: usize,
443 ) -> Result<Box<dyn Iterator<Item = Result<MultiVersionRow>> + Send + '_>> {
444 self.check_active()?;
445 Ok(self.cmd.as_mut().unwrap().range(range, batch_size))
446 }
447
448 #[inline]
449 pub fn range_rev(
450 &mut self,
451 range: EncodedKeyRange,
452 batch_size: usize,
453 ) -> Result<Box<dyn Iterator<Item = Result<MultiVersionRow>> + Send + '_>> {
454 self.check_active()?;
455 Ok(self.cmd.as_mut().unwrap().range_rev(range, batch_size))
456 }
457}
458
459impl WithEventBus for AdminTransaction {
460 fn event_bus(&self) -> &EventBus {
461 &self.event_bus
462 }
463}
464
465impl Write for AdminTransaction {
466 #[inline]
467 fn set(&mut self, key: &EncodedKey, row: EncodedRow) -> Result<()> {
468 AdminTransaction::set(self, key, row)
469 }
470 #[inline]
471 fn unset(&mut self, key: &EncodedKey, row: EncodedRow) -> Result<()> {
472 AdminTransaction::unset(self, key, row)
473 }
474 #[inline]
475 fn remove(&mut self, key: &EncodedKey) -> Result<()> {
476 AdminTransaction::remove(self, key)
477 }
478 #[inline]
479 fn mark_preexisting(&mut self, key: &EncodedKey) -> Result<()> {
480 AdminTransaction::mark_preexisting(self, key)
481 }
482 #[inline]
483 fn track_row_change(&mut self, changes: &[RowChange]) {
484 AdminTransaction::track_row_change(self, changes)
485 }
486 #[inline]
487 fn track_flow_change(&mut self, change: Change) {
488 AdminTransaction::track_flow_change(self, change)
489 }
490}
491
492impl WithInterceptors for AdminTransaction {
493 fn table_row_pre_insert_interceptors(&mut self) -> &mut Chain<dyn TableRowPreInsertInterceptor + Send + Sync> {
494 &mut self.interceptors.table_row_pre_insert
495 }
496
497 fn table_row_post_insert_interceptors(
498 &mut self,
499 ) -> &mut Chain<dyn TableRowPostInsertInterceptor + Send + Sync> {
500 &mut self.interceptors.table_row_post_insert
501 }
502
503 fn table_row_pre_update_interceptors(&mut self) -> &mut Chain<dyn TableRowPreUpdateInterceptor + Send + Sync> {
504 &mut self.interceptors.table_row_pre_update
505 }
506
507 fn table_row_post_update_interceptors(
508 &mut self,
509 ) -> &mut Chain<dyn TableRowPostUpdateInterceptor + Send + Sync> {
510 &mut self.interceptors.table_row_post_update
511 }
512
513 fn table_row_pre_delete_interceptors(&mut self) -> &mut Chain<dyn TableRowPreDeleteInterceptor + Send + Sync> {
514 &mut self.interceptors.table_row_pre_delete
515 }
516
517 fn table_row_post_delete_interceptors(
518 &mut self,
519 ) -> &mut Chain<dyn TableRowPostDeleteInterceptor + Send + Sync> {
520 &mut self.interceptors.table_row_post_delete
521 }
522
523 fn ringbuffer_row_pre_insert_interceptors(
524 &mut self,
525 ) -> &mut Chain<dyn RingBufferRowPreInsertInterceptor + Send + Sync> {
526 &mut self.interceptors.ringbuffer_row_pre_insert
527 }
528
529 fn ringbuffer_row_post_insert_interceptors(
530 &mut self,
531 ) -> &mut Chain<dyn RingBufferRowPostInsertInterceptor + Send + Sync> {
532 &mut self.interceptors.ringbuffer_row_post_insert
533 }
534
535 fn ringbuffer_row_pre_update_interceptors(
536 &mut self,
537 ) -> &mut Chain<dyn RingBufferRowPreUpdateInterceptor + Send + Sync> {
538 &mut self.interceptors.ringbuffer_row_pre_update
539 }
540
541 fn ringbuffer_row_post_update_interceptors(
542 &mut self,
543 ) -> &mut Chain<dyn RingBufferRowPostUpdateInterceptor + Send + Sync> {
544 &mut self.interceptors.ringbuffer_row_post_update
545 }
546
547 fn ringbuffer_row_pre_delete_interceptors(
548 &mut self,
549 ) -> &mut Chain<dyn RingBufferRowPreDeleteInterceptor + Send + Sync> {
550 &mut self.interceptors.ringbuffer_row_pre_delete
551 }
552
553 fn ringbuffer_row_post_delete_interceptors(
554 &mut self,
555 ) -> &mut Chain<dyn RingBufferRowPostDeleteInterceptor + Send + Sync> {
556 &mut self.interceptors.ringbuffer_row_post_delete
557 }
558
559 fn pre_commit_interceptors(&mut self) -> &mut Chain<dyn PreCommitInterceptor + Send + Sync> {
560 &mut self.interceptors.pre_commit
561 }
562
563 fn post_commit_interceptors(&mut self) -> &mut Chain<dyn PostCommitInterceptor + Send + Sync> {
564 &mut self.interceptors.post_commit
565 }
566
567 fn namespace_post_create_interceptors(
568 &mut self,
569 ) -> &mut Chain<dyn NamespacePostCreateInterceptor + Send + Sync> {
570 &mut self.interceptors.namespace_post_create
571 }
572
573 fn namespace_pre_update_interceptors(&mut self) -> &mut Chain<dyn NamespacePreUpdateInterceptor + Send + Sync> {
574 &mut self.interceptors.namespace_pre_update
575 }
576
577 fn namespace_post_update_interceptors(
578 &mut self,
579 ) -> &mut Chain<dyn NamespacePostUpdateInterceptor + Send + Sync> {
580 &mut self.interceptors.namespace_post_update
581 }
582
583 fn namespace_pre_delete_interceptors(&mut self) -> &mut Chain<dyn NamespacePreDeleteInterceptor + Send + Sync> {
584 &mut self.interceptors.namespace_pre_delete
585 }
586
587 fn table_post_create_interceptors(&mut self) -> &mut Chain<dyn TablePostCreateInterceptor + Send + Sync> {
588 &mut self.interceptors.table_post_create
589 }
590
591 fn table_pre_update_interceptors(&mut self) -> &mut Chain<dyn TablePreUpdateInterceptor + Send + Sync> {
592 &mut self.interceptors.table_pre_update
593 }
594
595 fn table_post_update_interceptors(&mut self) -> &mut Chain<dyn TablePostUpdateInterceptor + Send + Sync> {
596 &mut self.interceptors.table_post_update
597 }
598
599 fn table_pre_delete_interceptors(&mut self) -> &mut Chain<dyn TablePreDeleteInterceptor + Send + Sync> {
600 &mut self.interceptors.table_pre_delete
601 }
602
603 fn view_row_pre_insert_interceptors(&mut self) -> &mut Chain<dyn ViewRowPreInsertInterceptor + Send + Sync> {
604 &mut self.interceptors.view_row_pre_insert
605 }
606
607 fn view_row_post_insert_interceptors(&mut self) -> &mut Chain<dyn ViewRowPostInsertInterceptor + Send + Sync> {
608 &mut self.interceptors.view_row_post_insert
609 }
610
611 fn view_row_pre_update_interceptors(&mut self) -> &mut Chain<dyn ViewRowPreUpdateInterceptor + Send + Sync> {
612 &mut self.interceptors.view_row_pre_update
613 }
614
615 fn view_row_post_update_interceptors(&mut self) -> &mut Chain<dyn ViewRowPostUpdateInterceptor + Send + Sync> {
616 &mut self.interceptors.view_row_post_update
617 }
618
619 fn view_row_pre_delete_interceptors(&mut self) -> &mut Chain<dyn ViewRowPreDeleteInterceptor + Send + Sync> {
620 &mut self.interceptors.view_row_pre_delete
621 }
622
623 fn view_row_post_delete_interceptors(&mut self) -> &mut Chain<dyn ViewRowPostDeleteInterceptor + Send + Sync> {
624 &mut self.interceptors.view_row_post_delete
625 }
626
627 fn view_post_create_interceptors(&mut self) -> &mut Chain<dyn ViewPostCreateInterceptor + Send + Sync> {
628 &mut self.interceptors.view_post_create
629 }
630
631 fn view_pre_update_interceptors(&mut self) -> &mut Chain<dyn ViewPreUpdateInterceptor + Send + Sync> {
632 &mut self.interceptors.view_pre_update
633 }
634
635 fn view_post_update_interceptors(&mut self) -> &mut Chain<dyn ViewPostUpdateInterceptor + Send + Sync> {
636 &mut self.interceptors.view_post_update
637 }
638
639 fn view_pre_delete_interceptors(&mut self) -> &mut Chain<dyn ViewPreDeleteInterceptor + Send + Sync> {
640 &mut self.interceptors.view_pre_delete
641 }
642
643 fn ringbuffer_post_create_interceptors(
644 &mut self,
645 ) -> &mut Chain<dyn RingBufferPostCreateInterceptor + Send + Sync> {
646 &mut self.interceptors.ringbuffer_post_create
647 }
648
649 fn ringbuffer_pre_update_interceptors(
650 &mut self,
651 ) -> &mut Chain<dyn RingBufferPreUpdateInterceptor + Send + Sync> {
652 &mut self.interceptors.ringbuffer_pre_update
653 }
654
655 fn ringbuffer_post_update_interceptors(
656 &mut self,
657 ) -> &mut Chain<dyn RingBufferPostUpdateInterceptor + Send + Sync> {
658 &mut self.interceptors.ringbuffer_post_update
659 }
660
661 fn ringbuffer_pre_delete_interceptors(
662 &mut self,
663 ) -> &mut Chain<dyn RingBufferPreDeleteInterceptor + Send + Sync> {
664 &mut self.interceptors.ringbuffer_pre_delete
665 }
666
667 fn dictionary_row_pre_insert_interceptors(
668 &mut self,
669 ) -> &mut Chain<dyn DictionaryRowPreInsertInterceptor + Send + Sync> {
670 &mut self.interceptors.dictionary_row_pre_insert
671 }
672
673 fn dictionary_row_post_insert_interceptors(
674 &mut self,
675 ) -> &mut Chain<dyn DictionaryRowPostInsertInterceptor + Send + Sync> {
676 &mut self.interceptors.dictionary_row_post_insert
677 }
678
679 fn dictionary_row_pre_update_interceptors(
680 &mut self,
681 ) -> &mut Chain<dyn DictionaryRowPreUpdateInterceptor + Send + Sync> {
682 &mut self.interceptors.dictionary_row_pre_update
683 }
684
685 fn dictionary_row_post_update_interceptors(
686 &mut self,
687 ) -> &mut Chain<dyn DictionaryRowPostUpdateInterceptor + Send + Sync> {
688 &mut self.interceptors.dictionary_row_post_update
689 }
690
691 fn dictionary_row_pre_delete_interceptors(
692 &mut self,
693 ) -> &mut Chain<dyn DictionaryRowPreDeleteInterceptor + Send + Sync> {
694 &mut self.interceptors.dictionary_row_pre_delete
695 }
696
697 fn dictionary_row_post_delete_interceptors(
698 &mut self,
699 ) -> &mut Chain<dyn DictionaryRowPostDeleteInterceptor + Send + Sync> {
700 &mut self.interceptors.dictionary_row_post_delete
701 }
702
703 fn dictionary_post_create_interceptors(
704 &mut self,
705 ) -> &mut Chain<dyn DictionaryPostCreateInterceptor + Send + Sync> {
706 &mut self.interceptors.dictionary_post_create
707 }
708
709 fn dictionary_pre_update_interceptors(
710 &mut self,
711 ) -> &mut Chain<dyn DictionaryPreUpdateInterceptor + Send + Sync> {
712 &mut self.interceptors.dictionary_pre_update
713 }
714
715 fn dictionary_post_update_interceptors(
716 &mut self,
717 ) -> &mut Chain<dyn DictionaryPostUpdateInterceptor + Send + Sync> {
718 &mut self.interceptors.dictionary_post_update
719 }
720
721 fn dictionary_pre_delete_interceptors(
722 &mut self,
723 ) -> &mut Chain<dyn DictionaryPreDeleteInterceptor + Send + Sync> {
724 &mut self.interceptors.dictionary_pre_delete
725 }
726
727 fn series_row_pre_insert_interceptors(
728 &mut self,
729 ) -> &mut Chain<dyn SeriesRowPreInsertInterceptor + Send + Sync> {
730 &mut self.interceptors.series_row_pre_insert
731 }
732
733 fn series_row_post_insert_interceptors(
734 &mut self,
735 ) -> &mut Chain<dyn SeriesRowPostInsertInterceptor + Send + Sync> {
736 &mut self.interceptors.series_row_post_insert
737 }
738
739 fn series_row_pre_update_interceptors(
740 &mut self,
741 ) -> &mut Chain<dyn SeriesRowPreUpdateInterceptor + Send + Sync> {
742 &mut self.interceptors.series_row_pre_update
743 }
744
745 fn series_row_post_update_interceptors(
746 &mut self,
747 ) -> &mut Chain<dyn SeriesRowPostUpdateInterceptor + Send + Sync> {
748 &mut self.interceptors.series_row_post_update
749 }
750
751 fn series_row_pre_delete_interceptors(
752 &mut self,
753 ) -> &mut Chain<dyn SeriesRowPreDeleteInterceptor + Send + Sync> {
754 &mut self.interceptors.series_row_pre_delete
755 }
756
757 fn series_row_post_delete_interceptors(
758 &mut self,
759 ) -> &mut Chain<dyn SeriesRowPostDeleteInterceptor + Send + Sync> {
760 &mut self.interceptors.series_row_post_delete
761 }
762
763 fn series_post_create_interceptors(&mut self) -> &mut Chain<dyn SeriesPostCreateInterceptor + Send + Sync> {
764 &mut self.interceptors.series_post_create
765 }
766
767 fn series_pre_update_interceptors(&mut self) -> &mut Chain<dyn SeriesPreUpdateInterceptor + Send + Sync> {
768 &mut self.interceptors.series_pre_update
769 }
770
771 fn series_post_update_interceptors(&mut self) -> &mut Chain<dyn SeriesPostUpdateInterceptor + Send + Sync> {
772 &mut self.interceptors.series_post_update
773 }
774
775 fn series_pre_delete_interceptors(&mut self) -> &mut Chain<dyn SeriesPreDeleteInterceptor + Send + Sync> {
776 &mut self.interceptors.series_pre_delete
777 }
778
779 fn identity_post_create_interceptors(&mut self) -> &mut Chain<dyn IdentityPostCreateInterceptor + Send + Sync> {
780 &mut self.interceptors.identity_post_create
781 }
782
783 fn identity_pre_update_interceptors(&mut self) -> &mut Chain<dyn IdentityPreUpdateInterceptor + Send + Sync> {
784 &mut self.interceptors.identity_pre_update
785 }
786
787 fn identity_post_update_interceptors(&mut self) -> &mut Chain<dyn IdentityPostUpdateInterceptor + Send + Sync> {
788 &mut self.interceptors.identity_post_update
789 }
790
791 fn identity_pre_delete_interceptors(&mut self) -> &mut Chain<dyn IdentityPreDeleteInterceptor + Send + Sync> {
792 &mut self.interceptors.identity_pre_delete
793 }
794
795 fn role_post_create_interceptors(&mut self) -> &mut Chain<dyn RolePostCreateInterceptor + Send + Sync> {
796 &mut self.interceptors.role_post_create
797 }
798
799 fn role_pre_update_interceptors(&mut self) -> &mut Chain<dyn RolePreUpdateInterceptor + Send + Sync> {
800 &mut self.interceptors.role_pre_update
801 }
802
803 fn role_post_update_interceptors(&mut self) -> &mut Chain<dyn RolePostUpdateInterceptor + Send + Sync> {
804 &mut self.interceptors.role_post_update
805 }
806
807 fn role_pre_delete_interceptors(&mut self) -> &mut Chain<dyn RolePreDeleteInterceptor + Send + Sync> {
808 &mut self.interceptors.role_pre_delete
809 }
810
811 fn granted_role_post_create_interceptors(
812 &mut self,
813 ) -> &mut Chain<dyn GrantedRolePostCreateInterceptor + Send + Sync> {
814 &mut self.interceptors.granted_role_post_create
815 }
816
817 fn granted_role_pre_delete_interceptors(
818 &mut self,
819 ) -> &mut Chain<dyn GrantedRolePreDeleteInterceptor + Send + Sync> {
820 &mut self.interceptors.granted_role_pre_delete
821 }
822
823 fn authentication_post_create_interceptors(
824 &mut self,
825 ) -> &mut Chain<dyn AuthenticationPostCreateInterceptor + Send + Sync> {
826 &mut self.interceptors.authentication_post_create
827 }
828
829 fn authentication_pre_delete_interceptors(
830 &mut self,
831 ) -> &mut Chain<dyn AuthenticationPreDeleteInterceptor + Send + Sync> {
832 &mut self.interceptors.authentication_pre_delete
833 }
834}
835
836impl TransactionalChanges for AdminTransaction {}
837
838impl Drop for AdminTransaction {
839 fn drop(&mut self) {
840 if let Some(mut multi) = self.cmd.take()
841 && (self.state == TransactionState::Active || self.state == TransactionState::Poisoned)
842 {
843 let _ = multi.rollback();
844 }
845 }
846}