add error handling + find

This commit is contained in:
JMARyA 2024-07-18 14:03:07 +02:00
parent 3e73dd0d20
commit 97348a9275
Signed by: jmarya
GPG key ID: 901B2ADDF27C2263
2 changed files with 47 additions and 8 deletions

View file

@ -4,6 +4,7 @@ pub use model::reference::*;
pub use model::valid::Validate; pub use model::valid::Validate;
pub use model::Model; pub use model::Model;
pub use mongod_derive as derive; pub use mongod_derive as derive;
pub use mongodb;
/// Get a `MongoDB` Client from the environment /// Get a `MongoDB` Client from the environment
#[macro_export] #[macro_export]

View file

@ -1,21 +1,24 @@
use mongodb::results::{DeleteResult, InsertOneResult};
use reference::Referencable; use reference::Referencable;
use serde_json::{Map, Value}; use serde_json::{Map, Value};
use valid::Validate; use valid::Validate;
use crate::{col, get_mongo, id_of}; use crate::{col, collect_results, get_mongo, id_of};
pub mod historic; pub mod historic;
pub mod reference; pub mod reference;
pub mod update; pub mod update;
pub mod valid; pub mod valid;
// todo : use mongodb projection to only get fields you actually use, maybe PartialModel shadow struct?
/// Error type when updating a model /// Error type when updating a model
#[derive(Debug)] #[derive(Debug)]
pub enum UpdateError { pub enum UpdateError {
/// Provided data was no object /// Provided data was no object
NoObject, NoObject,
/// Database related error /// Database related error
Database, Database(mongodb::error::Error),
/// Validation failed /// Validation failed
Validation, Validation,
} }
@ -24,7 +27,9 @@ pub trait Model:
Sized + Referencable + Validate + serde::Serialize + for<'a> serde::Deserialize<'a> Sized + Referencable + Validate + serde::Serialize + for<'a> serde::Deserialize<'a>
{ {
/// Insert the `Model` into the database /// Insert the `Model` into the database
fn insert(&self) -> impl std::future::Future<Output = ()> + Send fn insert(
&self,
) -> impl std::future::Future<Output = Result<InsertOneResult, mongodb::error::Error>> + Send
where where
Self: Sync, Self: Sync,
{ {
@ -34,23 +39,27 @@ pub trait Model:
collection collection
.insert_one(mongodb::bson::to_document(self).unwrap(), None) .insert_one(mongodb::bson::to_document(self).unwrap(), None)
.await .await
.unwrap();
} }
} }
/// Remove a `Model` from the database. /// Remove a `Model` from the database.
fn remove(id: &str) -> impl std::future::Future<Output = ()> + Send { #[must_use]
fn remove(
id: &str,
) -> impl std::future::Future<Output = Result<DeleteResult, mongodb::error::Error>> + Send {
async move { async move {
let db = get_mongo!(); let db = get_mongo!();
let collection = col!(db, Self::collection_name()); let collection = col!(db, Self::collection_name());
collection.delete_one(id_of!(id), None).await.unwrap(); collection.delete_one(id_of!(id), None).await
} }
} }
/// Remove a `Model` from the database. /// Remove a `Model` from the database.
/// ///
/// This is a convenience function to let you call `remove()` on a `Model` you have at hand. /// This is a convenience function to let you call `remove()` on a `Model` you have at hand.
fn delete(&self) -> impl std::future::Future<Output = ()> + Send fn delete(
&self,
) -> impl std::future::Future<Output = Result<DeleteResult, mongodb::error::Error>> + Send
where where
Self: Sync, Self: Sync,
{ {
@ -68,6 +77,35 @@ pub trait Model:
} }
} }
/// Get a `Model` by using a filter from the database
#[must_use]
fn find_one(
filter: mongodb::bson::Document,
) -> impl std::future::Future<Output = Option<Self>> {
async move {
let db = get_mongo!();
let collection = col!(db, Self::collection_name());
let doc = collection.find_one(filter, None).await.ok()??;
mongodb::bson::from_document(doc).ok()
}
}
/// Get multiple `Model`s by using a filter from the database
#[must_use]
fn find(
filter: mongodb::bson::Document,
) -> impl std::future::Future<Output = Option<Vec<Self>>> {
async move {
let db = get_mongo!();
let collection = col!(db, Self::collection_name());
let mut results = collection.find(filter, None).await.ok()?;
let docs = collect_results!(results);
docs.into_iter()
.map(|x| mongodb::bson::from_document(x).unwrap())
.collect()
}
}
/// Update values of `Model` into database /// Update values of `Model` into database
fn update( fn update(
&mut self, &mut self,
@ -92,7 +130,7 @@ pub trait Model:
None, None,
) )
.await .await
.map_err(|_| UpdateError::Database)?; .map_err(UpdateError::Database)?;
return Ok(()); return Ok(());
} }
return Err(UpdateError::Validation); return Err(UpdateError::Validation);