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}