Skip to content

Commit fab0ffe

Browse files
authored
Merge pull request diesel-rs#1741 from GiGainfosystems/bugfix/1736
Restructure `InternalSaveChangesDsl`
2 parents b0dd75e + b1bf5c7 commit fab0ffe

2 files changed

Lines changed: 41 additions & 28 deletions

File tree

diesel/src/query_dsl/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ pub use self::group_by_dsl::GroupByDsl;
4848
pub use self::join_dsl::{InternalJoinDsl, JoinOnDsl, JoinWithImplicitOnClause};
4949
#[doc(hidden)]
5050
pub use self::load_dsl::LoadQuery;
51-
pub use self::save_changes_dsl::SaveChangesDsl;
51+
pub use self::save_changes_dsl::{SaveChangesDsl, UpdateAndFetchResults};
5252

5353
/// The traits used by `QueryDsl`.
5454
///

diesel/src/query_dsl/save_changes_dsl.rs

Lines changed: 40 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use associations::HasTable;
22
#[cfg(any(feature = "sqlite", feature = "mysql"))]
33
use associations::Identifiable;
4+
use connection::Connection;
45
#[cfg(any(feature = "sqlite", feature = "mysql"))]
56
use dsl::Find;
67
#[cfg(any(feature = "sqlite", feature = "postgres", feature = "mysql"))]
@@ -12,57 +13,68 @@ use query_dsl::methods::{ExecuteDsl, FindDsl};
1213
use query_dsl::{LoadQuery, RunQueryDsl};
1314
use result::QueryResult;
1415

15-
pub trait InternalSaveChangesDsl<Conn, T>: Sized {
16-
fn internal_save_changes(self, connection: &Conn) -> QueryResult<T>;
16+
/// A trait defining how to update a record and fetch the updated entry
17+
/// on a certain backend.
18+
///
19+
/// The only case where it is required to work with this trait is while
20+
/// implementing a new connection type.
21+
/// Otherwise use [`SaveChangesDsl`](trait.SaveChangesDsl.html)
22+
///
23+
/// For implementing this trait for a custom backend:
24+
/// * The `Changes` generic parameter represents the changeset that should be stored
25+
/// * The `Output` generic parameter represents the type of the response.
26+
pub trait UpdateAndFetchResults<Changes, Output>: Connection {
27+
/// See the traits documentation.
28+
fn update_and_fetch(&self, changeset: Changes) -> QueryResult<Output>;
1729
}
1830

1931
#[cfg(feature = "postgres")]
2032
use pg::PgConnection;
2133

2234
#[cfg(feature = "postgres")]
23-
impl<T, U> InternalSaveChangesDsl<PgConnection, U> for T
35+
impl<Changes, Output> UpdateAndFetchResults<Changes, Output> for PgConnection
2436
where
25-
T: Copy + AsChangeset<Target = <T as HasTable>::Table> + IntoUpdateTarget,
26-
Update<T, T>: LoadQuery<PgConnection, U>,
37+
Changes: Copy + AsChangeset<Target = <Changes as HasTable>::Table> + IntoUpdateTarget,
38+
Update<Changes, Changes>: LoadQuery<PgConnection, Output>,
2739
{
28-
fn internal_save_changes(self, conn: &PgConnection) -> QueryResult<U> {
29-
::update(self).set(self).get_result(conn)
40+
fn update_and_fetch(&self, changeset: Changes) -> QueryResult<Output> {
41+
::update(changeset).set(changeset).get_result(self)
3042
}
3143
}
3244

3345
#[cfg(feature = "sqlite")]
3446
use sqlite::SqliteConnection;
3547

3648
#[cfg(feature = "sqlite")]
37-
impl<T, U> InternalSaveChangesDsl<SqliteConnection, U> for T
49+
impl<Changes, Output> UpdateAndFetchResults<Changes, Output> for SqliteConnection
3850
where
39-
T: Copy + Identifiable,
40-
T: AsChangeset<Target = <T as HasTable>::Table> + IntoUpdateTarget,
41-
T::Table: FindDsl<T::Id>,
42-
Update<T, T>: ExecuteDsl<SqliteConnection>,
43-
Find<T::Table, T::Id>: LoadQuery<SqliteConnection, U>,
51+
Changes: Copy + Identifiable,
52+
Changes: AsChangeset<Target = <Changes as HasTable>::Table> + IntoUpdateTarget,
53+
Changes::Table: FindDsl<Changes::Id>,
54+
Update<Changes, Changes>: ExecuteDsl<SqliteConnection>,
55+
Find<Changes::Table, Changes::Id>: LoadQuery<SqliteConnection, Output>,
4456
{
45-
fn internal_save_changes(self, conn: &SqliteConnection) -> QueryResult<U> {
46-
try!(::update(self).set(self).execute(conn));
47-
T::table().find(self.id()).get_result(conn)
57+
fn update_and_fetch(&self, changeset: Changes) -> QueryResult<Output> {
58+
try!(::update(changeset).set(changeset).execute(self));
59+
Changes::table().find(changeset.id()).get_result(self)
4860
}
4961
}
5062

5163
#[cfg(feature = "mysql")]
5264
use mysql::MysqlConnection;
5365

5466
#[cfg(feature = "mysql")]
55-
impl<T, U> InternalSaveChangesDsl<MysqlConnection, U> for T
67+
impl<Changes, Output> UpdateAndFetchResults<Changes, Output> for MysqlConnection
5668
where
57-
T: Copy + Identifiable,
58-
T: AsChangeset<Target = <T as HasTable>::Table> + IntoUpdateTarget,
59-
T::Table: FindDsl<T::Id>,
60-
Update<T, T>: ExecuteDsl<MysqlConnection>,
61-
Find<T::Table, T::Id>: LoadQuery<MysqlConnection, U>,
69+
Changes: Copy + Identifiable,
70+
Changes: AsChangeset<Target = <Changes as HasTable>::Table> + IntoUpdateTarget,
71+
Changes::Table: FindDsl<Changes::Id>,
72+
Update<Changes, Changes>: ExecuteDsl<MysqlConnection>,
73+
Find<Changes::Table, Changes::Id>: LoadQuery<MysqlConnection, Output>,
6274
{
63-
fn internal_save_changes(self, conn: &MysqlConnection) -> QueryResult<U> {
64-
try!(::update(self).set(self).execute(conn));
65-
T::table().find(self.id()).get_result(conn)
75+
fn update_and_fetch(&self, changeset: Changes) -> QueryResult<Output> {
76+
try!(::update(changeset).set(changeset).execute(self));
77+
Changes::table().find(changeset.id()).get_result(self)
6678
}
6779
}
6880

@@ -118,9 +130,10 @@ pub trait SaveChangesDsl<Conn> {
118130
/// See the trait documentation.
119131
fn save_changes<T>(self, connection: &Conn) -> QueryResult<T>
120132
where
121-
Self: InternalSaveChangesDsl<Conn, T>,
133+
Self: Sized,
134+
Conn: UpdateAndFetchResults<Self, T>,
122135
{
123-
self.internal_save_changes(connection)
136+
connection.update_and_fetch(self)
124137
}
125138
}
126139

0 commit comments

Comments
 (0)