use std::collections::HashMap;
use crate::{DucklakeError, DucklakeResult, io};
mod arena;
mod load;
mod refs;
mod typedefs;
mod views;
use arena::{Arena, ArenaIdx};
pub(crate) use refs::{ColumnRef, SchemaRef, TableRef};
use typedefs::*;
pub(crate) use views::SchemaView;
#[derive(Debug, Clone)]
pub struct Catalog {
schema_arena: Arena<CatalogSchema>,
table_arena: Arena<CatalogTable>,
schemas: HashMap<String, ArenaIdx>,
}
impl Catalog {
pub fn add_schema(&mut self, name: &str, path: io::DucklakePath) -> DucklakeResult<SchemaRef> {
if self.schema(name).is_ok() {
return Err(DucklakeError::schema_already_exists(name));
}
let schema = CatalogSchema {
id: None,
name: name.to_string(),
tables: HashMap::new(),
path,
};
let idx = self.schema_arena.push(schema, None);
self.schemas.insert(name.to_string(), idx);
Ok(idx.into())
}
}
impl Catalog {
#[allow(clippy::type_complexity)]
pub fn add_table(
&mut self,
table: crate::TableInfo,
path: io::DucklakePath,
) -> DucklakeResult<(
SchemaRef,
TableRef,
Vec<Vec<ColumnRef>>,
Option<Vec<ColumnRef>>,
)> {
if let Ok(table) = self.table(&table.name) {
return Err(DucklakeError::table_already_exists(table.name()));
}
let columns = table.schema.into();
let partition = table
.partitioning
.map(|p| CatalogTablePartition::from_partition(p, &columns))
.transpose()?;
let catalog_table = CatalogTable {
id: None,
name: table.name.clone(),
columns,
partition: partition.clone(),
tags: table.tags,
path,
};
let column_idxs = catalog_table.columns.root_column_indices();
let table_idx = self.table_arena.push(catalog_table, None);
let mut schema = self.schema_mut(&table.name.schema)?;
let catalog_schema = schema.inner_mut();
catalog_schema
.tables
.insert(table.name.name.clone(), table_idx);
let column_refs = column_idxs
.into_iter()
.map(|idxs| {
idxs.into_iter()
.map(|idx| (table_idx, idx).into())
.collect()
})
.collect();
let partition_refs = partition.map(|p| {
p.columns
.iter()
.map(|col| (table_idx, col.column).into())
.collect()
});
Ok((schema.ref_(), table_idx.into(), column_refs, partition_refs))
}
}