Skip to main content

diesel/mariadb/
connection.rs

1use crate::mariadb::Mariadb;
2
3/// A connection to a Mariadb database. Connection URLs should be in the form
4/// `mariadb://[user[:password]@]host/database_name[?unix_socket=socket-path]`
5///
6///* `host` can be an IP address or a hostname. If it is set to `localhost`, a connection
7///  will be attempted through the socket at `/tmp/mysql.sock`. If you want to connect to
8///  a local server via TCP (e.g. docker containers), use `0.0.0.0` or `127.0.0.1` instead.
9/// * `unix_socket` expects the path to the unix socket
10///
11/// Errors carry the SQLSTATE the server or client library reports in
12/// [`DatabaseErrorInformation::sqlstate`](crate::result::DatabaseErrorInformation::sqlstate),
13/// including custom codes raised with
14/// [`SIGNAL`](https://mariadb.com/docs/server/reference/sql-statements/programmatic-compound-statements/signal).
15/// The server reports `HY000` for errors without a specific SQLSTATE, as
16/// described at <https://mariadb.com/docs/server/reference/sql-statements/programmatic-compound-statements/programmatic-compound-statements-diagnostics/sqlstate>.
17/// [`sql_state`](crate::mysql_like::sql_state) names the codes.
18///
19/// # Supported loading model implementations
20///
21/// * [`DefaultLoadingMode`](crate::connection::DefaultLoadingMode)
22///
23/// As `MariadbConnection` only supports a single loading mode implementation
24/// it is **not required** to explicitly specify a loading mode
25/// when calling [`RunQueryDsl::load_iter()`](crate::query_dsl::RunQueryDsl::load_iter)
26/// or [`LoadConnection::load`](crate::connection::LoadConnection::load)
27///
28/// ## DefaultLoadingMode
29///
30/// `MariadbConnection` only supports a single loading mode, which loads
31/// values row by row from the result set.
32///
33/// ```rust,dejadoc
34/// # include!("../doctest_setup.rs");
35/// #
36/// # fn main() {
37/// #     run_test().unwrap();
38/// # }
39/// #
40/// # fn run_test() -> QueryResult<()> {
41/// #     use schema::users;
42/// #     let connection = &mut establish_connection();
43/// use diesel::connection::DefaultLoadingMode;
44/// { // scope to restrict the lifetime of the iterator
45///     let iter1 = users::table.load_iter::<(i32, String), DefaultLoadingMode>(connection)?;
46///
47///     for r in iter1 {
48///         let (id, name) = r?;
49///         println!("Id: {} Name: {}", id, name);
50///     }
51/// }
52///
53/// // works without specifying the loading mode
54/// let iter2 = users::table.load_iter::<(i32, String), _>(connection)?;
55///
56/// for r in iter2 {
57///     let (id, name) = r?;
58///     println!("Id: {} Name: {}", id, name);
59/// }
60/// #   Ok(())
61/// # }
62/// ```
63///
64/// This mode does **not support** creating
65/// multiple iterators using the same connection.
66///
67/// ```compile_fail,dejadoc
68/// # include!("../../doctest_setup.rs");
69/// #
70/// # fn main() {
71/// #     run_test().unwrap();
72/// # }
73/// #
74/// # fn run_test() -> QueryResult<()> {
75/// #     use schema::users;
76/// #     let connection = &mut establish_connection();
77/// use diesel::connection::DefaultLoadingMode;
78///
79/// let iter1 = users::table.load_iter::<(i32, String), DefaultLoadingMode>(connection)?;
80/// let iter2 = users::table.load_iter::<(i32, String), DefaultLoadingMode>(connection)?;
81///
82/// for r in iter1 {
83///     let (id, name) = r?;
84///     println!("Id: {} Name: {}", id, name);
85/// }
86///
87/// for r in iter2 {
88///     let (id, name) = r?;
89///     println!("Id: {} Name: {}", id, name);
90/// }
91/// #   Ok(())
92/// # }
93/// ```
94pub type MariadbConnection = crate::mysql_like::MysqlLikeConnection<Mariadb>;
95
96#[cfg(test)]
97mod tests {
98    extern crate dotenvy;
99
100    use super::*;
101    use std::env;
102
103    use crate::connection::Connection;
104    use crate::connection::SimpleConnection;
105    use crate::query_dsl::RunQueryDsl;
106
107    fn connection() -> MariadbConnection {
108        dotenvy::dotenv().ok();
109        let database_url = env::var("MARIADB_UNIT_TEST_DATABASE_URL")
110            .or_else(|_| env::var("MARIADB_DATABASE_URL"))
111            .or_else(|_| env::var("DATABASE_URL"))
112            .expect("DATABASE_URL must be set in order to run unit tests");
113        MariadbConnection::establish(&database_url).unwrap()
114    }
115
116    #[diesel_test_helper::test]
117    fn batch_execute_handles_single_queries_with_results() {
118        let connection = &mut connection();
119        assert!(connection.batch_execute("SELECT 1").is_ok());
120        assert!(connection.batch_execute("SELECT 1").is_ok());
121    }
122
123    #[diesel_test_helper::test]
124    fn batch_execute_handles_multi_queries_with_results() {
125        let connection = &mut connection();
126        let query = "SELECT 1; SELECT 2; SELECT 3;";
127        assert!(connection.batch_execute(query).is_ok());
128        assert!(connection.batch_execute(query).is_ok());
129    }
130
131    #[diesel_test_helper::test]
132    fn execute_handles_queries_which_return_results() {
133        let connection = &mut connection();
134        assert!(crate::sql_query("SELECT 1").execute(connection).is_ok());
135        assert!(crate::sql_query("SELECT 1").execute(connection).is_ok());
136    }
137
138    #[diesel_test_helper::test]
139    fn check_client_found_rows_flag() {
140        let conn = &mut crate::test_helpers::connection();
141        crate::sql_query("DROP TABLE IF EXISTS update_test CASCADE")
142            .execute(conn)
143            .unwrap();
144
145        crate::sql_query("CREATE TABLE update_test(id INTEGER PRIMARY KEY, num INTEGER NOT NULL)")
146            .execute(conn)
147            .unwrap();
148
149        crate::sql_query("INSERT INTO update_test(id, num) VALUES (1, 5)")
150            .execute(conn)
151            .unwrap();
152
153        let output = crate::sql_query("UPDATE update_test SET num = 5 WHERE id = 1")
154            .execute(conn)
155            .unwrap();
156
157        assert_eq!(output, 1);
158    }
159
160    #[crate::declare_sql_function]
161    extern "SQL" {
162        fn version() -> crate::sql_types::Text;
163    }
164
165    #[diesel_test_helper::test]
166    fn version_matches_the_server_reported_version() {
167        let connection = &mut connection();
168        let expected = connection.version().unwrap().to_string();
169        let reported = crate::select(version())
170            .get_result::<String>(connection)
171            .unwrap();
172        assert!(
173            reported.starts_with(&format!("{expected}-")),
174            "`{reported}` does not start with `{expected}-`"
175        );
176    }
177}