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