1use std::marker::PhantomData;
2
3use crate::backend::{sql_dialect, Backend, DieselReserveSpecialization, SqlDialect};
4use crate::expression::grouped::Grouped;
5use crate::expression::{AppearsOnTable, Expression};
6use crate::query_builder::{
7 AstPass, BatchInsert, InsertStatement, NoFromClause, QueryFragment, QueryId,
8 UndecoratedInsertRecord, ValuesClause,
9};
10use crate::query_source::{Column, Table};
11use crate::result::QueryResult;
12
13pub trait Insertable<T> {
19 type Values;
26
27 fn values(self) -> Self::Values;
32
33 fn insert_into(self, table: T) -> InsertStatement<T, Self::Values>
65 where
66 T: Table,
67 Self: Sized,
68 {
69 crate::insert_into(table).values(self)
70 }
71}
72
73#[doc(inline)]
74pub use diesel_derives::Insertable;
75
76pub trait CanInsertInSingleQuery<DB: Backend> {
77 fn rows_to_insert(&self) -> Option<usize>;
82}
83
84impl<T, DB> CanInsertInSingleQuery<DB> for &T
85where
86 T: ?Sized + CanInsertInSingleQuery<DB>,
87 DB: Backend,
88{
89 fn rows_to_insert(&self) -> Option<usize> {
90 (*self).rows_to_insert()
91 }
92}
93
94impl<T, U, DB> CanInsertInSingleQuery<DB> for ColumnInsertValue<T, U>
95where
96 DB: Backend,
97{
98 fn rows_to_insert(&self) -> Option<usize> {
99 Some(1)
100 }
101}
102
103impl<V, DB> CanInsertInSingleQuery<DB> for DefaultableColumnInsertValue<V>
104where
105 DB: Backend,
106 V: CanInsertInSingleQuery<DB>,
107{
108 fn rows_to_insert(&self) -> Option<usize> {
109 Some(1)
110 }
111}
112
113pub trait InsertValues<DB: Backend, T: Table>: QueryFragment<DB> {
114 fn column_names(&self, out: AstPass<'_, '_, DB>) -> QueryResult<()>;
115}
116
117#[derive(Debug, Copy, Clone, QueryId)]
118#[doc(hidden)]
119pub struct ColumnInsertValue<Col, Expr> {
120 pub(crate) expr: Expr,
121 p: PhantomData<Col>,
122}
123
124impl<Col, Expr> ColumnInsertValue<Col, Expr> {
125 pub(crate) fn new(expr: Expr) -> Self {
126 Self {
127 expr,
128 p: PhantomData,
129 }
130 }
131}
132
133#[derive(Debug, Default, Copy, Clone)]
134#[doc(hidden)]
135pub enum DefaultableColumnInsertValue<T> {
136 Expression(T),
137 #[default]
138 Default,
139}
140
141impl<T> QueryId for DefaultableColumnInsertValue<T> {
142 type QueryId = ();
143 const HAS_STATIC_QUERY_ID: bool = false;
144}
145
146impl<Col, Expr, DB> InsertValues<DB, Col::Table>
147 for DefaultableColumnInsertValue<ColumnInsertValue<Col, Expr>>
148where
149 DB: Backend + SqlDialect<InsertWithDefaultKeyword = sql_dialect::default_keyword_for_insert::IsoSqlDefaultKeyword>,
150 Col: Column,
151 Expr: Expression<SqlType = Col::SqlType> + AppearsOnTable<NoFromClause>,
152 Self: QueryFragment<DB>,
153{
154 fn column_names(&self, mut out: AstPass<'_, '_, DB>) -> QueryResult<()> {
155 out.push_identifier(Col::NAME)?;
156 Ok(())
157 }
158}
159
160impl<Col, Expr, DB> InsertValues<DB, Col::Table> for ColumnInsertValue<Col, Expr>
161where
162 DB: Backend,
163 Col: Column,
164 Expr: Expression<SqlType = Col::SqlType> + AppearsOnTable<NoFromClause>,
165 Self: QueryFragment<DB>,
166{
167 fn column_names(&self, mut out: AstPass<'_, '_, DB>) -> QueryResult<()> {
168 out.push_identifier(Col::NAME)?;
169 Ok(())
170 }
171}
172
173impl<Expr, DB> QueryFragment<DB> for DefaultableColumnInsertValue<Expr>
174where
175 DB: Backend,
176 Self: QueryFragment<DB, DB::InsertWithDefaultKeyword>,
177{
178 fn walk_ast<'b>(&'b self, pass: AstPass<'_, 'b, DB>) -> QueryResult<()> {
179 <Self as QueryFragment<DB, DB::InsertWithDefaultKeyword>>::walk_ast(self, pass)
180 }
181}
182
183impl<Expr, DB> QueryFragment<DB, sql_dialect::default_keyword_for_insert::IsoSqlDefaultKeyword> for DefaultableColumnInsertValue<Expr>
184where
185 DB: Backend + SqlDialect<InsertWithDefaultKeyword = sql_dialect::default_keyword_for_insert::IsoSqlDefaultKeyword>,
186 Expr: QueryFragment<DB>,
187{
188 fn walk_ast<'b>(&'b self, mut out: AstPass<'_, 'b, DB>) -> QueryResult<()> {
189 out.unsafe_to_cache_prepared();
190 if let Self::Expression(ref inner) = *self {
191 inner.walk_ast(out.reborrow())?;
192 } else {
193 out.push_sql("DEFAULT");
194 }
195 Ok(())
196 }
197}
198
199impl<Col, Expr, DB> QueryFragment<DB> for ColumnInsertValue<Col, Expr>
200where
201 DB: Backend + DieselReserveSpecialization,
202 Expr: QueryFragment<DB>,
203{
204 fn walk_ast<'b>(&'b self, pass: AstPass<'_, 'b, DB>) -> QueryResult<()> {
205 self.expr.walk_ast(pass)
206 }
207}
208
209#[cfg(feature = "sqlite")]
210impl<Col, Expr> InsertValues<crate::sqlite::Sqlite, Col::Table>
211 for DefaultableColumnInsertValue<ColumnInsertValue<Col, Expr>>
212where
213 Col: Column,
214 Expr: Expression<SqlType = Col::SqlType> + AppearsOnTable<NoFromClause>,
215 Self: QueryFragment<crate::sqlite::Sqlite>,
216{
217 fn column_names(&self, mut out: AstPass<'_, '_, crate::sqlite::Sqlite>) -> QueryResult<()> {
218 if let Self::Expression(..) = *self {
219 out.push_identifier(Col::NAME)?;
220 }
221 Ok(())
222 }
223}
224
225#[cfg(feature = "sqlite")]
226impl<Col, Expr>
227 QueryFragment<
228 crate::sqlite::Sqlite,
229 crate::backend::sql_dialect::default_keyword_for_insert::DoesNotSupportDefaultKeyword,
230 > for DefaultableColumnInsertValue<ColumnInsertValue<Col, Expr>>
231where
232 Expr: QueryFragment<crate::sqlite::Sqlite>,
233{
234 fn walk_ast<'b>(&'b self, mut out: AstPass<'_, 'b, crate::sqlite::Sqlite>) -> QueryResult<()> {
235 if let Self::Expression(ref inner) = *self {
236 inner.walk_ast(out.reborrow())?;
237 }
238 Ok(())
239 }
240}
241
242impl<'a, T, Tab> Insertable<Tab> for &'a [T]
243where
244 &'a T: UndecoratedInsertRecord<Tab> + Insertable<Tab>,
245{
246 type Values = BatchInsert<Vec<<&'a T as Insertable<Tab>>::Values>, Tab, (), false>;
247
248 fn values(self) -> Self::Values {
249 let values = self.iter().map(Insertable::values).collect::<Vec<_>>();
250 BatchInsert::new(values)
251 }
252}
253
254impl<'a, T, Tab> Insertable<Tab> for &'a Vec<T>
255where
256 &'a [T]: Insertable<Tab>,
257{
258 type Values = <&'a [T] as Insertable<Tab>>::Values;
259
260 fn values(self) -> Self::Values {
261 (&**self).values()
262 }
263}
264
265impl<T, Tab> Insertable<Tab> for Vec<T>
266where
267 T: Insertable<Tab> + UndecoratedInsertRecord<Tab>,
268{
269 type Values = BatchInsert<Vec<T::Values>, Tab, (), false>;
270
271 fn values(self) -> Self::Values {
272 let values = self.into_iter().map(Insertable::values).collect::<Vec<_>>();
273 BatchInsert::new(values)
274 }
275}
276
277impl<T, Tab, const N: usize> Insertable<Tab> for [T; N]
278where
279 T: Insertable<Tab>,
280{
281 type Values = BatchInsert<Vec<T::Values>, Tab, [T::Values; N], true>;
282
283 fn values(self) -> Self::Values {
284 let values = self.into_iter().map(Insertable::values).collect::<Vec<_>>();
285 BatchInsert::new(values)
286 }
287}
288
289impl<'a, T, Tab, const N: usize> Insertable<Tab> for &'a [T; N]
290where
291 T: Insertable<Tab>,
292 &'a T: Insertable<Tab>,
293{
294 type Values = BatchInsert<Vec<<&'a T as Insertable<Tab>>::Values>, Tab, [T::Values; N], true>;
297
298 fn values(self) -> Self::Values {
299 let values = self.iter().map(Insertable::values).collect();
300 BatchInsert::new(values)
301 }
302}
303
304impl<T, Tab, const N: usize> Insertable<Tab> for Box<[T; N]>
305where
306 T: Insertable<Tab>,
307{
308 type Values = BatchInsert<Vec<T::Values>, Tab, [T::Values; N], true>;
311
312 fn values(self) -> Self::Values {
313 let v = Vec::from(self as Box<[T]>);
314 let values = v.into_iter().map(Insertable::values).collect::<Vec<_>>();
315 BatchInsert::new(values)
316 }
317}
318
319mod private {
320 #[allow(missing_debug_implementations)]
323 pub struct InsertableOptionHelper<T, V>(
324 pub(crate) Option<T>,
325 pub(crate) std::marker::PhantomData<V>,
326 );
327}
328
329pub(crate) use self::private::InsertableOptionHelper;
330
331impl<T, Tab, V> Insertable<Tab> for Option<T>
332where
333 T: Insertable<Tab, Values = ValuesClause<V, Tab>>,
334 InsertableOptionHelper<T, V>: Insertable<Tab>,
335{
336 type Values = <InsertableOptionHelper<T, V> as Insertable<Tab>>::Values;
337
338 fn values(self) -> Self::Values {
339 InsertableOptionHelper(self, PhantomData).values()
340 }
341}
342
343impl<T, Tab, Expr, Col> Insertable<Tab> for InsertableOptionHelper<T, ColumnInsertValue<Col, Expr>>
344where
345 T: Insertable<Tab, Values = ValuesClause<ColumnInsertValue<Col, Expr>, Tab>>,
346{
347 type Values = ValuesClause<DefaultableColumnInsertValue<ColumnInsertValue<Col, Expr>>, Tab>;
348
349 fn values(self) -> Self::Values {
350 ValuesClause::new(
351 self.0
352 .map(|v| DefaultableColumnInsertValue::Expression(Insertable::values(v).values))
353 .unwrap_or_default(),
354 )
355 }
356}
357
358impl<'a, T, Tab> Insertable<Tab> for &'a Option<T>
359where
360 Option<&'a T>: Insertable<Tab>,
361{
362 type Values = <Option<&'a T> as Insertable<Tab>>::Values;
363
364 fn values(self) -> Self::Values {
365 self.as_ref().values()
366 }
367}
368
369impl<L, R, Tab> Insertable<Tab> for Grouped<crate::expression::operators::Eq<L, R>>
370where
371 crate::expression::operators::Eq<L, R>: Insertable<Tab>,
372{
373 type Values = <crate::expression::operators::Eq<L, R> as Insertable<Tab>>::Values;
374
375 fn values(self) -> Self::Values {
376 self.0.values()
377 }
378}
379
380impl<'a, L, R, Tab> Insertable<Tab> for &'a Grouped<crate::expression::operators::Eq<L, R>>
381where
382 &'a crate::expression::operators::Eq<L, R>: Insertable<Tab>,
383{
384 type Values = <&'a crate::expression::operators::Eq<L, R> as Insertable<Tab>>::Values;
385
386 fn values(self) -> Self::Values {
387 self.0.values()
388 }
389}