use std::{
iter,
sync::{Arc, Mutex},
};
use crate::{
catalog::{CatalogManager, system::catalog::SystemCatalog},
common::symbol::Symbol,
executor::ExecutionError,
storage::{Storage, TableHeap, btree::BPlusTreeIndex},
};
pub struct Executor {
pub catalog: CatalogManager,
pub session_user: Symbol,
pub current_database: Option<Symbol>,
pub storage: Option<Storage>,
pub system_catalog: Option<SystemCatalog>,
}
impl Executor {
pub fn new(catalog: CatalogManager, session_user: Symbol, storage: Storage) -> Self {
let data_dir = storage.data_dir().to_path_buf();
let system_catalog = SystemCatalog::new(data_dir);
system_catalog.init().ok();
let mut catalog = catalog;
if let Ok(databses) = system_catalog.load_all(&mut catalog.interner) {
for db_entry in databses {
catalog.catalog.databases.insert(db_entry.name, db_entry);
}
let max_oid =
catalog
.catalog
.databases
.values()
.flat_map(|db| {
iter::once(db.oid).chain(db.schemas.values().flat_map(|s| {
iter::once(s.oid).chain(s.tables.values().map(|t| t.oid))
}))
})
.max()
.unwrap_or(0);
catalog.catalog.set_next_oid(max_oid + 1);
}
Self {
catalog,
session_user,
current_database: None,
storage: Some(storage),
system_catalog: Some(system_catalog),
}
}
pub fn new_in_memory(catalog: CatalogManager, session_user: Symbol) -> Self {
Self {
catalog,
session_user,
current_database: None,
storage: None,
system_catalog: None,
}
}
pub fn get_table_heap(
&mut self,
db: Symbol,
schema: Symbol,
table: Symbol,
) -> Result<Arc<Mutex<TableHeap>>, ExecutionError> {
let entry = self.catalog.get_table(db, schema, table)?;
entry
.heap
.clone()
.ok_or_else(|| ExecutionError::Storage("table heap not initialized".to_string()))
}
pub fn get_index(
&mut self,
db: Symbol,
schema: Symbol,
table: Symbol,
index_key: Symbol,
) -> Result<Arc<Mutex<BPlusTreeIndex>>, ExecutionError> {
let entry = self.catalog.get_table(db, schema, table)?;
entry
.indexes
.get(&index_key)
.cloned()
.ok_or_else(|| ExecutionError::Storage("index not found for column".to_string()))
}
}