reifydb_catalog/store/namespace/
create.rs

1// Copyright (c) reifydb.com 2025
2// This file is licensed under the AGPL-3.0-or-later, see license.md file
3
4use reifydb_core::interface::{CommandTransaction, NamespaceDef, NamespaceKey};
5use reifydb_type::{Fragment, diagnostic::catalog::namespace_already_exists, return_error};
6
7use crate::{
8	CatalogStore,
9	store::{
10		namespace::layout::namespace::{ID, LAYOUT, NAME},
11		sequence::SystemSequence,
12	},
13};
14
15#[derive(Debug, Clone)]
16pub struct NamespaceToCreate {
17	pub namespace_fragment: Option<Fragment>,
18	pub name: String,
19}
20
21impl CatalogStore {
22	pub async fn create_namespace(
23		txn: &mut impl CommandTransaction,
24		to_create: NamespaceToCreate,
25	) -> crate::Result<NamespaceDef> {
26		if let Some(namespace) = Self::find_namespace_by_name(txn, &to_create.name).await? {
27			return_error!(namespace_already_exists(
28				to_create.namespace_fragment.unwrap_or_else(|| Fragment::None),
29				&namespace.name
30			));
31		}
32
33		let namespace_id = SystemSequence::next_namespace_id(txn).await?;
34
35		let mut row = LAYOUT.allocate();
36		LAYOUT.set_u64(&mut row, ID, namespace_id);
37		LAYOUT.set_utf8(&mut row, NAME, &to_create.name);
38
39		txn.set(&NamespaceKey::encoded(namespace_id), row).await?;
40
41		Ok(Self::get_namespace(txn, namespace_id).await?)
42	}
43}
44
45#[cfg(test)]
46mod tests {
47	use reifydb_core::interface::NamespaceId;
48	use reifydb_engine::test_utils::create_test_command_transaction;
49
50	use crate::{CatalogStore, store::namespace::create::NamespaceToCreate};
51
52	#[tokio::test]
53	async fn test_create_namespace() {
54		let mut txn = create_test_command_transaction().await;
55
56		let to_create = NamespaceToCreate {
57			namespace_fragment: None,
58			name: "test_namespace".to_string(),
59		};
60
61		// First creation should succeed
62		let result = CatalogStore::create_namespace(&mut txn, to_create.clone()).await.unwrap();
63		assert_eq!(result.id, NamespaceId(1025));
64		assert_eq!(result.name, "test_namespace");
65
66		// Creating the same namespace again with `if_not_exists =
67		// false` should return error
68		let err = CatalogStore::create_namespace(&mut txn, to_create).await.unwrap_err();
69		assert_eq!(err.diagnostic().code, "CA_001");
70	}
71}