reifydb_catalog/store/table/
find.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::{
5	MultiVersionValues, NamespaceId, NamespaceTableKey, QueryTransaction, TableDef, TableId, TableKey,
6};
7
8use crate::{
9	CatalogStore,
10	store::table::layout::{table, table_namespace},
11};
12
13impl CatalogStore {
14	pub async fn find_table(rx: &mut impl QueryTransaction, table: TableId) -> crate::Result<Option<TableDef>> {
15		let Some(multi) = rx.get(&TableKey::encoded(table)).await? else {
16			return Ok(None);
17		};
18
19		let row = multi.values;
20		let id = TableId(table::LAYOUT.get_u64(&row, table::ID));
21		let namespace = NamespaceId(table::LAYOUT.get_u64(&row, table::NAMESPACE));
22		let name = table::LAYOUT.get_utf8(&row, table::NAME).to_string();
23
24		Ok(Some(TableDef {
25			id,
26			name,
27			namespace,
28			columns: Self::list_columns(rx, id).await?,
29			primary_key: Self::find_primary_key(rx, id).await?,
30		}))
31	}
32
33	pub async fn find_table_by_name(
34		rx: &mut impl QueryTransaction,
35		namespace: NamespaceId,
36		name: impl AsRef<str>,
37	) -> crate::Result<Option<TableDef>> {
38		let name = name.as_ref();
39		let batch = rx.range(NamespaceTableKey::full_scan(namespace)).await?;
40		let Some(table) = batch.items.iter().find_map(|multi: &MultiVersionValues| {
41			let row = &multi.values;
42			let table_name = table_namespace::LAYOUT.get_utf8(row, table_namespace::NAME);
43			if name == table_name {
44				Some(TableId(table_namespace::LAYOUT.get_u64(row, table_namespace::ID)))
45			} else {
46				None
47			}
48		}) else {
49			return Ok(None);
50		};
51
52		Ok(Some(Self::get_table(rx, table).await?))
53	}
54}
55
56#[cfg(test)]
57mod tests {
58	use reifydb_core::interface::{NamespaceId, TableId};
59	use reifydb_engine::test_utils::create_test_command_transaction;
60
61	use crate::{
62		CatalogStore,
63		test_utils::{create_namespace, create_table, ensure_test_namespace},
64	};
65
66	#[tokio::test]
67	async fn test_ok() {
68		let mut txn = create_test_command_transaction().await;
69		ensure_test_namespace(&mut txn).await;
70		create_namespace(&mut txn, "namespace_one").await;
71		create_namespace(&mut txn, "namespace_two").await;
72		create_namespace(&mut txn, "namespace_three").await;
73
74		create_table(&mut txn, "namespace_one", "table_one", &[]).await;
75		create_table(&mut txn, "namespace_two", "table_two", &[]).await;
76		create_table(&mut txn, "namespace_three", "table_three", &[]).await;
77
78		let result = CatalogStore::find_table_by_name(&mut txn, NamespaceId(1027), "table_two")
79			.await
80			.unwrap()
81			.unwrap();
82		assert_eq!(result.id, TableId(1026));
83		assert_eq!(result.namespace, NamespaceId(1027));
84		assert_eq!(result.name, "table_two");
85	}
86
87	#[tokio::test]
88	async fn test_empty() {
89		let mut txn = create_test_command_transaction().await;
90
91		let result = CatalogStore::find_table_by_name(&mut txn, NamespaceId(1025), "some_table").await.unwrap();
92		assert!(result.is_none());
93	}
94
95	#[tokio::test]
96	async fn test_not_found_different_table() {
97		let mut txn = create_test_command_transaction().await;
98		ensure_test_namespace(&mut txn).await;
99		create_namespace(&mut txn, "namespace_one").await;
100		create_namespace(&mut txn, "namespace_two").await;
101		create_namespace(&mut txn, "namespace_three").await;
102
103		create_table(&mut txn, "namespace_one", "table_one", &[]).await;
104		create_table(&mut txn, "namespace_two", "table_two", &[]).await;
105		create_table(&mut txn, "namespace_three", "table_three", &[]).await;
106
107		let result =
108			CatalogStore::find_table_by_name(&mut txn, NamespaceId(1025), "table_four_two").await.unwrap();
109		assert!(result.is_none());
110	}
111
112	#[tokio::test]
113	async fn test_not_found_different_namespace() {
114		let mut txn = create_test_command_transaction().await;
115		ensure_test_namespace(&mut txn).await;
116		create_namespace(&mut txn, "namespace_one").await;
117		create_namespace(&mut txn, "namespace_two").await;
118		create_namespace(&mut txn, "namespace_three").await;
119
120		create_table(&mut txn, "namespace_one", "table_one", &[]).await;
121		create_table(&mut txn, "namespace_two", "table_two", &[]).await;
122		create_table(&mut txn, "namespace_three", "table_three", &[]).await;
123
124		let result = CatalogStore::find_table_by_name(&mut txn, NamespaceId(2), "table_two").await.unwrap();
125		assert!(result.is_none());
126	}
127}