use crate::{
Executor, Result,
schema::Model,
stmt::{Expr, Insert, IntoExpr, IntoInsert, List},
};
use toasty_core::stmt as core_stmt;
pub struct CreateMany<M: Model> {
stmts: Vec<Insert<M>>,
}
impl<M: Model> CreateMany<M> {
pub fn new() -> Self {
Self::default()
}
pub fn item(mut self, item: impl IntoInsert<Model = M>) -> Self {
let stmt = item.into_insert();
assert!(
stmt.untyped.source.single,
"BUG: insert statement should have `single` flag set"
);
self.stmts.push(stmt);
self
}
pub fn with_item(
mut self,
f: impl FnOnce(<M as Model>::Create) -> <M as Model>::Create,
) -> Self {
let create = f(M::new_create());
let stmt = create.into_insert();
assert!(
stmt.untyped.source.single,
"BUG: insert statement should have `single` flag set"
);
self.stmts.push(stmt);
self
}
pub fn into_expr(self) -> Expr<List<M>> {
if self.stmts.is_empty() {
return Expr::from_untyped(
core_stmt::Expr::list(std::iter::empty::<core_stmt::Expr>()),
);
}
let mut stmts = self.stmts.into_iter();
let mut merged = stmts.next().unwrap();
for stmt in stmts {
merged.merge(stmt);
}
merged.untyped.source.single = false;
merged.into_list_expr()
}
pub async fn exec(self, executor: &mut dyn Executor) -> Result<Vec<M>> {
if self.stmts.is_empty() {
return Ok(vec![]);
}
let mut stmts = self.stmts.into_iter();
let mut merged = stmts.next().unwrap();
for stmt in stmts {
merged.merge(stmt);
}
merged.untyped.source.single = false;
let stmt: crate::Statement<List<M>> =
crate::Statement::from_untyped_stmt(merged.untyped.into());
executor.exec(stmt).await
}
}
impl<M: Model> IntoExpr<List<M>> for CreateMany<M> {
fn into_expr(self) -> Expr<List<M>> {
self.into_expr()
}
fn by_ref(&self) -> Expr<List<M>> {
todo!()
}
}
impl<M: Model> Default for CreateMany<M> {
fn default() -> Self {
Self { stmts: vec![] }
}
}