Skip to main content

reifydb_transaction/transaction/catalog/
identity.rs

1// SPDX-License-Identifier: Apache-2.0
2// Copyright (c) 2026 ReifyDB
3
4use 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}