reifydb_catalog/store/column/
list.rs1use reifydb_core::interface::{ColumnKey, QueryTransaction, SourceId};
5
6use crate::{
7 CatalogStore,
8 store::column::{ColumnDef, ColumnId, layout::source_column},
9};
10
11pub struct ColumnInfo {
13 pub column: ColumnDef,
14 pub source_id: SourceId,
15 pub is_view: bool,
16}
17
18impl CatalogStore {
19 pub async fn list_columns(
20 rx: &mut impl QueryTransaction,
21 source: impl Into<SourceId>,
22 ) -> crate::Result<Vec<ColumnDef>> {
23 let source = source.into();
24 let mut result = vec![];
25
26 let batch = rx.range(ColumnKey::full_scan(source)).await?;
27 let ids: Vec<_> = batch
28 .items
29 .into_iter()
30 .map(|multi| {
31 let row = multi.values;
32 ColumnId(source_column::LAYOUT.get_u64(&row, source_column::ID))
33 })
34 .collect();
35
36 for id in ids {
37 result.push(Self::get_column(rx, id).await?);
38 }
39
40 result.sort_by_key(|c| c.index);
41
42 Ok(result)
43 }
44
45 pub async fn list_columns_all(rx: &mut impl QueryTransaction) -> crate::Result<Vec<ColumnInfo>> {
46 let mut result = Vec::new();
47
48 let tables = CatalogStore::list_tables_all(rx).await?;
50 for table in tables {
51 let columns = CatalogStore::list_columns(rx, table.id).await?;
52 for column in columns {
53 result.push(ColumnInfo {
54 column,
55 source_id: table.id.into(),
56 is_view: false,
57 });
58 }
59 }
60
61 let views = CatalogStore::list_views_all(rx).await?;
63 for view in views {
64 let columns = CatalogStore::list_columns(rx, view.id).await?;
65 for column in columns {
66 result.push(ColumnInfo {
67 column,
68 source_id: view.id.into(),
69 is_view: true,
70 });
71 }
72 }
73
74 let ringbuffers = CatalogStore::list_ringbuffers_all(rx).await?;
76 for ringbuffer in ringbuffers {
77 let columns = CatalogStore::list_columns(rx, ringbuffer.id).await?;
78 for column in columns {
79 result.push(ColumnInfo {
80 column,
81 source_id: ringbuffer.id.into(),
82 is_view: false,
83 });
84 }
85 }
86
87 Ok(result)
88 }
89}
90
91#[cfg(test)]
92mod tests {
93 use reifydb_core::interface::TableId;
94 use reifydb_engine::test_utils::create_test_command_transaction;
95 use reifydb_type::{Type, TypeConstraint};
96
97 use crate::{
98 CatalogStore,
99 store::column::{ColumnIndex, ColumnToCreate},
100 test_utils::ensure_test_table,
101 };
102
103 #[tokio::test]
104 async fn test_ok() {
105 let mut txn = create_test_command_transaction().await;
106 ensure_test_table(&mut txn).await;
107
108 CatalogStore::create_column(
110 &mut txn,
111 TableId(1),
112 ColumnToCreate {
113 fragment: None,
114 namespace_name: "test_namespace".to_string(),
115 table: TableId(1),
116 table_name: "test_table".to_string(),
117 column: "b_col".to_string(),
118 constraint: TypeConstraint::unconstrained(Type::Int4),
119 if_not_exists: false,
120 policies: vec![],
121 index: ColumnIndex(1),
122 auto_increment: true,
123 dictionary_id: None,
124 },
125 )
126 .await
127 .unwrap();
128
129 CatalogStore::create_column(
130 &mut txn,
131 TableId(1),
132 ColumnToCreate {
133 fragment: None,
134 namespace_name: "test_namespace".to_string(),
135 table: TableId(1),
136 table_name: "test_table".to_string(),
137 column: "a_col".to_string(),
138 constraint: TypeConstraint::unconstrained(Type::Boolean),
139 if_not_exists: false,
140 policies: vec![],
141 index: ColumnIndex(0),
142 auto_increment: false,
143 dictionary_id: None,
144 },
145 )
146 .await
147 .unwrap();
148
149 let columns = CatalogStore::list_columns(&mut txn, TableId(1)).await.unwrap();
150 assert_eq!(columns.len(), 2);
151
152 assert_eq!(columns[0].name, "a_col"); assert_eq!(columns[1].name, "b_col"); assert_eq!(columns[0].index, ColumnIndex(0));
156 assert_eq!(columns[1].index, ColumnIndex(1));
157
158 assert_eq!(columns[0].auto_increment, false);
159 assert_eq!(columns[1].auto_increment, true);
160 }
161
162 #[tokio::test]
163 async fn test_empty() {
164 let mut txn = create_test_command_transaction().await;
165 ensure_test_table(&mut txn).await;
166
167 let columns = CatalogStore::list_columns(&mut txn, TableId(1)).await.unwrap();
168 assert!(columns.is_empty());
169 }
170
171 #[tokio::test]
172 async fn test_table_does_not_exist() {
173 let mut txn = create_test_command_transaction().await;
174
175 let columns = CatalogStore::list_columns(&mut txn, TableId(1)).await.unwrap();
176 assert!(columns.is_empty());
177 }
178}