use std::marker::PhantomData;
use rorm_db::database;
use rorm_db::error::Error;
use rorm_db::executor::Executor;
use crate::conditions::{Condition, DynamicCollection};
use crate::crud::selector::Selector;
use crate::internal::patch::{IntoPatchCow, PatchCow};
use crate::internal::query_context::QueryContext;
use crate::model::{Identifiable, Model};
use crate::Patch;
pub fn delete<'ex, E, S>(executor: E, _: S) -> DeleteBuilder<E, S::Model>
where
E: Executor<'ex>,
S: Selector<Model: Patch<ValueSpaceImpl = S>>,
{
DeleteBuilder {
executor,
_phantom: PhantomData,
}
}
#[must_use]
pub struct DeleteBuilder<E, M> {
executor: E,
_phantom: PhantomData<M>,
}
impl<'ex, E, M> DeleteBuilder<E, M>
where
E: Executor<'ex>,
M: Model,
{
pub async fn single<P>(self, patch: &P) -> Result<u64, Error>
where
P: Patch<Model = M> + Identifiable,
{
self.condition(patch.as_condition()).await
}
pub async fn bulk<'p, I, P>(self, patches: I) -> Result<u64, Error>
where
I: IntoIterator,
I::Item: IntoPatchCow<'p, Patch = P>,
P: Patch<Model = M> + Identifiable,
{
let mut owned = Vec::new();
let mut conditions = Vec::new();
for patch in patches {
match patch.into_patch_cow() {
PatchCow::Borrowed(patch) => conditions.push(patch.as_condition()),
PatchCow::Owned(patch) => owned.push(patch),
}
}
for patch in &owned {
conditions.push(patch.as_condition());
}
if let Some(condition) = DynamicCollection::or(conditions) {
self.condition(condition).await
} else {
Ok(0)
}
}
pub async fn condition<'c, C: Condition<'c>>(self, condition: C) -> Result<u64, Error> {
let mut context = QueryContext::new();
let condition_index = context.add_condition(&condition);
database::delete(
self.executor,
M::TABLE,
Some(&context.get_condition(condition_index)),
)
.await
}
pub async fn all(self) -> Result<u64, Error> {
database::delete(self.executor, M::TABLE, None).await
}
}