use std::sync::Arc;
use bson::Document;
use vantage_core::{Result, error};
use super::MongoDB;
#[derive(Debug, Clone)]
#[non_exhaustive]
pub struct MongoView {
pub collection: String,
pub stages: Vec<Document>,
}
impl MongoView {
pub fn new(collection: impl Into<String>, stages: Vec<Document>) -> Self {
Self {
collection: collection.into(),
stages,
}
}
}
impl MongoDB {
pub fn with_view(mut self, view: MongoView) -> Self {
self.view = Some(Arc::new(view));
self
}
#[cfg(feature = "vista")]
pub(crate) fn without_view(mut self) -> Self {
self.view = None;
self
}
pub fn view(&self) -> Option<&MongoView> {
self.view.as_deref()
}
pub(crate) fn view_stages(&self) -> Vec<Document> {
self.view().map(|v| v.stages.clone()).unwrap_or_default()
}
pub(crate) fn read_collection_name<'a>(&'a self, table_name: &'a str) -> &'a str {
match self.view() {
Some(view) => &view.collection,
None => table_name,
}
}
pub(crate) fn read_collection(&self, table_name: &str) -> mongodb::Collection<Document> {
self.doc_collection(self.read_collection_name(table_name))
}
pub(crate) fn ensure_writable(&self) -> Result<()> {
match self.view() {
Some(view) => Err(error!(
"MongoDB pipeline view is read-only",
collection = view.collection.clone()
)
.mark_unsupported()),
None => Ok(()),
}
}
#[cfg(feature = "vista")]
pub(crate) fn ensure_watchable(&self) -> Result<()> {
match self.view() {
Some(view) => Err(error!(
"MongoDB pipeline view has no change stream",
collection = view.collection.clone()
)
.mark_unsupported()),
None => Ok(()),
}
}
}