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((users::name.concat("'s First Post"), users::id))
54    ///     .insert_into(posts::table)
55    ///     .into_columns((posts::title, posts::user_id))
56    ///     .execute(conn)?;
57    ///
58    /// let inserted_posts = posts::table.select(posts::title).load::<String>(conn)?;
59    /// let expected = vec!["Sean's First Post", "Tess's First Post"];
60    /// assert_eq!(expected, inserted_posts);
61    /// #     Ok(())
62    /// # }
63    /// ```
64    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    /// How many rows will this query insert?
78    ///
79    /// This function should only return `None` when the query is valid on all
80    /// backends, regardless of how many rows get inserted.
81    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    // We can reuse the query id for [T; N] here as this
295    // compiles down to the same query
296    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    // We can reuse the query id for [T; N] here as this
309    // compiles down to the same query
310    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    // This helper exists to differentiate between
321    // Insertable implementations for tuples and for single values
322    #[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}