use crate::{
backend::QueryBuilder, error::*, prepare::*, types::*, value::*, Expr, Query,
QueryStatementBuilder, SelectExpr, SelectStatement, SimpleExpr,
};
#[derive(Debug, Default, Clone)]
pub struct InsertStatement {
pub(crate) table: Option<Box<TableRef>>,
pub(crate) columns: Vec<DynIden>,
pub(crate) values: Vec<Vec<SimpleExpr>>,
pub(crate) returning: Vec<SelectExpr>,
}
impl InsertStatement {
pub fn new() -> Self {
Self::default()
}
#[allow(clippy::wrong_self_convention)]
pub fn into_table<T>(&mut self, tbl_ref: T) -> &mut Self
where
T: IntoTableRef,
{
self.table = Some(Box::new(tbl_ref.into_table_ref()));
self
}
pub fn columns<C, I>(&mut self, columns: I) -> &mut Self
where
C: IntoIden,
I: IntoIterator<Item = C>,
{
self.columns = columns.into_iter().map(|c| c.into_iden()).collect();
self
}
pub fn values<I>(&mut self, values: I) -> Result<&mut Self>
where
I: IntoIterator<Item = Value>,
{
let values = values
.into_iter()
.map(|v| Expr::val(v).into())
.collect::<Vec<SimpleExpr>>();
if self.columns.len() != values.len() {
return Err(Error::ColValNumMismatch {
col_len: self.columns.len(),
val_len: values.len(),
});
}
self.values.push(values);
Ok(self)
}
pub fn exprs<I>(&mut self, values: I) -> Result<&mut Self>
where
I: IntoIterator<Item = SimpleExpr>,
{
let values = values.into_iter().collect::<Vec<SimpleExpr>>();
if self.columns.len() != values.len() {
return Err(Error::ColValNumMismatch {
col_len: self.columns.len(),
val_len: values.len(),
});
}
self.values.push(values);
Ok(self)
}
pub fn values_panic<I>(&mut self, values: I) -> &mut Self
where
I: IntoIterator<Item = Value>,
{
self.values(values).unwrap()
}
pub fn exprs_panic<I>(&mut self, values: I) -> &mut Self
where
I: IntoIterator<Item = SimpleExpr>,
{
self.exprs(values).unwrap()
}
pub fn returning(&mut self, select: SelectStatement) -> &mut Self {
self.returning = select.selects;
self
}
pub fn returning_col<C>(&mut self, col: C) -> &mut Self
where
C: IntoIden,
{
self.returning(Query::select().column(col.into_iden()).take())
}
}
impl QueryStatementBuilder for InsertStatement {
fn build_collect<T: QueryBuilder>(
&self,
query_builder: T,
collector: &mut dyn FnMut(Value),
) -> String {
let mut sql = SqlWriter::new();
query_builder.prepare_insert_statement(self, &mut sql, collector);
sql.result()
}
fn build_collect_any(
&self,
query_builder: &dyn QueryBuilder,
collector: &mut dyn FnMut(Value),
) -> String {
let mut sql = SqlWriter::new();
query_builder.prepare_insert_statement(self, &mut sql, collector);
sql.result()
}
}