1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
use associations::HasTable;
use backend::SupportsReturningClause;
use connection::Connection;
use helper_types::*;
use query_builder::{AsChangeset, IntoUpdateTarget};
use query_dsl::*;
use query_source::Queryable;
use result::QueryResult;
use types::HasSqlType;
#[cfg(any(feature = "sqlite", feature = "mysql"))]
use associations::Identifiable;

pub trait SaveChangesDsl<Conn, ST> where
    Conn: Connection,
    Conn::Backend: HasSqlType<ST>,
{
    fn save_changes<T>(self, connection: &Conn) -> QueryResult<T> where
        T: Queryable<ST, Conn::Backend>;
}

impl<T, ST, Conn> SaveChangesDsl<Conn, ST> for T where
    Conn: Connection,
    Conn::Backend: HasSqlType<ST> + SupportsReturningClause,
    T: Copy + AsChangeset<Target=<T as HasTable>::Table> + IntoUpdateTarget,
    Update<T, T>: LoadDsl<Conn, SqlType=ST>,
{
    fn save_changes<U>(self, conn: &Conn) -> QueryResult<U> where
        U: Queryable<ST, Conn::Backend>,
    {
        ::update(self).set(self).get_result(conn)
    }
}

#[cfg(feature = "sqlite")]
use sqlite::{SqliteConnection, Sqlite};

#[cfg(feature = "sqlite")]
impl<T, ST> SaveChangesDsl<SqliteConnection, ST> for T where
    Sqlite: HasSqlType<ST>,
    T: Copy + Identifiable,
    T: AsChangeset<Target=<T as HasTable>::Table> + IntoUpdateTarget,
    T::Table: FindDsl<T::Id, SqlType=ST>,
    Update<T, T>: ExecuteDsl<SqliteConnection>,
    Find<T::Table, T::Id>: LoadDsl<SqliteConnection, SqlType=ST>,
{
    fn save_changes<U>(self, conn: &SqliteConnection) -> QueryResult<U> where
        U: Queryable<ST, Sqlite>,
    {
        try!(::update(self).set(self).execute(conn));
        T::table().find(self.id()).get_result(conn)
    }
}

#[cfg(feature = "mysql")]
use mysql::{MysqlConnection, Mysql};

#[cfg(feature = "mysql")]
impl<T, ST> SaveChangesDsl<MysqlConnection, ST> for T where
    Mysql: HasSqlType<ST>,
    T: Copy + Identifiable,
    T: AsChangeset<Target=<T as HasTable>::Table> + IntoUpdateTarget,
    T::Table: FindDsl<T::Id, SqlType=ST>,
    Update<T, T>: ExecuteDsl<MysqlConnection>,
    Find<T::Table, T::Id>: LoadDsl<MysqlConnection, SqlType=ST>,
{
    fn save_changes<U>(self, conn: &MysqlConnection) -> QueryResult<U> where
        U: Queryable<ST, Mysql>,
    {
        try!(::update(self).set(self).execute(conn));
        T::table().find(self.id()).get_result(conn)
    }
}