alopex_sql/catalog/
memory.rs1use std::collections::HashMap;
7
8use super::{Catalog, IndexMetadata, TableMetadata};
9use crate::planner::PlannerError;
10
11#[derive(Debug, Default)]
42pub struct MemoryCatalog {
43 tables: HashMap<String, TableMetadata>,
45 indexes: HashMap<String, IndexMetadata>,
47 table_id_counter: u32,
49 index_id_counter: u32,
51}
52
53impl MemoryCatalog {
54 pub fn new() -> Self {
56 Self::default()
57 }
58
59 pub fn table_count(&self) -> usize {
61 self.tables.len()
62 }
63
64 pub fn index_count(&self) -> usize {
66 self.indexes.len()
67 }
68
69 pub fn table_names(&self) -> Vec<&str> {
71 self.tables.keys().map(|s| s.as_str()).collect()
72 }
73
74 pub fn index_names(&self) -> Vec<&str> {
76 self.indexes.keys().map(|s| s.as_str()).collect()
77 }
78
79 pub fn clear(&mut self) {
81 self.tables.clear();
82 self.indexes.clear();
83 }
84}
85
86impl Catalog for MemoryCatalog {
87 fn create_table(&mut self, table: TableMetadata) -> Result<(), PlannerError> {
88 if self.tables.contains_key(&table.name) {
89 return Err(PlannerError::table_already_exists(&table.name));
90 }
91 self.tables.insert(table.name.clone(), table);
92 Ok(())
93 }
94
95 fn get_table(&self, name: &str) -> Option<&TableMetadata> {
96 self.tables.get(name)
97 }
98
99 fn drop_table(&mut self, name: &str) -> Result<(), PlannerError> {
100 if self.tables.remove(name).is_none() {
101 return Err(PlannerError::TableNotFound {
102 name: name.to_string(),
103 line: 0,
104 column: 0,
105 });
106 }
107 self.indexes.retain(|_, idx| idx.table != name);
109 Ok(())
110 }
111
112 fn create_index(&mut self, index: IndexMetadata) -> Result<(), PlannerError> {
113 if self.indexes.contains_key(&index.name) {
115 return Err(PlannerError::index_already_exists(&index.name));
116 }
117
118 let table = self
120 .tables
121 .get(&index.table)
122 .ok_or_else(|| PlannerError::TableNotFound {
123 name: index.table.clone(),
124 line: 0,
125 column: 0,
126 })?;
127
128 for column in &index.columns {
130 if table.get_column(column).is_none() {
131 return Err(PlannerError::ColumnNotFound {
132 column: column.clone(),
133 table: index.table.clone(),
134 line: 0,
135 col: 0,
136 });
137 }
138 }
139
140 self.indexes.insert(index.name.clone(), index);
141 Ok(())
142 }
143
144 fn get_index(&self, name: &str) -> Option<&IndexMetadata> {
145 self.indexes.get(name)
146 }
147
148 fn get_indexes_for_table(&self, table: &str) -> Vec<&IndexMetadata> {
149 self.indexes
150 .values()
151 .filter(|idx| idx.table == table)
152 .collect()
153 }
154
155 fn drop_index(&mut self, name: &str) -> Result<(), PlannerError> {
156 if self.indexes.remove(name).is_none() {
157 return Err(PlannerError::index_not_found(name));
158 }
159 Ok(())
160 }
161
162 fn table_exists(&self, name: &str) -> bool {
163 self.tables.contains_key(name)
164 }
165
166 fn index_exists(&self, name: &str) -> bool {
167 self.indexes.contains_key(name)
168 }
169
170 fn next_table_id(&mut self) -> u32 {
171 self.table_id_counter += 1;
172 self.table_id_counter
173 }
174
175 fn next_index_id(&mut self) -> u32 {
176 self.index_id_counter += 1;
177 self.index_id_counter
178 }
179}