pub mod backend;
pub mod backend_postgres;
pub mod backend_sqlite;
pub mod channel_repo;
pub mod eval_repo;
pub mod migrations;
pub mod model_repo;
pub mod mutable_repo;
pub mod result_repo;
pub mod schema;
pub mod source_repo;
pub mod status;
pub mod topic_repo;
pub mod training_repo;
use std::path::Path;
use std::sync::Arc;
use crate::error::Result;
use crate::tenant::TenantId;
use crate::tenant_scope::TenantBinding;
use backend::BackendImpl;
use backend_sqlite::SqliteBackend;
use channel_repo::ChannelRepo;
pub struct Catalog {
backend: Arc<BackendImpl>,
tenant: Option<TenantBinding>,
}
impl Catalog {
pub async fn open(artifact_dir: &Path) -> Result<Self> {
Self::open_with_tenant(artifact_dir, None).await
}
pub async fn open_with_tenant(
artifact_dir: &Path,
tenant: Option<TenantBinding>,
) -> Result<Self> {
std::fs::create_dir_all(artifact_dir)?;
let db_path = artifact_dir.join("catalog.db");
let backend = SqliteBackend::open(&db_path).await?;
let cat = Self {
backend: Arc::new(BackendImpl::Sqlite(backend)),
tenant,
};
cat.backend.migrate().await?;
Ok(cat)
}
pub fn from_backend(backend: BackendImpl) -> Self {
Self::from_backend_with_tenant(backend, None)
}
pub fn from_backend_with_tenant(backend: BackendImpl, tenant: Option<TenantBinding>) -> Self {
Self {
backend: Arc::new(backend),
tenant,
}
}
pub fn pinned_to_tenant(&self, tenant: Option<TenantId>) -> Self {
let binding = TenantBinding::unscoped();
if let Some(t) = tenant {
binding.set_shared(crate::tenant::TenantContext::Scoped(t));
}
Self {
backend: Arc::clone(&self.backend),
tenant: Some(binding),
}
}
pub fn channels(&self) -> ChannelRepo<'_> {
ChannelRepo::new(self)
}
pub(crate) fn backend(&self) -> &BackendImpl {
&self.backend
}
pub fn backend_arc(&self) -> Arc<BackendImpl> {
Arc::clone(&self.backend)
}
pub fn current_tenant(&self) -> Option<TenantId> {
self.tenant.as_ref().and_then(|b| b.current_tenant())
}
pub async fn ping(&self) -> std::result::Result<(), backend::BackendError> {
self.backend.ping().await
}
}