use std::future::Future;
use std::pin::Pin;
use std::sync::Arc;
use anyhow::Result;
use tracing::Instrument;
use uuid::Uuid;
use crate::catalog;
use crate::catalog::{
DatabaseDefinition, DatabaseId, DefaultConfig, IndexId, NamespaceDefinition, NamespaceId,
Record, TableDefinition, TableId, UserDefinition,
};
use crate::ctx::Context;
use crate::dbs::node::Node;
use crate::err::Error;
use crate::kvs::CachePolicy;
use crate::val::{RecordId, RecordIdKey, TableName};
#[cfg(target_family = "wasm")]
pub(crate) type BoxProviderFut<'a, T> = Pin<Box<dyn Future<Output = T> + 'a>>;
#[cfg(not(target_family = "wasm"))]
pub(crate) type BoxProviderFut<'a, T> = Pin<Box<dyn Future<Output = T> + Send + 'a>>;
#[cfg(not(target_family = "wasm"))]
pub(crate) trait ProviderFutureSendRequirement: Sync {}
#[cfg(not(target_family = "wasm"))]
impl<T: Sync + ?Sized> ProviderFutureSendRequirement for T {}
#[cfg(target_family = "wasm")]
pub(crate) trait ProviderFutureSendRequirement {}
#[cfg(target_family = "wasm")]
impl<T: ?Sized> ProviderFutureSendRequirement for T {}
pub(crate) trait NodeProvider: ProviderFutureSendRequirement {
fn all_nodes(&self) -> BoxProviderFut<'_, Result<Arc<[Node]>>>;
fn get_node(&self, id: Uuid) -> BoxProviderFut<'_, Result<Arc<Node>>>;
}
pub(crate) trait RootProvider: ProviderFutureSendRequirement {
fn get_default_config(&self) -> BoxProviderFut<'_, Result<Option<Arc<DefaultConfig>>>>;
fn get_root_config<'a>(
&'a self,
cg: &'a str,
) -> BoxProviderFut<'a, Result<Option<Arc<catalog::ConfigDefinition>>>>;
fn expect_root_config<'a>(
&'a self,
cg: &'a str,
) -> BoxProviderFut<'a, Result<Arc<catalog::ConfigDefinition>>> {
Box::pin(async move {
if let Some(val) = self.get_root_config(cg).await? {
Ok(val)
} else {
Err(anyhow::Error::new(Error::CgNotFound {
name: cg.to_owned(),
}))
}
})
}
}
pub(crate) trait NamespaceProvider: ProviderFutureSendRequirement {
fn all_ns(
&self,
version: Option<u64>,
) -> BoxProviderFut<'_, Result<Arc<[NamespaceDefinition]>>>;
fn get_ns_by_name<'a>(
&'a self,
ns: &'a str,
version: Option<u64>,
) -> BoxProviderFut<'a, Result<Option<Arc<NamespaceDefinition>>>>;
fn get_or_add_ns<'a>(
&'a self,
ctx: Option<&'a Context>,
ns: &'a str,
) -> BoxProviderFut<'a, Result<Arc<NamespaceDefinition>>> {
Box::pin(
async move {
match self.get_ns_by_name(ns, None).await? {
Some(val) => Ok(val),
None => {
let ns = NamespaceDefinition {
namespace_id: self.get_next_ns_id(ctx).await?,
name: ns.into(),
comment: None,
};
self.put_ns(ns).await
}
}
}
.instrument(trace_span!(target: "surrealdb::core::kvs::tx", "get_or_add_ns")),
)
}
fn get_next_ns_id<'a>(
&'a self,
ctx: Option<&'a Context>,
) -> BoxProviderFut<'a, Result<NamespaceId>>;
fn put_ns(
&self,
ns: NamespaceDefinition,
) -> BoxProviderFut<'_, Result<Arc<NamespaceDefinition>>>;
fn expect_ns_by_name<'a>(
&'a self,
ns: &'a str,
) -> BoxProviderFut<'a, Result<Arc<NamespaceDefinition>>> {
Box::pin(async move {
match self.get_ns_by_name(ns, None).await? {
Some(val) => Ok(val),
None => anyhow::bail!(Error::NsNotFound {
name: ns.to_owned(),
}),
}
})
}
}
pub(crate) trait DatabaseProvider: NamespaceProvider {
fn all_db(
&self,
ns: NamespaceId,
version: Option<u64>,
) -> BoxProviderFut<'_, Result<Arc<[DatabaseDefinition]>>>;
fn get_db_by_name<'a>(
&'a self,
ns: &'a str,
db: &'a str,
version: Option<u64>,
) -> BoxProviderFut<'a, Result<Option<Arc<DatabaseDefinition>>>>;
fn get_or_add_db_upwards<'a>(
&'a self,
ctx: Option<&'a Context>,
ns: &'a str,
db: &'a str,
upwards: bool,
) -> BoxProviderFut<'a, Result<Arc<DatabaseDefinition>>>;
fn get_next_db_id<'a>(
&'a self,
ctx: Option<&'a Context>,
ns: NamespaceId,
) -> BoxProviderFut<'a, Result<DatabaseId>>;
fn put_db<'a>(
&'a self,
ns: &'a str,
db: DatabaseDefinition,
) -> BoxProviderFut<'a, Result<Arc<DatabaseDefinition>>>;
fn expect_db_by_name<'a>(
&'a self,
ns: &'a str,
db: &'a str,
) -> BoxProviderFut<'a, Result<Arc<DatabaseDefinition>>> {
Box::pin(async move {
match self.get_db_by_name(ns, db, None).await? {
Some(val) => Ok(val),
None => {
self.expect_ns_by_name(ns).await?;
Err(anyhow::anyhow!(Error::DbNotFound {
name: db.to_owned()
}))
}
}
})
}
fn all_db_analyzers(
&self,
ns: NamespaceId,
db: DatabaseId,
version: Option<u64>,
) -> BoxProviderFut<'_, Result<Arc<[catalog::AnalyzerDefinition]>>>;
fn all_db_sequences(
&self,
ns: NamespaceId,
db: DatabaseId,
version: Option<u64>,
) -> BoxProviderFut<'_, Result<Arc<[catalog::SequenceDefinition]>>>;
fn all_db_functions(
&self,
ns: NamespaceId,
db: DatabaseId,
version: Option<u64>,
) -> BoxProviderFut<'_, Result<Arc<[catalog::FunctionDefinition]>>>;
fn all_db_modules(
&self,
ns: NamespaceId,
db: DatabaseId,
version: Option<u64>,
) -> BoxProviderFut<'_, Result<Arc<[catalog::ModuleDefinition]>>>;
fn all_db_params(
&self,
ns: NamespaceId,
db: DatabaseId,
version: Option<u64>,
) -> BoxProviderFut<'_, Result<Arc<[catalog::ParamDefinition]>>>;
fn all_db_models(
&self,
ns: NamespaceId,
db: DatabaseId,
version: Option<u64>,
) -> BoxProviderFut<'_, Result<Arc<[catalog::MlModelDefinition]>>>;
fn all_db_configs(
&self,
ns: NamespaceId,
db: DatabaseId,
version: Option<u64>,
) -> BoxProviderFut<'_, Result<Arc<[catalog::ConfigDefinition]>>>;
fn get_db_model<'a>(
&'a self,
ns: NamespaceId,
db: DatabaseId,
ml: &'a str,
vn: &'a str,
version: Option<u64>,
) -> BoxProviderFut<'a, Result<Option<Arc<catalog::MlModelDefinition>>>>;
fn get_db_analyzer<'a>(
&'a self,
ns: NamespaceId,
db: DatabaseId,
az: &'a str,
version: Option<u64>,
) -> BoxProviderFut<'a, Result<Arc<catalog::AnalyzerDefinition>>>;
fn get_db_sequence<'a>(
&'a self,
ns: NamespaceId,
db: DatabaseId,
sq: &'a str,
version: Option<u64>,
) -> BoxProviderFut<'a, Result<Arc<catalog::SequenceDefinition>>>;
fn get_db_function<'a>(
&'a self,
ns: NamespaceId,
db: DatabaseId,
fc: &'a str,
version: Option<u64>,
) -> BoxProviderFut<'a, Result<Arc<catalog::FunctionDefinition>>>;
fn put_db_function<'a>(
&'a self,
ns: NamespaceId,
db: DatabaseId,
fc: &'a catalog::FunctionDefinition,
) -> BoxProviderFut<'a, Result<()>>;
fn get_db_module<'a>(
&'a self,
ns: NamespaceId,
db: DatabaseId,
md: &'a str,
version: Option<u64>,
) -> BoxProviderFut<'a, Result<Arc<catalog::ModuleDefinition>>>;
fn put_db_module<'a>(
&'a self,
ns: NamespaceId,
db: DatabaseId,
md: &'a catalog::ModuleDefinition,
) -> BoxProviderFut<'a, Result<()>>;
fn get_db_param<'a>(
&'a self,
ns: NamespaceId,
db: DatabaseId,
pa: &'a str,
version: Option<u64>,
) -> BoxProviderFut<'a, Result<Arc<catalog::ParamDefinition>>>;
fn put_db_param<'a>(
&'a self,
ns: NamespaceId,
db: DatabaseId,
pa: &'a catalog::ParamDefinition,
) -> BoxProviderFut<'a, Result<()>>;
fn get_db_config<'a>(
&'a self,
ns: NamespaceId,
db: DatabaseId,
cg: &'a str,
version: Option<u64>,
) -> BoxProviderFut<'a, Result<Option<Arc<catalog::ConfigDefinition>>>>;
fn expect_db_config<'a>(
&'a self,
ns: NamespaceId,
db: DatabaseId,
cg: &'a str,
) -> BoxProviderFut<'a, Result<Arc<catalog::ConfigDefinition>>> {
Box::pin(async move {
if let Some(val) = self.get_db_config(ns, db, cg, None).await? {
Ok(val)
} else {
Err(anyhow::Error::new(Error::CgNotFound {
name: cg.to_owned(),
}))
}
})
}
}
pub(crate) trait TableProvider: ProviderFutureSendRequirement {
fn all_tb(
&self,
ns: NamespaceId,
db: DatabaseId,
version: Option<u64>,
) -> BoxProviderFut<'_, Result<Arc<[TableDefinition]>>>;
fn all_tb_views<'a>(
&'a self,
ns: NamespaceId,
db: DatabaseId,
tb: &'a TableName,
version: Option<u64>,
) -> BoxProviderFut<'a, Result<Arc<[TableDefinition]>>>;
fn get_tb_by_name<'a>(
&'a self,
ns: &'a str,
db: &'a str,
tb: &'a TableName,
version: Option<u64>,
) -> BoxProviderFut<'a, Result<Option<Arc<TableDefinition>>>>;
fn expect_tb_by_name<'a>(
&'a self,
ns: &'a str,
db: &'a str,
tb: &'a TableName,
) -> BoxProviderFut<'a, Result<Arc<TableDefinition>>> {
Box::pin(async move {
match self.get_tb_by_name(ns, db, tb, None).await? {
Some(val) => Ok(val),
None => anyhow::bail!(Error::TbNotFound {
name: tb.to_owned(),
}),
}
})
}
fn get_or_add_tb<'a>(
&'a self,
ctx: Option<&'a Context>,
ns: &'a str,
db: &'a str,
tb: &'a TableName,
version: Option<u64>,
) -> BoxProviderFut<'a, Result<Arc<TableDefinition>>>;
fn get_next_tb_id<'a>(
&'a self,
ctx: Option<&'a Context>,
ns: NamespaceId,
db: DatabaseId,
) -> BoxProviderFut<'a, Result<TableId>>;
fn put_tb<'a>(
&'a self,
ns: &'a str,
db: &'a str,
tb: &'a TableDefinition,
) -> BoxProviderFut<'a, Result<Arc<TableDefinition>>>;
fn del_tb<'a>(
&'a self,
ns: &'a str,
db: &'a str,
tb: &'a TableName,
) -> BoxProviderFut<'a, Result<()>>;
fn clr_tb<'a>(
&'a self,
ns: &'a str,
db: &'a str,
tb: &'a TableName,
) -> BoxProviderFut<'a, Result<()>>;
fn all_tb_events<'a>(
&'a self,
ns: NamespaceId,
db: DatabaseId,
tb: &'a TableName,
version: Option<u64>,
) -> BoxProviderFut<'a, Result<Arc<[catalog::EventDefinition]>>>;
fn all_tb_fields<'a>(
&'a self,
ns: NamespaceId,
db: DatabaseId,
tb: &'a TableName,
version: Option<u64>,
) -> BoxProviderFut<'a, Result<Arc<[catalog::FieldDefinition]>>>;
fn all_tb_indexes<'a>(
&'a self,
ns: NamespaceId,
db: DatabaseId,
tb: &'a TableName,
version: Option<u64>,
) -> BoxProviderFut<'a, Result<Arc<[catalog::IndexDefinition]>>>;
fn all_tb_lives<'a>(
&'a self,
ns: NamespaceId,
db: DatabaseId,
tb: &'a TableName,
version: Option<u64>,
) -> BoxProviderFut<'a, Result<Arc<[catalog::SubscriptionDefinition]>>>;
fn get_tb<'a>(
&'a self,
ns: NamespaceId,
db: DatabaseId,
tb: &'a TableName,
version: Option<u64>,
) -> BoxProviderFut<'a, Result<Option<Arc<TableDefinition>>>>;
fn expect_tb<'a>(
&'a self,
ns: NamespaceId,
db: DatabaseId,
tb: &'a TableName,
) -> BoxProviderFut<'a, Result<Arc<TableDefinition>>> {
Box::pin(async move {
match self.get_tb(ns, db, tb, None).await? {
Some(val) => Ok(val),
None => anyhow::bail!(Error::TbNotFound {
name: tb.to_owned(),
}),
}
})
}
fn get_tb_event<'a>(
&'a self,
ns: NamespaceId,
db: DatabaseId,
tb: &'a TableName,
ev: &'a str,
version: Option<u64>,
) -> BoxProviderFut<'a, Result<Arc<catalog::EventDefinition>>>;
fn get_tb_field<'a>(
&'a self,
ns: NamespaceId,
db: DatabaseId,
tb: &'a TableName,
fd: &'a str,
version: Option<u64>,
) -> BoxProviderFut<'a, Result<Option<Arc<catalog::FieldDefinition>>>>;
fn put_tb_field<'a>(
&'a self,
ns: NamespaceId,
db: DatabaseId,
tb: &'a TableName,
fd: &'a catalog::FieldDefinition,
) -> BoxProviderFut<'a, Result<()>>;
fn get_tb_index<'a>(
&'a self,
ns: NamespaceId,
db: DatabaseId,
tb: &'a TableName,
ix: &'a str,
version: Option<u64>,
) -> BoxProviderFut<'a, Result<Option<Arc<catalog::IndexDefinition>>>>;
fn get_tb_index_by_id<'a>(
&'a self,
ns: NamespaceId,
db: DatabaseId,
tb: &'a TableName,
ix: IndexId,
version: Option<u64>,
) -> BoxProviderFut<'a, Result<Option<Arc<catalog::IndexDefinition>>>>;
fn expect_tb_index<'a>(
&'a self,
ns: NamespaceId,
db: DatabaseId,
tb: &'a TableName,
ix: &'a str,
) -> BoxProviderFut<'a, Result<Arc<catalog::IndexDefinition>>> {
Box::pin(async move {
self.get_tb_index(ns, db, tb, ix, None).await?.ok_or_else(|| {
Error::IxNotFound {
name: ix.to_owned(),
}
.into()
})
})
}
fn put_tb_index<'a>(
&'a self,
ns: NamespaceId,
db: DatabaseId,
tb: &'a TableName,
ix: &'a catalog::IndexDefinition,
) -> BoxProviderFut<'a, Result<()>>;
fn del_tb_index<'a>(
&'a self,
ns: NamespaceId,
db: DatabaseId,
tb: &'a TableName,
ix: &'a str,
) -> BoxProviderFut<'a, Result<()>>;
fn get_record<'a>(
&'a self,
ns: NamespaceId,
db: DatabaseId,
tb: &'a TableName,
id: &'a RecordIdKey,
version: Option<u64>,
) -> BoxProviderFut<'a, Result<Arc<Record>>>;
fn get_records<'a>(
&'a self,
ns: NamespaceId,
db: DatabaseId,
rids: &'a [RecordId],
version: Option<u64>,
cache_policy: CachePolicy,
) -> BoxProviderFut<'a, Result<Vec<Arc<Record>>>>;
fn record_exists<'a>(
&'a self,
ns: NamespaceId,
db: DatabaseId,
tb: &'a TableName,
id: &'a RecordIdKey,
version: Option<u64>,
) -> BoxProviderFut<'a, Result<bool>>;
fn put_record<'a>(
&'a self,
ns: NamespaceId,
db: DatabaseId,
tb: &'a TableName,
id: &'a RecordIdKey,
record: Arc<Record>,
) -> BoxProviderFut<'a, Result<()>>;
fn set_record<'a>(
&'a self,
ns: NamespaceId,
db: DatabaseId,
tb: &'a TableName,
id: &'a RecordIdKey,
record: Arc<Record>,
) -> BoxProviderFut<'a, Result<()>>;
fn del_record<'a>(
&'a self,
ns: NamespaceId,
db: DatabaseId,
tb: &'a TableName,
id: &'a RecordIdKey,
) -> BoxProviderFut<'a, Result<()>>;
}
pub(crate) trait UserProvider: ProviderFutureSendRequirement {
fn all_root_users(
&self,
version: Option<u64>,
) -> BoxProviderFut<'_, Result<Arc<[UserDefinition]>>>;
fn all_ns_users(
&self,
ns: NamespaceId,
version: Option<u64>,
) -> BoxProviderFut<'_, Result<Arc<[catalog::UserDefinition]>>>;
fn all_db_users(
&self,
ns: NamespaceId,
db: DatabaseId,
version: Option<u64>,
) -> BoxProviderFut<'_, Result<Arc<[UserDefinition]>>>;
fn get_root_user<'a>(
&'a self,
us: &'a str,
version: Option<u64>,
) -> BoxProviderFut<'a, Result<Option<Arc<UserDefinition>>>>;
fn put_root_user<'a>(&'a self, us: &'a UserDefinition) -> BoxProviderFut<'a, Result<()>>;
fn get_ns_user<'a>(
&'a self,
ns: NamespaceId,
us: &'a str,
version: Option<u64>,
) -> BoxProviderFut<'a, Result<Option<Arc<UserDefinition>>>>;
fn put_ns_user<'a>(
&'a self,
ns: NamespaceId,
us: &'a UserDefinition,
) -> BoxProviderFut<'a, Result<()>>;
fn get_db_user<'a>(
&'a self,
ns: NamespaceId,
db: DatabaseId,
us: &'a str,
version: Option<u64>,
) -> BoxProviderFut<'a, Result<Option<Arc<UserDefinition>>>>;
fn put_db_user<'a>(
&'a self,
ns: NamespaceId,
db: DatabaseId,
us: &'a UserDefinition,
) -> BoxProviderFut<'a, Result<()>>;
fn expect_root_user<'a>(
&'a self,
us: &'a str,
) -> BoxProviderFut<'a, Result<Arc<UserDefinition>>> {
Box::pin(async move {
match self.get_root_user(us, None).await? {
Some(val) => Ok(val),
None => anyhow::bail!(Error::UserRootNotFound {
name: us.to_owned(),
}),
}
})
}
#[allow(unused)]
fn expect_ns_user<'a>(
&'a self,
ns: NamespaceId,
us: &'a str,
) -> BoxProviderFut<'a, Result<Arc<UserDefinition>>> {
Box::pin(async move {
match self.get_ns_user(ns, us, None).await? {
Some(val) => Ok(val),
None => anyhow::bail!(Error::UserNsNotFound {
name: us.to_owned(),
ns: ns.to_string(),
}),
}
})
}
#[allow(unused)]
fn expect_db_user<'a>(
&'a self,
ns: NamespaceId,
db: DatabaseId,
us: &'a str,
) -> BoxProviderFut<'a, Result<Arc<UserDefinition>>> {
Box::pin(async move {
match self.get_db_user(ns, db, us, None).await? {
Some(val) => Ok(val),
None => anyhow::bail!(Error::UserDbNotFound {
name: us.to_owned(),
ns: ns.to_string(),
db: db.to_string(),
}),
}
})
}
}
pub(crate) trait AuthorisationProvider: ProviderFutureSendRequirement {
fn all_root_accesses(
&self,
version: Option<u64>,
) -> BoxProviderFut<'_, Result<Arc<[catalog::AccessDefinition]>>>;
fn all_root_access_grants<'a>(
&'a self,
ra: &'a str,
version: Option<u64>,
) -> BoxProviderFut<'a, Result<Arc<[catalog::AccessGrant]>>>;
fn all_ns_accesses(
&self,
ns: NamespaceId,
version: Option<u64>,
) -> BoxProviderFut<'_, Result<Arc<[catalog::AccessDefinition]>>>;
fn all_ns_access_grants<'a>(
&'a self,
ns: NamespaceId,
na: &'a str,
version: Option<u64>,
) -> BoxProviderFut<'a, Result<Arc<[catalog::AccessGrant]>>>;
fn all_db_accesses(
&self,
ns: NamespaceId,
db: DatabaseId,
version: Option<u64>,
) -> BoxProviderFut<'_, Result<Arc<[catalog::AccessDefinition]>>>;
fn all_db_access_grants<'a>(
&'a self,
ns: NamespaceId,
db: DatabaseId,
da: &'a str,
version: Option<u64>,
) -> BoxProviderFut<'a, Result<Arc<[catalog::AccessGrant]>>>;
fn get_root_access<'a>(
&'a self,
ra: &'a str,
version: Option<u64>,
) -> BoxProviderFut<'a, Result<Option<Arc<catalog::AccessDefinition>>>>;
fn expect_root_access<'a>(
&'a self,
ra: &'a str,
) -> BoxProviderFut<'a, Result<Arc<catalog::AccessDefinition>>> {
Box::pin(async move {
match self.get_root_access(ra, None).await? {
Some(val) => Ok(val),
None => anyhow::bail!(Error::AccessRootNotFound {
ac: ra.to_owned(),
}),
}
})
}
fn get_root_access_grant<'a>(
&'a self,
ac: &'a str,
gr: &'a str,
version: Option<u64>,
) -> BoxProviderFut<'a, Result<Option<Arc<catalog::AccessGrant>>>>;
fn get_ns_access<'a>(
&'a self,
ns: NamespaceId,
na: &'a str,
version: Option<u64>,
) -> BoxProviderFut<'a, Result<Option<Arc<catalog::AccessDefinition>>>>;
fn get_ns_access_grant<'a>(
&'a self,
ns: NamespaceId,
ac: &'a str,
gr: &'a str,
version: Option<u64>,
) -> BoxProviderFut<'a, Result<Option<Arc<catalog::AccessGrant>>>>;
fn get_db_access<'a>(
&'a self,
ns: NamespaceId,
db: DatabaseId,
da: &'a str,
version: Option<u64>,
) -> BoxProviderFut<'a, Result<Option<Arc<catalog::AccessDefinition>>>>;
fn get_db_access_grant<'a>(
&'a self,
ns: NamespaceId,
db: DatabaseId,
ac: &'a str,
gr: &'a str,
version: Option<u64>,
) -> BoxProviderFut<'a, Result<Option<Arc<catalog::AccessGrant>>>>;
fn del_root_access<'a>(&'a self, ra: &'a str) -> BoxProviderFut<'a, Result<()>>;
fn del_ns_access<'a>(&'a self, ns: NamespaceId, na: &'a str) -> BoxProviderFut<'a, Result<()>>;
fn del_db_access<'a>(
&'a self,
ns: NamespaceId,
db: DatabaseId,
da: &'a str,
) -> BoxProviderFut<'a, Result<()>>;
}
pub(crate) trait ApiProvider: ProviderFutureSendRequirement {
fn all_db_apis(
&self,
ns: NamespaceId,
db: DatabaseId,
version: Option<u64>,
) -> BoxProviderFut<'_, Result<Arc<[catalog::ApiDefinition]>>>;
fn get_db_api<'a>(
&'a self,
ns: NamespaceId,
db: DatabaseId,
ap: &'a str,
version: Option<u64>,
) -> BoxProviderFut<'a, Result<Option<Arc<catalog::ApiDefinition>>>>;
fn put_db_api<'a>(
&'a self,
ns: NamespaceId,
db: DatabaseId,
ap: &'a catalog::ApiDefinition,
) -> BoxProviderFut<'a, Result<()>>;
}
pub(crate) trait BucketProvider: ProviderFutureSendRequirement {
fn all_db_buckets(
&self,
ns: NamespaceId,
db: DatabaseId,
version: Option<u64>,
) -> BoxProviderFut<'_, Result<Arc<[catalog::BucketDefinition]>>>;
fn get_db_bucket<'a>(
&'a self,
ns: NamespaceId,
db: DatabaseId,
bu: &'a str,
version: Option<u64>,
) -> BoxProviderFut<'a, Result<Option<Arc<catalog::BucketDefinition>>>>;
fn expect_db_bucket<'a>(
&'a self,
ns: NamespaceId,
db: DatabaseId,
bu: &'a str,
) -> BoxProviderFut<'a, Result<Arc<catalog::BucketDefinition>>> {
Box::pin(async move {
match self.get_db_bucket(ns, db, bu, None).await? {
Some(val) => Ok(val),
None => anyhow::bail!(Error::BuNotFound {
name: bu.to_owned(),
}),
}
})
}
}
pub(crate) trait CatalogProvider:
NodeProvider
+ NamespaceProvider
+ DatabaseProvider
+ TableProvider
+ UserProvider
+ AuthorisationProvider
+ ApiProvider
+ BucketProvider
{
fn get_or_add_db<'a>(
&'a self,
ctx: Option<&'a Context>,
ns: &'a str,
db: &'a str,
) -> BoxProviderFut<'a, Result<Arc<DatabaseDefinition>>> {
Box::pin(async move { self.get_or_add_db_upwards(ctx, ns, db, false).await })
}
fn ensure_ns_db<'a>(
&'a self,
ctx: Option<&'a Context>,
ns: &'a str,
db: &'a str,
) -> BoxProviderFut<'a, Result<Arc<DatabaseDefinition>>> {
Box::pin(async move { self.get_or_add_db_upwards(ctx, ns, db, true).await })
}
}