diesel/
insertable.rs

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
13/// Represents that a structure can be used to insert a new row into the
14/// database. This is automatically implemented for `&[T]` and `&Vec<T>` for
15/// inserting more than one record.
16///
17/// This trait can be [derived](derive@Insertable)
18pub trait Insertable<T> {
19    /// The `VALUES` clause to insert these records
20    ///
21    /// The types used here are generally internal to Diesel.
22    /// Implementations of this trait should use the `Values`
23    /// type of other `Insertable` types.
24    /// For example `<diesel::dsl::Eq<column, &str> as Insertable<table>>::Values`.
25    type Values;
26
27    /// Construct `Self::Values`
28    ///
29    /// Implementations of this trait typically call `.values`
30    /// on other `Insertable` types.
31    fn values(self) -> Self::Values;
32
33    /// Insert `self` into a given table.
34    ///
35    /// `foo.insert_into(table)` is identical to `insert_into(table).values(foo)`.
36    /// However, when inserting from a select statement,
37    /// this form is generally preferred.
38    ///
39    /// # Example
40    ///
41    /// ```rust
42    /// # include!("doctest_setup.rs");
43    /// #
44    /// # fn main() {
45    /// #     run_test().unwrap();
46    /// # }
47    /// #
48    /// # fn run_test() -> QueryResult<()> {
49    /// #     use schema::{posts, users};
50    /// #     let conn = &mut establish_connection();
51    /// #     diesel::delete(posts::table).execute(conn)?;
52    /// users::table
53    ///     .select((
54    ///         users::name.concat("'s First Post"),
55    ///         users::id,
56    ///     ))
57    ///     .insert_into(posts::table)
58    ///     .into_columns((posts::title, posts::user_id))
59    ///     .execute(conn)?;
60    ///
61    /// let inserted_posts = posts::table
62    ///     .select(posts::title)
63    ///     .load::<String>(conn)?;
64    /// let expected = vec!["Sean's First Post", "Tess's First Post"];
65    /// assert_eq!(expected, inserted_posts);
66    /// #     Ok(())
67    /// # }
68    /// ```
69    fn insert_into(self, table: T) -> InsertStatement<T, Self::Values>
70    where
71        T: Table,
72        Self: Sized,
73    {
74        crate::insert_into(table).values(self)
75    }
76}
77
78#[doc(inline)]
79pub use diesel_derives::Insertable;
80
81pub trait CanInsertInSingleQuery<DB: Backend> {
82    /// How many rows will this query insert?
83    ///
84    /// This function should only return `None` when the query is valid on all
85    /// backends, regardless of how many rows get inserted.
86    fn rows_to_insert(&self) -> Option<usize>;
87}
88
89impl<T, DB> CanInsertInSingleQuery<DB> for &T
90where
91    T: ?Sized + CanInsertInSingleQuery<DB>,
92    DB: Backend,
93{
94    fn rows_to_insert(&self) -> Option<usize> {
95        (*self).rows_to_insert()
96    }
97}
98
99impl<T, U, DB> CanInsertInSingleQuery<DB> for ColumnInsertValue<T, U>
100where
101    DB: Backend,
102{
103    fn rows_to_insert(&self) -> Option<usize> {
104        Some(1)
105    }
106}
107
108impl<V, DB> CanInsertInSingleQuery<DB> for DefaultableColumnInsertValue<V>
109where
110    DB: Backend,
111    V: CanInsertInSingleQuery<DB>,
112{
113    fn rows_to_insert(&self) -> Option<usize> {
114        Some(1)
115    }
116}
117
118pub trait InsertValues<DB: Backend, T: Table>: QueryFragment<DB> {
119    fn column_names(&self, out: AstPass<'_, '_, DB>) -> QueryResult<()>;
120}
121
122#[derive(Debug, Copy, Clone, QueryId)]
123#[doc(hidden)]
124pub struct ColumnInsertValue<Col, Expr> {
125    pub(crate) expr: Expr,
126    p: PhantomData<Col>,
127}
128
129impl<Col, Expr> ColumnInsertValue<Col, Expr> {
130    pub(crate) fn new(expr: Expr) -> Self {
131        Self {
132            expr,
133            p: PhantomData,
134        }
135    }
136}
137
138#[derive(Debug, Copy, Clone)]
139#[doc(hidden)]
140pub enum DefaultableColumnInsertValue<T> {
141    Expression(T),
142    Default,
143}
144
145impl<T> QueryId for DefaultableColumnInsertValue<T> {
146    type QueryId = ();
147    const HAS_STATIC_QUERY_ID: bool = false;
148}
149
150#[allow(clippy::derivable_impls)] // that's not supported on rust 1.65
151impl<T> Default for DefaultableColumnInsertValue<T> {
152    fn default() -> Self {
153        DefaultableColumnInsertValue::Default
154    }
155}
156
157impl<Col, Expr, DB> InsertValues<DB, Col::Table>
158    for DefaultableColumnInsertValue<ColumnInsertValue<Col, Expr>>
159where
160    DB: Backend + SqlDialect<InsertWithDefaultKeyword = sql_dialect::default_keyword_for_insert::IsoSqlDefaultKeyword>,
161    Col: Column,
162    Expr: Expression<SqlType = Col::SqlType> + AppearsOnTable<NoFromClause>,
163    Self: QueryFragment<DB>,
164{
165    fn column_names(&self, mut out: AstPass<'_, '_, DB>) -> QueryResult<()> {
166        out.push_identifier(Col::NAME)?;
167        Ok(())
168    }
169}
170
171impl<Col, Expr, DB> InsertValues<DB, Col::Table> for ColumnInsertValue<Col, Expr>
172where
173    DB: Backend,
174    Col: Column,
175    Expr: Expression<SqlType = Col::SqlType> + AppearsOnTable<NoFromClause>,
176    Self: QueryFragment<DB>,
177{
178    fn column_names(&self, mut out: AstPass<'_, '_, DB>) -> QueryResult<()> {
179        out.push_identifier(Col::NAME)?;
180        Ok(())
181    }
182}
183
184impl<Expr, DB> QueryFragment<DB> for DefaultableColumnInsertValue<Expr>
185where
186    DB: Backend,
187    Self: QueryFragment<DB, DB::InsertWithDefaultKeyword>,
188{
189    fn walk_ast<'b>(&'b self, pass: AstPass<'_, 'b, DB>) -> QueryResult<()> {
190        <Self as QueryFragment<DB, DB::InsertWithDefaultKeyword>>::walk_ast(self, pass)
191    }
192}
193
194impl<Expr, DB> QueryFragment<DB, sql_dialect::default_keyword_for_insert::IsoSqlDefaultKeyword> for DefaultableColumnInsertValue<Expr>
195where
196    DB: Backend + SqlDialect<InsertWithDefaultKeyword = sql_dialect::default_keyword_for_insert::IsoSqlDefaultKeyword>,
197    Expr: QueryFragment<DB>,
198{
199    fn walk_ast<'b>(&'b self, mut out: AstPass<'_, 'b, DB>) -> QueryResult<()> {
200        out.unsafe_to_cache_prepared();
201        if let Self::Expression(ref inner) = *self {
202            inner.walk_ast(out.reborrow())?;
203        } else {
204            out.push_sql("DEFAULT");
205        }
206        Ok(())
207    }
208}
209
210impl<Col, Expr, DB> QueryFragment<DB> for ColumnInsertValue<Col, Expr>
211where
212    DB: Backend + DieselReserveSpecialization,
213    Expr: QueryFragment<DB>,
214{
215    fn walk_ast<'b>(&'b self, pass: AstPass<'_, 'b, DB>) -> QueryResult<()> {
216        self.expr.walk_ast(pass)
217    }
218}
219
220#[cfg(feature = "sqlite")]
221impl<Col, Expr> InsertValues<crate::sqlite::Sqlite, Col::Table>
222    for DefaultableColumnInsertValue<ColumnInsertValue<Col, Expr>>
223where
224    Col: Column,
225    Expr: Expression<SqlType = Col::SqlType> + AppearsOnTable<NoFromClause>,
226    Self: QueryFragment<crate::sqlite::Sqlite>,
227{
228    fn column_names(&self, mut out: AstPass<'_, '_, crate::sqlite::Sqlite>) -> QueryResult<()> {
229        if let Self::Expression(..) = *self {
230            out.push_identifier(Col::NAME)?;
231        }
232        Ok(())
233    }
234}
235
236#[cfg(feature = "sqlite")]
237impl<Col, Expr>
238    QueryFragment<
239        crate::sqlite::Sqlite,
240        crate::backend::sql_dialect::default_keyword_for_insert::DoesNotSupportDefaultKeyword,
241    > for DefaultableColumnInsertValue<ColumnInsertValue<Col, Expr>>
242where
243    Expr: QueryFragment<crate::sqlite::Sqlite>,
244{
245    fn walk_ast<'b>(&'b self, mut out: AstPass<'_, 'b, crate::sqlite::Sqlite>) -> QueryResult<()> {
246        if let Self::Expression(ref inner) = *self {
247            inner.walk_ast(out.reborrow())?;
248        }
249        Ok(())
250    }
251}
252
253impl<'a, T, Tab> Insertable<Tab> for &'a [T]
254where
255    &'a T: UndecoratedInsertRecord<Tab> + Insertable<Tab>,
256{
257    type Values = BatchInsert<Vec<<&'a T as Insertable<Tab>>::Values>, Tab, (), false>;
258
259    fn values(self) -> Self::Values {
260        let values = self.iter().map(Insertable::values).collect::<Vec<_>>();
261        BatchInsert::new(values)
262    }
263}
264
265impl<'a, T, Tab> Insertable<Tab> for &'a Vec<T>
266where
267    &'a [T]: Insertable<Tab>,
268{
269    type Values = <&'a [T] as Insertable<Tab>>::Values;
270
271    fn values(self) -> Self::Values {
272        (&**self).values()
273    }
274}
275
276impl<T, Tab> Insertable<Tab> for Vec<T>
277where
278    T: Insertable<Tab> + UndecoratedInsertRecord<Tab>,
279{
280    type Values = BatchInsert<Vec<T::Values>, Tab, (), false>;
281
282    fn values(self) -> Self::Values {
283        let values = self.into_iter().map(Insertable::values).collect::<Vec<_>>();
284        BatchInsert::new(values)
285    }
286}
287
288impl<T, Tab, const N: usize> Insertable<Tab> for [T; N]
289where
290    T: Insertable<Tab>,
291{
292    type Values = BatchInsert<Vec<T::Values>, Tab, [T::Values; N], true>;
293
294    // We must use the deprecated `IntoIter` function
295    // here as 1.51 (MSRV) does not support the new not
296    // deprecated variant
297    #[allow(deprecated)]
298    fn values(self) -> Self::Values {
299        let values = std::array::IntoIter::new(self)
300            .map(Insertable::values)
301            .collect::<Vec<_>>();
302        BatchInsert::new(values)
303    }
304}
305
306impl<'a, T, Tab, const N: usize> Insertable<Tab> for &'a [T; N]
307where
308    T: Insertable<Tab>,
309    &'a T: Insertable<Tab>,
310{
311    // We can reuse the query id for [T; N] here as this
312    // compiles down to the same query
313    type Values = BatchInsert<Vec<<&'a T as Insertable<Tab>>::Values>, Tab, [T::Values; N], true>;
314
315    fn values(self) -> Self::Values {
316        let values = self.iter().map(Insertable::values).collect();
317        BatchInsert::new(values)
318    }
319}
320
321impl<T, Tab, const N: usize> Insertable<Tab> for Box<[T; N]>
322where
323    T: Insertable<Tab>,
324{
325    // We can reuse the query id for [T; N] here as this
326    // compiles down to the same query
327    type Values = BatchInsert<Vec<T::Values>, Tab, [T::Values; N], true>;
328
329    fn values(self) -> Self::Values {
330        let v = Vec::from(self as Box<[T]>);
331        let values = v.into_iter().map(Insertable::values).collect::<Vec<_>>();
332        BatchInsert::new(values)
333    }
334}
335
336mod private {
337    // This helper exists to differentiate between
338    // Insertable implementations for tuples and for single values
339    #[allow(missing_debug_implementations)]
340    pub struct InsertableOptionHelper<T, V>(
341        pub(crate) Option<T>,
342        pub(crate) std::marker::PhantomData<V>,
343    );
344}
345
346pub(crate) use self::private::InsertableOptionHelper;
347
348impl<T, Tab, V> Insertable<Tab> for Option<T>
349where
350    T: Insertable<Tab, Values = ValuesClause<V, Tab>>,
351    InsertableOptionHelper<T, V>: Insertable<Tab>,
352{
353    type Values = <InsertableOptionHelper<T, V> as Insertable<Tab>>::Values;
354
355    fn values(self) -> Self::Values {
356        InsertableOptionHelper(self, PhantomData).values()
357    }
358}
359
360impl<T, Tab, Expr, Col> Insertable<Tab> for InsertableOptionHelper<T, ColumnInsertValue<Col, Expr>>
361where
362    T: Insertable<Tab, Values = ValuesClause<ColumnInsertValue<Col, Expr>, Tab>>,
363{
364    type Values = ValuesClause<DefaultableColumnInsertValue<ColumnInsertValue<Col, Expr>>, Tab>;
365
366    fn values(self) -> Self::Values {
367        ValuesClause::new(
368            self.0
369                .map(|v| DefaultableColumnInsertValue::Expression(Insertable::values(v).values))
370                .unwrap_or_default(),
371        )
372    }
373}
374
375impl<'a, T, Tab> Insertable<Tab> for &'a Option<T>
376where
377    Option<&'a T>: Insertable<Tab>,
378{
379    type Values = <Option<&'a T> as Insertable<Tab>>::Values;
380
381    fn values(self) -> Self::Values {
382        self.as_ref().values()
383    }
384}
385
386impl<L, R, Tab> Insertable<Tab> for Grouped<crate::expression::operators::Eq<L, R>>
387where
388    crate::expression::operators::Eq<L, R>: Insertable<Tab>,
389{
390    type Values = <crate::expression::operators::Eq<L, R> as Insertable<Tab>>::Values;
391
392    fn values(self) -> Self::Values {
393        self.0.values()
394    }
395}
396
397impl<'a, L, R, Tab> Insertable<Tab> for &'a Grouped<crate::expression::operators::Eq<L, R>>
398where
399    &'a crate::expression::operators::Eq<L, R>: Insertable<Tab>,
400{
401    type Values = <&'a crate::expression::operators::Eq<L, R> as Insertable<Tab>>::Values;
402
403    fn values(self) -> Self::Values {
404        self.0.values()
405    }
406}