use std::borrow::Borrow;
use std::fmt::Debug;
use std::marker::PhantomData;
use bson::{Bson, Document};
use bson::oid::ObjectId;
use mongodb::{Collection, Database};
use mongodb::error::Error;
use mongodb::options::{FindOneOptions, FindOptions};
use opentelemetry::{Context, global, KeyValue};
use crate::document::document::BaseDocument;
use crate::document::pageable::{PageableRequest, PageableResponse};
use crate::repository::base_repository::Repository;
use async_trait::async_trait;
use opentelemetry::trace::{Span, TraceContextExt, Tracer};
pub struct MongoRepository<T: BaseDocument + Debug + serde::ser::Serialize + for<'de> serde::Deserialize<'de> + Sync + Send> {
pub database: Database,
pub x: PhantomData<T>,
pub collection: Collection<T>
}
impl<T: BaseDocument + Debug + serde::ser::Serialize + for<'de> serde::Deserialize<'de> + Sync + Send> MongoRepository<T> {
pub fn convert_bson_to_entity(&self, doc: Document) -> Result<T, Error> {
match bson::from_bson(Bson::Document(doc)) {
Ok(entity) => Ok(entity),
Err(err) => {
Err(Error::custom(err))
}
}
}
}
#[async_trait]
impl<T: BaseDocument + Debug + serde::ser::Serialize + for<'de> serde::Deserialize<'de> + Sync + Send> Repository<T> for MongoRepository<T> {
async fn save(&self, entity: T, ctx: Option<&Context>) -> Result<ObjectId, Error> {
if let Some(u_ctx) = ctx {
let mut span =
global::tracer("opentelemetry").start_with_context("save", u_ctx);
span.set_attribute(KeyValue::new("method", "save"));
span.set_attribute(KeyValue::new("system", "mongodb"));
u_ctx.with_span(span);
}
let result = match self.collection.insert_one(entity, None).await {
Ok(res) => res,
Err(e) => return Err(Error::custom(e)),
};
match result.inserted_id.as_object_id() {
None => Err(Error::custom("could not get object id saved object..")),
Some(oid) => Ok(oid),
}
}
async fn save_many(&self, entities: Vec<T>, ctx: Option<&Context>) -> Result<Vec<ObjectId>, Error> {
let mut ids:Vec<ObjectId> = vec![];
for entity in entities {
let saved = self.save(entity, ctx)
.await?;
ids.push(saved);
};
Ok(ids)
}
async fn get_all_pageable(&self, request: PageableRequest, ctx: Option<&Context>) -> Result<PageableResponse<T>, Error> {
todo!()
}
async fn count_documents_in_collection(&self, ctx: Option<&Context>) -> Result<u64, Error> {
todo!()
}
async fn find_by_id(&self, id: &str, ctx: Option<&Context>) -> Result<T, Error> {
todo!()
}
async fn find_by_raw_id(&self, id: ObjectId, ctx: Option<&Context>) -> Result<T, Error> {
todo!()
}
async fn find_by_ids(&self, ids: Vec<String>, ctx: Option<&Context>) -> Result<Vec<T>, Error> {
todo!()
}
async fn find_by_raw_ids(&self, pids: Vec<ObjectId>, ctx: Option<&Context>) -> Result<Vec<T>, Error> {
todo!()
}
async fn find_by_filter_and_options(&self, filter: Document, options: Option<FindOneOptions>, ctx: Option<&Context>) -> Result<T, Error> {
todo!()
}
async fn find_all_by_filter_and_options(&self, filter: Document, options: Option<FindOptions>, ctx: Option<&Context>) -> Result<Vec<T>, Error> {
todo!()
}
async fn update(&self, entity: &T, ctx: Option<&Context>) -> Result<ObjectId, Error> {
todo!()
}
async fn delete(&self, pid: String, ctx: Option<&Context>) -> Result<(), Error> {
todo!()
}
}