use std::marker::PhantomData;
use turso_orm_driver::ConnectionTrait;
use turso_sql::{Build, IntoCondition, Returning, Statement, Value};
use crate::entity::{ActiveModelTrait, EntityTrait, FromQueryResult};
use crate::query::select::pk_condition;
use crate::{DbErr, Result};
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct DeleteResult {
pub rows_affected: u64,
}
#[derive(Clone, Debug)]
pub struct DeleteOne<A: ActiveModelTrait> {
model: A,
}
impl<A: ActiveModelTrait> DeleteOne<A> {
pub(crate) fn new(model: A) -> Self {
Self { model }
}
pub async fn exec<C: ConnectionTrait>(self, db: &C) -> Result<DeleteResult> {
let pk = self
.model
.get_primary_key_value()
.ok_or(DbErr::PrimaryKeyNotSet)?;
DeleteMany::<A::Entity>::new()
.filter_by_pk(pk)
.exec(db)
.await
}
pub async fn exec_with_returning<C: ConnectionTrait>(
self,
db: &C,
) -> Result<<A::Entity as EntityTrait>::Model> {
let pk = self
.model
.get_primary_key_value()
.ok_or(DbErr::PrimaryKeyNotSet)?;
DeleteMany::<A::Entity>::new()
.filter_by_pk(pk)
.exec_with_returning(db)
.await?
.into_iter()
.next()
.ok_or_else(|| DbErr::RecordNotFound("delete".into()))
}
}
#[derive(Clone, Debug)]
pub struct DeleteMany<E: EntityTrait> {
query: turso_sql::Delete,
_e: PhantomData<E>,
}
impl<E: EntityTrait> DeleteMany<E> {
pub(crate) fn new() -> Self {
Self {
query: turso_sql::Query::delete().from_table(E::TABLE_NAME),
_e: PhantomData,
}
}
pub(crate) fn filter_by_pk(mut self, values: Vec<Value>) -> Self {
self.query = self.query.and_where(pk_condition::<E>(values));
self
}
#[must_use]
pub fn filter(mut self, cond: impl IntoCondition) -> Self {
self.query = self.query.and_where(cond);
self
}
pub fn build(&self) -> Statement {
self.query.to_statement()
}
pub async fn exec<C: ConnectionTrait>(self, db: &C) -> Result<DeleteResult> {
let result = db.execute(self.build()).await?;
Ok(DeleteResult {
rows_affected: result.rows_affected,
})
}
pub async fn exec_with_returning<C: ConnectionTrait>(
mut self,
db: &C,
) -> Result<Vec<E::Model>> {
self.query = self.query.returning(Returning::All);
db.query_all(self.build())
.await?
.iter()
.map(|r| E::Model::from_query_result(r, ""))
.collect()
}
}