ferrule_sql/
transaction.rs1use crate::backend::Backend;
15use crate::connection::Connection;
16use crate::error::SqlError;
17
18fn begin_sql_for(backend: Backend) -> Option<&'static str> {
23 match backend {
24 #[cfg(feature = "mssql")]
25 Backend::MsSql => Some("BEGIN TRANSACTION"),
26 #[cfg(feature = "oracle")]
27 Backend::Oracle => None,
28 _ => Some("BEGIN"),
29 }
30}
31
32fn commit_sql_for(backend: Backend) -> &'static str {
34 match backend {
35 #[cfg(feature = "mssql")]
36 Backend::MsSql => "COMMIT TRANSACTION",
37 _ => "COMMIT",
38 }
39}
40
41fn rollback_sql_for(backend: Backend) -> &'static str {
43 match backend {
44 #[cfg(feature = "mssql")]
45 Backend::MsSql => "ROLLBACK TRANSACTION",
46 _ => "ROLLBACK",
47 }
48}
49
50#[must_use]
56pub fn begin_transaction(conn: &mut dyn Connection, backend: Backend) -> bool {
57 match begin_sql_for(backend) {
58 None => true,
59 Some(stmt) => conn.execute(stmt).is_ok(),
60 }
61}
62
63#[must_use = "commit_transaction returns a SqlError on wire failure that the caller must surface"]
66pub fn commit_transaction(conn: &mut dyn Connection, backend: Backend) -> Result<(), SqlError> {
67 conn.execute(commit_sql_for(backend)).map(|_| ())
68}
69
70#[must_use = "rollback_transaction returns a SqlError on wire failure; best-effort callers should still `let _ =`"]
73pub fn rollback_transaction(conn: &mut dyn Connection, backend: Backend) -> Result<(), SqlError> {
74 conn.execute(rollback_sql_for(backend)).map(|_| ())
75}
76
77#[cfg(test)]
78mod tests {
79 use super::*;
80
81 #[test]
82 fn statements_per_backend() {
83 #[cfg(feature = "postgres")]
85 {
86 let b = Backend::Postgres;
87 assert_eq!(begin_sql_for(b), Some("BEGIN"));
88 assert_eq!(commit_sql_for(b), "COMMIT");
89 assert_eq!(rollback_sql_for(b), "ROLLBACK");
90 }
91 #[cfg(feature = "mysql")]
92 {
93 let b = Backend::MySql;
94 assert_eq!(begin_sql_for(b), Some("BEGIN"));
95 assert_eq!(commit_sql_for(b), "COMMIT");
96 assert_eq!(rollback_sql_for(b), "ROLLBACK");
97 }
98 #[cfg(feature = "sqlite")]
99 {
100 let b = Backend::Sqlite;
101 assert_eq!(begin_sql_for(b), Some("BEGIN"));
102 assert_eq!(commit_sql_for(b), "COMMIT");
103 assert_eq!(rollback_sql_for(b), "ROLLBACK");
104 }
105
106 #[cfg(feature = "mssql")]
108 {
109 assert_eq!(begin_sql_for(Backend::MsSql), Some("BEGIN TRANSACTION"));
110 assert_eq!(commit_sql_for(Backend::MsSql), "COMMIT TRANSACTION");
111 assert_eq!(rollback_sql_for(Backend::MsSql), "ROLLBACK TRANSACTION");
112 }
113
114 #[cfg(feature = "oracle")]
116 {
117 assert_eq!(begin_sql_for(Backend::Oracle), None);
118 assert_eq!(commit_sql_for(Backend::Oracle), "COMMIT");
119 assert_eq!(rollback_sql_for(Backend::Oracle), "ROLLBACK");
120 }
121 }
122}