diesel/query_builder/update_statement/
batch_update.rs1#[cfg(doc)]
2use crate::backend::SqlDialect;
3use crate::backend::{Backend, sql_dialect};
4use crate::query_builder::{AstPass, QueryFragment};
5use crate::{QueryResult, query_builder::*};
6use core::marker::PhantomData;
7
8#[cfg(any(
9 feature = "__sqlite-shared",
10 feature = "postgres_backend",
11 feature = "mysql_backend"
12))]
13pub(crate) const BATCH_UPDATE_ALIAS: &str = "__diesel_internal_temp_values";
14
15#[cfg(any(
16 feature = "__sqlite-shared",
17 feature = "postgres_backend",
18 feature = "mysql_backend"
19))]
20pub trait BatchValueHelper<DB: Backend> {
21 fn assign<'b>(&'b self, out: AstPass<'_, 'b, DB>) -> QueryResult<()>;
22
23 fn column_name<'b>(&'b self, out: AstPass<'_, 'b, DB>) -> QueryResult<()>;
24
25 fn bind_value<'b>(&'b self, out: AstPass<'_, 'b, DB>) -> QueryResult<()>;
26}
27
28#[cfg(any(
29 feature = "__sqlite-shared",
30 feature = "postgres_backend",
31 feature = "mysql_backend"
32))]
33pub trait BatchAssignHelper<DB: Backend> {
34 fn batch_assign_identifier<'a>(&'a self, out: AstPass<'_, 'a, DB>) -> QueryResult<()>;
35}
36
37#[cfg(any(
38 feature = "__sqlite-shared",
39 feature = "postgres_backend",
40 feature = "mysql_backend"
41))]
42pub trait BatchKeyHelper<PK, DB: Backend> {
43 fn bind_value<'b>(&'b self, out: AstPass<'_, 'b, DB>) -> QueryResult<()>;
44
45 fn column_name<'b>(&'b self, out: AstPass<'_, 'b, DB>) -> QueryResult<()>;
46
47 fn assign<'b>(pk: &'b PK, out: AstPass<'_, 'b, DB>) -> QueryResult<()>;
48}
49
50#[cfg(any(
51 feature = "__sqlite-shared",
52 feature = "postgres_backend",
53 feature = "mysql_backend"
54))]
55impl<PK, DB, C> BatchKeyHelper<PK, DB> for C
56where
57 DB: Backend + crate::sql_types::HasSqlType<PK::SqlType>,
58 C: crate::serialize::ToSql<PK::SqlType, DB>,
59 PK: crate::expression::Expression + crate::Column + QueryFragment<DB>,
60 PK::SqlType: crate::sql_types::SingleValue,
61{
62 fn bind_value<'b>(&'b self, mut out: AstPass<'_, 'b, DB>) -> QueryResult<()> {
63 out.push_bind_param(self)
64 }
65
66 fn column_name<'b>(&'b self, mut out: AstPass<'_, 'b, DB>) -> QueryResult<()> {
67 out.push_identifier(PK::NAME)
68 }
69
70 fn assign<'b>(pk: &'b PK, mut out: AstPass<'_, 'b, DB>) -> QueryResult<()> {
71 pk.walk_ast(out.reborrow())?;
72 out.push_sql(" = ");
73 out.push_identifier(BATCH_UPDATE_ALIAS)?;
74 out.push_sql(".");
75 out.push_identifier(PK::NAME)?;
76 Ok(())
77 }
78}
79
80#[cfg_attr(
88 feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes",
89 cfg(feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes")
90)]
91#[allow(dead_code)]
94#[derive(#[automatically_derived]
#[allow(dead_code)]
impl<I: ::core::fmt::Debug, C: ::core::fmt::Debug, PK: ::core::fmt::Debug,
Tab: ::core::fmt::Debug> ::core::fmt::Debug for BatchUpdate<I, C, PK, Tab>
{
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field3_finish(f, "BatchUpdate",
"values", &self.values, "primary_key", &self.primary_key,
"_marker", &&self._marker)
}
}Debug)]
95pub struct BatchUpdate<I, C, PK, Tab> {
96 pub(crate) values: Vec<(I, C)>,
99 pub(crate) primary_key: PK,
101 _marker: PhantomData<Tab>,
102}
103
104impl<I, C, PK, Tab> BatchUpdate<I, C, PK, Tab> {
105 pub fn new(values: Vec<(I, C)>, primary_key: PK) -> Self {
107 Self {
108 values,
109 primary_key,
110 _marker: PhantomData,
111 }
112 }
113}
114
115impl<I, C, PK, Tab, DB> QueryFragment<DB> for BatchUpdate<I, C, PK, Tab>
116where
117 DB: Backend,
118 DB::BatchUpdateSupport: sql_dialect::batch_update_support::SupportsBatchUpdate,
119 Self: QueryFragment<DB, DB::BatchUpdateSupport>,
120{
121 fn walk_ast<'b>(&'b self, pass: AstPass<'_, 'b, DB>) -> QueryResult<()> {
122 <Self as QueryFragment<DB, DB::BatchUpdateSupport>>::walk_ast(self, pass)
123 }
124}