diesel/query_dsl/
save_changes_dsl.rs1#[cfg(any(feature = "__sqlite-shared", feature = "postgres", feature = "mysql"))]
2use crate::Table;
3use crate::associations::HasTable;
4#[cfg(any(feature = "__sqlite-shared", feature = "mysql"))]
5use crate::associations::Identifiable;
6use crate::connection::Connection;
7#[cfg(any(feature = "__sqlite-shared", feature = "mysql"))]
8use crate::dsl::Find;
9#[cfg(any(feature = "__sqlite-shared", feature = "postgres", feature = "mysql"))]
10use crate::dsl::Update;
11#[cfg(any(feature = "__sqlite-shared", feature = "postgres", feature = "mysql"))]
12use crate::expression::{MixedAggregates, ValidGrouping, is_aggregate};
13use crate::query_builder::{AsChangeset, IntoUpdateTarget};
14#[cfg(any(feature = "__sqlite-shared", feature = "mysql"))]
15use crate::query_dsl::methods::{ExecuteDsl, FindDsl};
16#[cfg(any(feature = "__sqlite-shared", feature = "postgres", feature = "mysql"))]
17use crate::query_dsl::{LoadQuery, RunQueryDsl};
18use crate::result::QueryResult;
19
20pub trait UpdateAndFetchResults<Changes, Output>: Connection {
31 fn update_and_fetch(&mut self, changeset: Changes) -> QueryResult<Output>;
33}
34
35#[cfg(feature = "postgres")]
36use crate::pg::PgConnection;
37
38#[cfg(feature = "postgres")]
39impl<'b, Changes, Output> UpdateAndFetchResults<Changes, Output> for PgConnection
40where
41 Changes: Copy + AsChangeset<Target = <Changes as HasTable>::Table> + IntoUpdateTarget,
42 Update<Changes, Changes>: LoadQuery<'b, PgConnection, Output>,
43 <Changes::Table as Table>::AllColumns: ValidGrouping<()>
44 + crate::expression::SelectableExpression<
45 crate::query_builder::returning::ReturningQuerySource<
46 crate::query_builder::returning::UpdateStmt,
47 Changes::Table,
48 >,
49 >,
50 <<Changes::Table as Table>::AllColumns as ValidGrouping<()>>::IsAggregate:
51 MixedAggregates<is_aggregate::No, Output = is_aggregate::No>,
52{
53 fn update_and_fetch(&mut self, changeset: Changes) -> QueryResult<Output> {
54 crate::update(changeset).set(changeset).get_result(self)
55 }
56}
57
58#[cfg(feature = "__sqlite-shared")]
59use crate::sqlite::SqliteConnection;
60
61#[cfg(feature = "__sqlite-shared")]
62impl<'b, Changes, Output> UpdateAndFetchResults<Changes, Output> for SqliteConnection
63where
64 Changes: Copy + Identifiable,
65 Changes: AsChangeset<Target = <Changes as HasTable>::Table> + IntoUpdateTarget,
66 Changes::Table: FindDsl<Changes::Id>,
67 Update<Changes, Changes>: ExecuteDsl<SqliteConnection>,
68 Find<Changes::Table, Changes::Id>: LoadQuery<'b, SqliteConnection, Output>,
69 <Changes::Table as Table>::AllColumns: ValidGrouping<()>
70 + crate::expression::SelectableExpression<
71 crate::query_builder::returning::ReturningQuerySource<
72 crate::query_builder::returning::UpdateStmt,
73 Changes::Table,
74 >,
75 >,
76 <<Changes::Table as Table>::AllColumns as ValidGrouping<()>>::IsAggregate:
77 MixedAggregates<is_aggregate::No, Output = is_aggregate::No>,
78{
79 fn update_and_fetch(&mut self, changeset: Changes) -> QueryResult<Output> {
80 crate::update(changeset).set(changeset).execute(self)?;
81 Changes::table().find(changeset.id()).get_result(self)
82 }
83}
84
85#[cfg(feature = "mysql")]
86use crate::mysql::MysqlConnection;
87
88#[cfg(feature = "mysql")]
89impl<'b, Changes, Output> UpdateAndFetchResults<Changes, Output> for MysqlConnection
90where
91 Changes: Copy + Identifiable,
92 Changes: AsChangeset<Target = <Changes as HasTable>::Table> + IntoUpdateTarget,
93 Changes::Table: FindDsl<Changes::Id>,
94 Update<Changes, Changes>: ExecuteDsl<MysqlConnection>,
95 Find<Changes::Table, Changes::Id>: LoadQuery<'b, MysqlConnection, Output>,
96 <Changes::Table as Table>::AllColumns: ValidGrouping<()>
97 + crate::expression::SelectableExpression<
98 crate::query_builder::returning::ReturningQuerySource<
99 crate::query_builder::returning::UpdateStmt,
100 Changes::Table,
101 >,
102 >,
103 <<Changes::Table as Table>::AllColumns as ValidGrouping<()>>::IsAggregate:
104 MixedAggregates<is_aggregate::No, Output = is_aggregate::No>,
105{
106 fn update_and_fetch(&mut self, changeset: Changes) -> QueryResult<Output> {
107 crate::update(changeset).set(changeset).execute(self)?;
108 Changes::table().find(changeset.id()).get_result(self)
109 }
110}
111
112pub trait SaveChangesDsl<Conn> {
163 fn save_changes<T>(self, connection: &mut Conn) -> QueryResult<T>
165 where
166 Self: Sized,
167 Conn: UpdateAndFetchResults<Self, T>,
168 {
169 connection.update_and_fetch(self)
170 }
171}
172
173impl<T, Conn> SaveChangesDsl<Conn> for T where
174 T: Copy + AsChangeset<Target = <T as HasTable>::Table> + IntoUpdateTarget
175{
176}