reifydb_transaction/transaction/catalog/
identity.rs1use reifydb_core::interface::catalog::{change::CatalogTrackIdentityChangeOperations, identity::Identity};
5use reifydb_value::{Result, value::identity::IdentityId};
6
7use crate::{
8 change::{
9 Change,
10 OperationType::{Create, Delete, Update},
11 TransactionalIdentityChanges,
12 },
13 interceptor::identity::{IdentityPostCreateContext, IdentityPreDeleteContext},
14 transaction::admin::AdminTransaction,
15};
16
17impl CatalogTrackIdentityChangeOperations for AdminTransaction {
18 fn track_identity_created(&mut self, identity: Identity) -> Result<()> {
19 self.interceptors.identity_post_create.execute(IdentityPostCreateContext::new(&identity))?;
20 let change = Change {
21 pre: None,
22 post: Some(identity),
23 op: Create,
24 };
25 self.changes.add_identity_change(change);
26 Ok(())
27 }
28
29 fn track_identity_updated(&mut self, pre: Identity, post: Identity) -> Result<()> {
30 let change = Change {
31 pre: Some(pre),
32 post: Some(post),
33 op: Update,
34 };
35 self.changes.add_identity_change(change);
36 Ok(())
37 }
38
39 fn track_identity_deleted(&mut self, identity: Identity) -> Result<()> {
40 self.interceptors.identity_pre_delete.execute(IdentityPreDeleteContext::new(&identity))?;
41 let change = Change {
42 pre: Some(identity),
43 post: None,
44 op: Delete,
45 };
46 self.changes.add_identity_change(change);
47 Ok(())
48 }
49}
50
51impl TransactionalIdentityChanges for AdminTransaction {
52 fn find_identity(&self, id: IdentityId) -> Option<&Identity> {
53 for change in self.changes.identity.iter().rev() {
54 if let Some(identity) = &change.post {
55 if identity.id == id {
56 return Some(identity);
57 }
58 } else if let Some(identity) = &change.pre
59 && identity.id == id && change.op == Delete
60 {
61 return None;
62 }
63 }
64 None
65 }
66
67 fn find_identity_by_name(&self, name: &str) -> Option<&Identity> {
68 self.changes.identity.iter().rev().find_map(|change| change.post.as_ref().filter(|u| u.name == name))
69 }
70
71 fn is_identity_deleted(&self, id: IdentityId) -> bool {
72 self.changes
73 .identity
74 .iter()
75 .rev()
76 .any(|change| change.op == Delete && change.pre.as_ref().map(|u| u.id) == Some(id))
77 }
78
79 fn is_identity_name_vacated(&self, name: &str) -> bool {
80 for change in self.changes.identity.iter().rev() {
81 if change.post.as_ref().is_some_and(|identity| identity.name == name) {
82 return false;
83 }
84 if change.pre.as_ref().is_some_and(|identity| identity.name == name) {
85 return true;
86 }
87 }
88 false
89 }
90}