sqlx_rxqlite/options/
connect.rs

1use crate::connection::RXQLiteConnection;
2use crate::options::RXQLiteConnectOptions;
3
4use futures_core::future::BoxFuture;
5use log::LevelFilter;
6use sqlx_core::connection::ConnectOptions;
7use sqlx_core::error::Error;
8
9use std::str::FromStr;
10use std::time::Duration;
11use url::Url;
12
13impl ConnectOptions for RXQLiteConnectOptions {
14    type Connection = RXQLiteConnection;
15    // borrowed from sqlx-mysql
16    fn from_url(url: &Url) -> Result<Self, Error> {
17        let mut options= RXQLiteConnectOptions::default();
18        if let Some(host) = url.host_str() {
19            options.node_host = host.into();
20        }
21
22        if let Some(port) = url.port() {
23            options.node_port = port;
24        }
25        /*
26        let username = url.username();
27        if !username.is_empty() {
28            options.user = Some(
29                percent_decode_str(username)
30                    .decode_utf8()
31                    .map_err(Error::config)?
32                    .to_string(),
33            );
34        }
35
36        if let Some(password) = url.password() {
37            options.pass = Some(
38                percent_decode_str(password)
39                    .decode_utf8()
40                    .map_err(Error::config)?
41                    .to_string(),
42            );
43        }
44        */
45        /*
46        let path = url.path().trim_start_matches('/');
47        if !path.is_empty() {
48            options = options.database(path);
49        }
50        */
51        for (key, value) in url.query_pairs().into_iter() {
52            match &*key {
53                "ssl" => {
54                    if value == "yes" || value == "1" {
55                        if options.tls_config.is_none() {
56                            options.tls_config = Some(Default::default());
57                        }
58                        options
59                            .tls_config
60                            .as_mut()
61                            .unwrap()
62                            .accept_invalid_certificates = false;
63                    }
64                }
65                "ssl-insecure" => {
66                    if value == "yes" || value == "1" {
67                        if options.tls_config.is_none() {
68                            options.tls_config = Some(Default::default());
69                        }
70                        options
71                            .tls_config
72                            .as_mut()
73                            .unwrap()
74                            .accept_invalid_certificates = true;
75                    }
76                }
77                _ => {}
78            }
79            
80        }
81        Ok(options)
82    }
83    fn to_url_lossy(&self) -> Url {
84        self.build_url()
85    }
86
87    fn connect(&self) -> BoxFuture<'_, Result<Self::Connection, Error>>
88    where
89        Self::Connection: Sized,
90    {
91        Box::pin(async move {
92            let conn = RXQLiteConnection::establish(self).await?;
93            /*
94                        // After the connection is established, we initialize by configuring a few
95                        // connection parameters
96
97                        // https://mariadb.com/kb/en/sql-mode/
98
99                        // PIPES_AS_CONCAT - Allows using the pipe character (ASCII 124) as string concatenation operator.
100                        //                   This means that "A" || "B" can be used in place of CONCAT("A", "B").
101
102                        // NO_ENGINE_SUBSTITUTION - If not set, if the available storage engine specified by a CREATE TABLE is
103                        //                          not available, a warning is given and the default storage
104                        //                          engine is used instead.
105
106                        // NO_ZERO_DATE - Don't allow '0000-00-00'. This is invalid in Rust.
107
108                        // NO_ZERO_IN_DATE - Don't allow 'YYYY-00-00'. This is invalid in Rust.
109
110                        // --
111
112                        // Setting the time zone allows us to assume that the output
113                        // from a TIMESTAMP field is UTC
114
115                        // --
116
117                        // https://mathiasbynens.be/notes/mysql-utf8mb4
118
119                        let mut sql_mode = Vec::new();
120                        if self.pipes_as_concat {
121                            sql_mode.push(r#"PIPES_AS_CONCAT"#);
122                        }
123                        if self.no_engine_subsitution {
124                            sql_mode.push(r#"NO_ENGINE_SUBSTITUTION"#);
125                        }
126
127                        let mut options = Vec::new();
128                        if !sql_mode.is_empty() {
129                            options.push(format!(
130                                r#"sql_mode=(SELECT CONCAT(@@sql_mode, ',{}'))"#,
131                                sql_mode.join(",")
132                            ));
133                        }
134                        if let Some(timezone) = &self.timezone {
135                            options.push(format!(r#"time_zone='{}'"#, timezone));
136                        }
137                        if self.set_names {
138                            options.push(format!(
139                                r#"NAMES {} COLLATE {}"#,
140                                conn.stream.charset.as_str(),
141                                conn.stream.collation.as_str()
142                            ))
143                        }
144
145                        if !options.is_empty() {
146                            conn.execute(&*format!(r#"SET {};"#, options.join(",")))
147                                .await?;
148                        }
149            */
150            Ok(conn)
151        })
152    }
153
154    fn log_statements(self, _level: LevelFilter) -> Self {
155        //self.log_settings.log_statements(level);
156        self
157    }
158
159    fn log_slow_statements(self, _level: LevelFilter, _duration: Duration) -> Self {
160        //self.log_settings.log_slow_statements(level, duration);
161        self
162    }
163}
164
165impl FromStr for RXQLiteConnectOptions {
166    type Err = Error;
167
168    fn from_str(s: &str) -> Result<Self, Error> {
169        let url: Url = s.parse().map_err(Error::config)?;
170        Self::from_url(&url)
171    }
172}