add partials

This commit is contained in:
JMARyA 2024-07-18 16:48:21 +02:00
parent 0cb1e28c20
commit c7f0caf34a
Signed by: jmarya
GPG key ID: 901B2ADDF27C2263
3 changed files with 139 additions and 2 deletions

View file

@ -1,5 +1,9 @@
use mongodb::results::{DeleteResult, InsertOneResult};
use mongodb::{
options::{FindOneOptions, FindOptions},
results::{DeleteResult, InsertOneResult},
};
use reference::Referencable;
use serde::de::DeserializeOwned;
use serde_json::{Map, Value};
use valid::Validate;
@ -26,6 +30,8 @@ pub enum UpdateError {
pub trait Model:
Sized + Referencable + Validate + serde::Serialize + for<'a> serde::Deserialize<'a>
{
type Partial: DeserializeOwned;
/// Insert the `Model` into the database
fn insert(
&self,
@ -77,8 +83,56 @@ pub trait Model:
}
}
/// Get a partial `Model` by id from the database with only some fields retrieved.
#[must_use]
fn get_partial(
id: &str,
part: &serde_json::Value,
) -> impl std::future::Future<Output = Option<Self::Partial>> {
async move {
let db = get_mongo!();
let collection = col!(db, Self::collection_name());
let doc = collection
.find_one(
id_of!(id),
Some(
FindOneOptions::builder()
.projection(Some(mongodb::bson::to_document(part).unwrap()))
.build(),
),
)
.await
.ok()??;
mongodb::bson::from_document(doc).ok()
}
}
/// Get a `Model` by using a filter from the database
#[must_use]
fn find_one_partial(
filter: mongodb::bson::Document,
part: &serde_json::Value,
) -> impl std::future::Future<Output = Option<Self::Partial>> {
async move {
let db = get_mongo!();
let collection = col!(db, Self::collection_name());
let doc = collection
.find_one(
filter,
Some(
FindOneOptions::builder()
.projection(Some(mongodb::bson::to_document(part).unwrap()))
.build(),
),
)
.await
.ok()??;
mongodb::bson::from_document(doc).ok()
}
}
/// Get a partial `Model` by using a filter from the database
#[must_use]
fn find_one(
filter: mongodb::bson::Document,
) -> impl std::future::Future<Output = Option<Self>> {
@ -106,6 +160,33 @@ pub trait Model:
}
}
/// Get multiple partial `Model`s by using a filter from the database
#[must_use]
fn find_partial(
filter: mongodb::bson::Document,
part: &serde_json::Value,
) -> 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,
Some(
FindOptions::builder()
.projection(Some(mongodb::bson::to_document(part).unwrap()))
.build(),
),
)
.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
fn update(
&mut self,