use std::sync::Arc;
use crate::catalog::{Catalog, FileSystemCatalog, RESTCatalog};
use crate::common::{CatalogOptions, Options};
use crate::error::{ConfigInvalidSnafu, Result};
const METASTORE_FILESYSTEM: &str = "filesystem";
const METASTORE_REST: &str = "rest";
pub struct CatalogFactory;
impl CatalogFactory {
pub async fn create(options: Options) -> Result<Arc<dyn Catalog>> {
let metastore = options
.get(CatalogOptions::METASTORE)
.map(|s| s.as_str())
.unwrap_or(METASTORE_FILESYSTEM);
match metastore {
METASTORE_FILESYSTEM => Self::create_filesystem_catalog(options),
METASTORE_REST => Self::create_rest_catalog(options).await,
_ => ConfigInvalidSnafu {
message: format!(
"Unknown metastore type: '{metastore}'. Available types: {METASTORE_FILESYSTEM}, {METASTORE_REST}"
),
}
.fail(),
}
}
fn create_filesystem_catalog(options: Options) -> Result<Arc<dyn Catalog>> {
let catalog = FileSystemCatalog::new(options)?;
Ok(Arc::new(catalog))
}
async fn create_rest_catalog(options: Options) -> Result<Arc<dyn Catalog>> {
let catalog = RESTCatalog::new(options, true).await?;
Ok(Arc::new(catalog))
}
}
#[cfg(test)]
#[cfg(not(windows))] mod tests {
use super::*;
#[tokio::test]
async fn test_create_filesystem_catalog() {
let mut options = Options::new();
options.set(CatalogOptions::WAREHOUSE, "/tmp/test-warehouse");
let result = CatalogFactory::create(options).await;
assert!(result.is_ok());
}
#[tokio::test]
async fn test_create_filesystem_catalog_explicit() {
let mut options = Options::new();
options.set(CatalogOptions::METASTORE, "filesystem");
options.set(CatalogOptions::WAREHOUSE, "/tmp/test-warehouse");
let result = CatalogFactory::create(options).await;
assert!(result.is_ok());
}
#[tokio::test]
async fn test_missing_warehouse_option() {
let options = Options::new();
let result = CatalogFactory::create(options).await;
assert!(result.is_err());
}
#[tokio::test]
async fn test_unknown_metastore_type() {
let mut options = Options::new();
options.set(CatalogOptions::METASTORE, "unknown");
options.set(CatalogOptions::WAREHOUSE, "/tmp/test");
let result = CatalogFactory::create(options).await;
assert!(result.is_err());
}
}