reifydb-catalog 0.4.11

Database catalog and metadata management for ReifyDB
Documentation
// SPDX-License-Identifier: Apache-2.0
// Copyright (c) 2025 ReifyDB

use reifydb_core::{
	interface::catalog::{
		handler::Handler,
		id::{HandlerId, NamespaceId},
	},
	key::{handler::HandlerKey, namespace_handler::NamespaceHandlerKey},
};
use reifydb_transaction::transaction::Transaction;

use crate::{
	CatalogStore, Result,
	store::handler::{handler_from_row, shape::handler_namespace},
};

impl CatalogStore {
	pub(crate) fn find_handler(rx: &mut Transaction<'_>, handler_id: HandlerId) -> Result<Option<Handler>> {
		let Some(multi) = rx.get(&HandlerKey::encoded(handler_id))? else {
			return Ok(None);
		};

		Ok(Some(handler_from_row(&multi.row)))
	}

	pub(crate) fn find_handler_by_name(
		rx: &mut Transaction<'_>,
		namespace: NamespaceId,
		name: impl AsRef<str>,
	) -> Result<Option<Handler>> {
		let name = name.as_ref();
		let mut stream = rx.range(NamespaceHandlerKey::full_scan(namespace), 1024)?;

		let mut found_id = None;
		for entry in stream.by_ref() {
			let multi = entry?;
			let row = &multi.row;
			let entry_name = handler_namespace::SHAPE.get_utf8(row, handler_namespace::NAME);
			if name == entry_name {
				found_id =
					Some(HandlerId(handler_namespace::SHAPE.get_u64(row, handler_namespace::ID)));
				break;
			}
		}

		drop(stream);

		let Some(id) = found_id else {
			return Ok(None);
		};

		Ok(Some(Self::get_handler(rx, id)?))
	}
}

#[cfg(test)]
pub mod tests {
	use reifydb_core::interface::catalog::id::{HandlerId, NamespaceId};
	use reifydb_engine::test_harness::create_test_admin_transaction;
	use reifydb_transaction::transaction::Transaction;
	use reifydb_type::value::sumtype::{SumTypeId, VariantRef};

	use crate::{
		CatalogStore,
		test_utils::{create_handler, create_namespace, ensure_test_namespace},
	};

	#[test]
	fn test_ok() {
		let mut txn = create_test_admin_transaction();
		ensure_test_namespace(&mut txn);
		create_namespace(&mut txn, "namespace_one");
		create_namespace(&mut txn, "namespace_two");
		create_namespace(&mut txn, "namespace_three");

		create_handler(
			&mut txn,
			"namespace_one",
			"handler_one",
			VariantRef {
				sumtype_id: SumTypeId(0),
				variant_tag: 0,
			},
			"",
		);
		create_handler(
			&mut txn,
			"namespace_two",
			"handler_two",
			VariantRef {
				sumtype_id: SumTypeId(0),
				variant_tag: 0,
			},
			"",
		);
		create_handler(
			&mut txn,
			"namespace_three",
			"handler_three",
			VariantRef {
				sumtype_id: SumTypeId(0),
				variant_tag: 0,
			},
			"",
		);

		let result = CatalogStore::find_handler_by_name(
			&mut Transaction::Admin(&mut txn),
			NamespaceId(16387),
			"handler_two",
		)
		.unwrap()
		.unwrap();
		assert_eq!(result.id, HandlerId(16386));
		assert_eq!(result.namespace, NamespaceId(16387));
		assert_eq!(result.name, "handler_two");
	}

	#[test]
	fn test_empty() {
		let mut txn = create_test_admin_transaction();

		let result = CatalogStore::find_handler_by_name(
			&mut Transaction::Admin(&mut txn),
			NamespaceId(16385),
			"some_handler",
		)
		.unwrap();
		assert!(result.is_none());
	}

	#[test]
	fn test_not_found_different_handler() {
		let mut txn = create_test_admin_transaction();
		ensure_test_namespace(&mut txn);
		create_namespace(&mut txn, "namespace_one");
		create_namespace(&mut txn, "namespace_two");
		create_namespace(&mut txn, "namespace_three");

		create_handler(
			&mut txn,
			"namespace_one",
			"handler_one",
			VariantRef {
				sumtype_id: SumTypeId(0),
				variant_tag: 0,
			},
			"",
		);
		create_handler(
			&mut txn,
			"namespace_two",
			"handler_two",
			VariantRef {
				sumtype_id: SumTypeId(0),
				variant_tag: 0,
			},
			"",
		);
		create_handler(
			&mut txn,
			"namespace_three",
			"handler_three",
			VariantRef {
				sumtype_id: SumTypeId(0),
				variant_tag: 0,
			},
			"",
		);

		let result = CatalogStore::find_handler_by_name(
			&mut Transaction::Admin(&mut txn),
			NamespaceId(16385),
			"handler_nonexistent",
		)
		.unwrap();
		assert!(result.is_none());
	}

	#[test]
	fn test_not_found_different_namespace() {
		let mut txn = create_test_admin_transaction();
		ensure_test_namespace(&mut txn);
		create_namespace(&mut txn, "namespace_one");
		create_namespace(&mut txn, "namespace_two");
		create_namespace(&mut txn, "namespace_three");

		create_handler(
			&mut txn,
			"namespace_one",
			"handler_one",
			VariantRef {
				sumtype_id: SumTypeId(0),
				variant_tag: 0,
			},
			"",
		);
		create_handler(
			&mut txn,
			"namespace_two",
			"handler_two",
			VariantRef {
				sumtype_id: SumTypeId(0),
				variant_tag: 0,
			},
			"",
		);
		create_handler(
			&mut txn,
			"namespace_three",
			"handler_three",
			VariantRef {
				sumtype_id: SumTypeId(0),
				variant_tag: 0,
			},
			"",
		);

		let result = CatalogStore::find_handler_by_name(
			&mut Transaction::Admin(&mut txn),
			NamespaceId::DEFAULT,
			"handler_two",
		)
		.unwrap();
		assert!(result.is_none());
	}
}