use super::select::{CompletedSelect, IntoSelectQuery};
use crate::{traits::MySQLTable, values::MySQLValue};
use drizzle_core::{
IncludesRequired, InsertSelectCompatible, InsertSelectTable, InsertTargetColumns,
PartialInsertSelectCompatible, ToSQL,
};
pub use drizzle_core::builder::{InsertColumnsSet, InsertInitial, InsertValuesSet};
#[derive(Debug, Clone, Copy, Default)]
pub struct InsertIgnoreSet;
#[derive(Debug, Clone, Copy, Default)]
pub struct InsertOnDuplicateKeyUpdateSet;
impl drizzle_core::ExecutableState for InsertOnDuplicateKeyUpdateSet {}
pub type InsertBuilder<'a, Schema, State, Table, Marker = (), Row = ()> =
super::QueryBuilder<'a, Schema, State, Table, Marker, Row>;
impl<'a, S, T, M, R> InsertBuilder<'a, S, InsertValuesSet, T, M, R> {
#[must_use]
pub fn prepare(&self) -> drizzle_core::prepared::PreparedStatement<'a, MySQLValue<'a>> {
self.prepared_statement()
}
#[track_caller]
pub fn on_duplicate_key_update(
self,
values: T::Update,
) -> InsertBuilder<'a, S, InsertOnDuplicateKeyUpdateSet, T, M, R>
where
T: MySQLTable<'a>,
{
let sql = crate::helpers::on_duplicate_key_update::<T>(&values);
drop(values);
InsertBuilder::from_sql(self.sql.append(sql))
}
}
impl<'a, S, T, M, R> InsertBuilder<'a, S, InsertOnDuplicateKeyUpdateSet, T, M, R> {
#[must_use]
pub fn prepare(&self) -> drizzle_core::prepared::PreparedStatement<'a, MySQLValue<'a>> {
self.prepared_statement()
}
}
impl<'a, Schema, Table> InsertBuilder<'a, Schema, InsertInitial, Table>
where
Table: MySQLTable<'a>,
{
#[must_use]
pub fn ignore(self) -> InsertBuilder<'a, Schema, InsertIgnoreSet, Table> {
InsertBuilder::from_sql(crate::helpers::insert_ignore(self.sql))
}
}
#[doc(hidden)]
pub trait InsertRowSourceState {}
impl InsertRowSourceState for InsertInitial {}
impl InsertRowSourceState for InsertIgnoreSet {}
impl<'a, Schema, State, Table> InsertBuilder<'a, Schema, State, Table>
where
State: InsertRowSourceState,
Table: MySQLTable<'a>,
{
pub fn columns<Columns>(
self,
columns: Columns,
) -> InsertBuilder<'a, Schema, InsertColumnsSet<Columns::Columns>, Table>
where
Columns: InsertTargetColumns<'a, MySQLValue<'a>, Table>,
{
InsertBuilder::from_sql(self.sql.append(columns.into_target_columns_sql()))
}
pub fn value<T>(
self,
value: Table::Insert<T>,
) -> InsertBuilder<'a, Schema, InsertValuesSet, Table> {
self.values([value])
}
#[track_caller]
pub fn values<I, T>(self, values: I) -> InsertBuilder<'a, Schema, InsertValuesSet, Table>
where
I: IntoIterator<Item = Table::Insert<T>>,
{
InsertBuilder::from_sql(
self.sql
.append(crate::helpers::values::<'a, Table, T>(values)),
)
}
pub fn select<Q, R, ScopeProof, AggProof>(
self,
query: Q,
) -> InsertBuilder<'a, Schema, InsertValuesSet, Table>
where
Table: InsertSelectTable,
Q: IntoSelectQuery<'a, Schema, R>,
Q::Marker: InsertSelectCompatible<'a, MySQLValue<'a>, Table, R>
+ drizzle_core::InsertSourceInScope<ScopeProof>
+ drizzle_core::MarkerAggValidFor<Q::Grouped, AggProof>,
{
InsertBuilder::from_sql(
self.sql
.append(Table::insert_columns_sql::<MySQLValue<'a>>())
.append(query.into_select_query().into_select_sql()),
)
}
pub fn select_raw<Q>(self, query: Q) -> InsertBuilder<'a, Schema, InsertValuesSet, Table>
where
Q: ToSQL<'a, MySQLValue<'a>>,
{
InsertBuilder::from_sql(self.sql.append(query.into_sql()))
}
}
impl<'a, Schema, Table, Targets> InsertBuilder<'a, Schema, InsertColumnsSet<Targets>, Table>
where
Table: MySQLTable<'a>,
{
pub fn select<Q, R, RequiredProof, ScopeProof, AggProof>(
self,
query: Q,
) -> InsertBuilder<'a, Schema, InsertValuesSet, Table>
where
Targets: IncludesRequired<Table::RequiredColumns, RequiredProof>,
Table: InsertSelectTable,
Q: IntoSelectQuery<'a, Schema, R>,
Q::Marker: PartialInsertSelectCompatible<'a, MySQLValue<'a>, Targets>
+ drizzle_core::InsertSourceInScope<ScopeProof>
+ drizzle_core::MarkerAggValidFor<Q::Grouped, AggProof>,
{
InsertBuilder::from_sql(self.sql.append(query.into_select_query().into_select_sql()))
}
pub fn select_raw<Q, RequiredProof>(
self,
query: Q,
) -> InsertBuilder<'a, Schema, InsertValuesSet, Table>
where
Table: InsertSelectTable,
Targets: IncludesRequired<Table::RequiredColumns, RequiredProof>,
Q: ToSQL<'a, MySQLValue<'a>>,
{
InsertBuilder::from_sql(self.sql.append(query.into_sql()))
}
}