Skip to main content

sqlx_xugu/options/
mod.rs

1mod connect;
2mod parse;
3
4use sqlx_core::connection::LogSettings;
5
6#[derive(Debug, Clone)]
7pub struct XuguConnectOptions {
8    pub(crate) host: String,
9    pub(crate) port: u16,
10    pub(crate) user: String,
11    pub(crate) password: String,
12    pub(crate) database: String,
13    pub(crate) charset: String,
14    version: Option<i16>,
15    return_schema: bool,
16    return_rowid: bool,
17    encryptor: Option<String>,
18    time_zone: Option<String>,
19    iso_level: Option<String>,
20    lock_timeout: Option<String>,
21    lob_ret: Option<String>,
22    identity_mode: Option<String>,
23    keyword_filter: Option<String>,
24    disable_binlog: Option<String>,
25    auto_commit: bool,
26    pub(crate) use_ssl: bool,
27    current_schema: Option<String>,
28    compatible_mode: Option<String>,
29
30    pub(crate) log_settings: LogSettings,
31    pub(crate) statement_cache_capacity: usize,
32}
33
34impl Default for XuguConnectOptions {
35    fn default() -> Self {
36        Self::new()
37    }
38}
39
40impl XuguConnectOptions {
41    pub(crate) fn to_conn_str(&self) -> String {
42        let return_schema = if self.return_schema { "on" } else { "off" };
43        let version = self.get_version();
44        // 必要参数
45        let mut conn_str = format!(
46            "login database='{}' user='{}' password='{}' version={} return_schema={} return_cursor_id=on",
47            self.database, self.user, self.password, version, return_schema,
48        );
49
50        // 可选参数
51        if self.return_rowid {
52            conn_str += " return_rowid=true";
53        }
54        if let Some(encryptor) = &self.encryptor {
55            conn_str += " encryptor=";
56            conn_str += encryptor;
57        }
58        if self.charset.is_empty() {
59            conn_str += " char_set=utf8";
60        } else {
61            conn_str = conn_str + " char_set=" + self.charset.as_str();
62        }
63        if let Some(time_zone) = &self.time_zone {
64            conn_str = conn_str + " time_zone='" + time_zone + "'";
65        }
66        if let Some(iso_level) = &self.iso_level {
67            conn_str += " iso_level='";
68            conn_str += iso_level;
69            conn_str += "'";
70        }
71        if let Some(lock_timeout) = &self.lock_timeout {
72            conn_str += " lock_timeout=";
73            conn_str += lock_timeout;
74        }
75        if let Some(lob_ret) = &self.lob_ret {
76            conn_str += " lob_ret='";
77            conn_str += lob_ret;
78            conn_str += "'";
79        }
80        if let Some(identity_mode) = &self.identity_mode {
81            conn_str += " identity_mode='";
82            conn_str += identity_mode;
83            conn_str += "'";
84        }
85        if let Some(keyword_filter) = &self.keyword_filter {
86            conn_str += " keyword_filter='";
87            conn_str += keyword_filter;
88            conn_str += "'";
89        }
90        if let Some(disable_binlog) = &self.disable_binlog {
91            conn_str += " disable_binlog='";
92            conn_str += disable_binlog;
93            conn_str += "'";
94        }
95        if self.auto_commit {
96            conn_str += " auto_commit=on";
97        } else {
98            conn_str += " auto_commit=off";
99        }
100        if let Some(current_schema) = &self.current_schema {
101            conn_str += " current_schema='";
102            conn_str += current_schema;
103            conn_str += "'";
104        }
105        if let Some(compatible_mode) = &self.compatible_mode {
106            conn_str += " compatible_mode='";
107            conn_str += compatible_mode;
108            conn_str += "'";
109        }
110
111        conn_str += "\0";
112        conn_str
113    }
114
115    pub fn get_version(&self) -> i16 {
116        self.version.unwrap_or(301)
117    }
118}
119
120impl XuguConnectOptions {
121    /// Creates a new, default set of options ready for configuration
122    pub fn new() -> Self {
123        Self {
124            host: String::from("127.0.0.1"),
125            port: 5138,
126            database: String::from("SYSTEM"),
127            user: String::from("SYSDBA"),
128            password: String::from("SYSDBA"),
129            version: None,
130            return_schema: true,
131            return_rowid: false,
132            encryptor: None,
133            charset: String::from("utf8"),
134            time_zone: None,
135            iso_level: Some(String::from("READ COMMITTED")),
136            lock_timeout: None,
137            lob_ret: None,
138            identity_mode: None,
139            keyword_filter: None,
140            disable_binlog: None,
141            auto_commit: true,
142            use_ssl: false,
143            current_schema: None,
144            compatible_mode: None,
145
146            log_settings: Default::default(),
147
148            statement_cache_capacity: 100,
149        }
150    }
151
152    /// Sets the name of the host to connect to.
153    ///
154    /// The default behavior when the host is not specified,
155    /// is to connect to localhost.
156    pub fn host(mut self, host: &str) -> Self {
157        host.clone_into(&mut self.host);
158        self
159    }
160
161    /// Sets the port to connect to at the server host.
162    ///
163    /// The default port for MySQL is `3306`.
164    pub fn port(mut self, port: u16) -> Self {
165        self.port = port;
166        self
167    }
168
169    /// Sets the database name.
170    pub fn database(mut self, database: &str) -> Self {
171        self.database = database.to_owned();
172        self
173    }
174
175    /// Sets the user to connect as.
176    pub fn user(mut self, user: &str) -> Self {
177        user.clone_into(&mut self.user);
178        self
179    }
180
181    /// Sets the password to connect with.
182    pub fn password(mut self, password: &str) -> Self {
183        self.password = password.to_owned();
184        self
185    }
186
187    /// Sets the version to connect with.
188    pub fn version(mut self, version: i16) -> Self {
189        self.version = Some(version);
190        self
191    }
192
193    pub fn return_schema(mut self, value: bool) -> Self {
194        self.return_schema = value;
195        self
196    }
197
198    pub fn return_rowid(mut self, value: bool) -> Self {
199        self.return_schema = value;
200        self
201    }
202
203    pub fn encryptor(mut self, value: &str) -> Self {
204        self.encryptor = Some(value.into());
205        self
206    }
207
208    pub fn iso_level(mut self, value: &str) -> Self {
209        self.iso_level = Some(value.into());
210        self
211    }
212
213    pub fn lock_timeout(mut self, value: &str) -> Self {
214        self.lock_timeout = Some(value.into());
215        self
216    }
217
218    pub fn lob_ret(mut self, value: &str) -> Self {
219        self.lob_ret = Some(value.into());
220        self
221    }
222
223    pub fn identity_mode(mut self, value: &str) -> Self {
224        self.identity_mode = Some(value.into());
225        self
226    }
227
228    pub fn keyword_filter(mut self, value: &str) -> Self {
229        self.keyword_filter = Some(value.into());
230        self
231    }
232
233    pub fn disable_binlog(mut self, value: &str) -> Self {
234        self.disable_binlog = Some(value.into());
235        self
236    }
237
238    pub fn auto_commit(mut self, value: bool) -> Self {
239        self.auto_commit = value;
240        self
241    }
242
243    pub fn use_ssl(mut self, value: bool) -> Self {
244        self.use_ssl = value;
245        self
246    }
247
248    pub fn current_schema(mut self, value: &str) -> Self {
249        self.current_schema = Some(value.into());
250        self
251    }
252
253    pub fn compatible_mode(mut self, value: &str) -> Self {
254        self.compatible_mode = Some(value.into());
255        self
256    }
257
258    /// Sets the character set for the connection.
259    ///
260    /// The default character set is `utf8mb4`. This is supported from MySQL 5.5.3.
261    /// If you need to connect to an older version, we recommend you to change this to `utf8`.
262    ///
263    /// Implies [`.set_names(true)`][Self::set_names()].
264    pub fn charset(mut self, charset: &str) -> Self {
265        charset.clone_into(&mut self.charset);
266        self
267    }
268
269    /// If `Some`, sets the `time_zone` option to the given string after connecting to the database.
270    ///
271    /// If `None`, no `time_zone` parameter is sent; the server timezone will be used instead.
272    ///
273    /// Defaults to `Some(String::from("+00:00"))` to ensure all timestamps are in UTC.
274    ///
275    /// ### Warning
276    /// Changing this setting from its default will apply an unexpected skew to any
277    /// `time::OffsetDateTime` or `chrono::DateTime<Utc>` value, whether passed as a parameter or
278    /// decoded as a result. `TIMESTAMP` values are not encoded with their UTC offset in the MySQL
279    /// protocol, so encoding and decoding of these types assumes the server timezone is *always*
280    /// UTC.
281    ///
282    /// If you are changing this option, ensure your application only uses
283    /// `time::PrimitiveDateTime` or `chrono::NaiveDateTime` and that it does not assume these
284    /// timestamps can be placed on a real timeline without applying the proper offset.
285    pub fn timezone(mut self, value: impl Into<Option<String>>) -> Self {
286        self.time_zone = value.into();
287        self
288    }
289
290    /// 单个连接会话上的最大预处理语句数量
291    ///
292    /// 取值范围 `[100, 2097152]`
293    ///
294    /// Sets the capacity of the connection's statement cache in a number of stored
295    /// distinct statements. Caching is handled using LRU, meaning when the
296    /// amount of queries hits the defined limit, the oldest statement will get
297    /// dropped.
298    ///
299    /// The default cache capacity is 100 statements.
300    pub fn statement_cache_capacity(mut self, capacity: usize) -> Self {
301        self.statement_cache_capacity = capacity.clamp(100, 2097152);
302        self
303    }
304}
305
306impl XuguConnectOptions {
307    /// Get the current host.
308    ///
309    /// # Example
310    ///
311    /// ```rust
312    /// # use sqlx_xugu::XuguConnectOptions;
313    /// let options = XuguConnectOptions::new()
314    ///     .host("127.0.0.1");
315    /// assert_eq!(options.get_host(), "127.0.0.1");
316    /// ```
317    pub fn get_host(&self) -> &str {
318        &self.host
319    }
320
321    /// Get the server's port.
322    ///
323    /// # Example
324    ///
325    /// ```rust
326    /// # use sqlx_xugu::XuguConnectOptions;
327    /// let options = XuguConnectOptions::new()
328    ///     .port(5138);
329    /// assert_eq!(options.get_port(), 5138);
330    /// ```
331    pub fn get_port(&self) -> u16 {
332        self.port
333    }
334
335    /// Get the current user.
336    ///
337    /// # Example
338    ///
339    /// ```rust
340    /// # use sqlx_xugu::XuguConnectOptions;
341    /// let options = XuguConnectOptions::new()
342    ///     .user("foo");
343    /// assert_eq!(options.get_user(), "foo");
344    /// ```
345    pub fn get_user(&self) -> &str {
346        &self.user
347    }
348
349    /// Get the current database name.
350    ///
351    /// # Example
352    ///
353    /// ```rust
354    /// # use sqlx_xugu::XuguConnectOptions;
355    /// let options = XuguConnectOptions::new()
356    ///     .database("SYSTEM");
357    /// assert_eq!(options.get_database(), "SYSTEM");
358    /// ```
359    pub fn get_database(&self) -> &str {
360        &self.database
361    }
362
363    /// Get the server charset.
364    ///
365    /// # Example
366    ///
367    /// ```rust
368    /// # use sqlx_xugu::XuguConnectOptions;
369    /// let options = XuguConnectOptions::new();
370    /// assert_eq!(options.get_charset(), "utf8");
371    /// ```
372    pub fn get_charset(&self) -> &str {
373        &self.charset
374    }
375}