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 feature = "mariadb_backend"
13))]
14pub(crate) const BATCH_UPDATE_ALIAS: &str = "__diesel_internal_temp_values";
15
16#[cfg(any(
17 feature = "__sqlite-shared",
18 feature = "postgres_backend",
19 feature = "mysql_backend",
20 feature = "mariadb_backend"
21))]
22pub trait BatchValueHelper<DB: Backend> {
23 fn assign<'b>(&'b self, out: AstPass<'_, 'b, DB>) -> QueryResult<()>;
24
25 fn column_name<'b>(&'b self, out: AstPass<'_, 'b, DB>) -> QueryResult<()>;
26
27 fn bind_value<'b>(&'b self, out: AstPass<'_, 'b, DB>) -> QueryResult<()>;
28}
29
30#[cfg(any(
31 feature = "__sqlite-shared",
32 feature = "postgres_backend",
33 feature = "mysql_backend",
34 feature = "mariadb_backend"
35))]
36pub trait BatchAssignHelper<DB: Backend> {
37 fn batch_assign_identifier<'a>(&'a self, out: AstPass<'_, 'a, DB>) -> QueryResult<()>;
38}
39
40#[cfg(any(
41 feature = "__sqlite-shared",
42 feature = "postgres_backend",
43 feature = "mysql_backend",
44 feature = "mariadb_backend"
45))]
46pub trait BatchKeyHelper<PK, DB: Backend> {
47 fn bind_value<'b>(&'b self, out: AstPass<'_, 'b, DB>) -> QueryResult<()>;
48
49 fn column_name<'b>(&'b self, out: AstPass<'_, 'b, DB>) -> QueryResult<()>;
50
51 fn assign<'b>(pk: &'b PK, out: AstPass<'_, 'b, DB>) -> QueryResult<()>;
52}
53
54#[cfg(any(
55 feature = "__sqlite-shared",
56 feature = "postgres_backend",
57 feature = "mysql_backend",
58 feature = "mariadb_backend"
59))]
60impl<PK, DB, C> BatchKeyHelper<PK, DB> for C
61where
62 DB: Backend + crate::sql_types::HasSqlType<PK::SqlType>,
63 C: crate::serialize::ToSql<PK::SqlType, DB>,
64 PK: crate::expression::Expression + crate::Column + QueryFragment<DB>,
65 PK::SqlType: crate::sql_types::SingleValue,
66{
67 fn bind_value<'b>(&'b self, mut out: AstPass<'_, 'b, DB>) -> QueryResult<()> {
68 out.push_bind_param(self)
69 }
70
71 fn column_name<'b>(&'b self, mut out: AstPass<'_, 'b, DB>) -> QueryResult<()> {
72 out.push_identifier(PK::NAME)
73 }
74
75 fn assign<'b>(pk: &'b PK, mut out: AstPass<'_, 'b, DB>) -> QueryResult<()> {
76 pk.walk_ast(out.reborrow())?;
77 out.push_sql(" = ");
78 out.push_identifier(BATCH_UPDATE_ALIAS)?;
79 out.push_sql(".");
80 out.push_identifier(PK::NAME)?;
81 Ok(())
82 }
83}
84
85#[cfg_attr(
93 feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes",
94 cfg(feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes")
95)]
96#[allow(dead_code)]
99#[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)]
100pub struct BatchUpdate<I, C, PK, Tab> {
101 pub(crate) values: Vec<(I, C)>,
104 pub(crate) primary_key: PK,
106 _marker: PhantomData<Tab>,
107}
108
109impl<I, C, PK, Tab> BatchUpdate<I, C, PK, Tab> {
110 pub fn new(values: Vec<(I, C)>, primary_key: PK) -> Self {
112 Self {
113 values,
114 primary_key,
115 _marker: PhantomData,
116 }
117 }
118}
119
120impl<I, C, PK, Tab, DB> QueryFragment<DB> for BatchUpdate<I, C, PK, Tab>
121where
122 DB: Backend,
123 DB::BatchUpdateSupport: sql_dialect::batch_update_support::SupportsBatchUpdate,
124 Self: QueryFragment<DB, DB::BatchUpdateSupport>,
125{
126 fn walk_ast<'b>(&'b self, pass: AstPass<'_, 'b, DB>) -> QueryResult<()> {
127 <Self as QueryFragment<DB, DB::BatchUpdateSupport>>::walk_ast(self, pass)
128 }
129}