sqlx_exasol_impl/responses/
attributes.rs1use std::{borrow::Cow, ops::Not};
2
3use serde::{Deserialize, Deserializer, Serialize};
4
5#[derive(Clone, Debug)]
14pub struct ExaAttributes {
15 read_write: ExaRwAttributes<'static>,
16 read_only: ExaRoAttributes,
17 driver: ExaDriverAttributes,
18}
19
20impl ExaAttributes {
21 pub(crate) fn new(
22 compression_enabled: bool,
23 fetch_size: usize,
24 encryption_enabled: bool,
25 statement_cache_capacity: usize,
26 ) -> Self {
27 Self {
28 read_write: ExaRwAttributes::default(),
29 read_only: ExaRoAttributes::new(compression_enabled),
30 driver: ExaDriverAttributes::new(
31 fetch_size,
32 encryption_enabled,
33 statement_cache_capacity,
34 ),
35 }
36 }
37
38 #[must_use]
39 pub fn autocommit(&self) -> bool {
40 self.read_write.autocommit
41 }
42
43 #[must_use]
44 pub fn current_schema(&self) -> Option<&str> {
45 self.read_write.current_schema.as_deref()
46 }
47
48 pub fn set_current_schema(&mut self, schema: String) -> &mut Self {
54 self.driver.needs_send = true;
55 self.read_write.current_schema = Some(schema.into());
56 self
57 }
58
59 #[must_use]
60 pub fn feedback_interval(&self) -> u64 {
61 self.read_write.feedback_interval
62 }
63
64 pub fn set_feedback_interval(&mut self, feedback_interval: u64) -> &mut Self {
65 self.driver.needs_send = true;
66 self.read_write.feedback_interval = feedback_interval;
67 self
68 }
69
70 #[must_use]
71 pub fn numeric_characters(&self) -> &str {
72 &self.read_write.numeric_characters
73 }
74
75 pub fn set_numeric_characters(&mut self, numeric_characters: String) -> &mut Self {
76 self.driver.needs_send = true;
77 self.read_write.numeric_characters = numeric_characters.into();
78 self
79 }
80
81 #[must_use]
82 pub fn query_timeout(&self) -> u64 {
83 self.read_write.query_timeout
84 }
85
86 #[must_use]
87 pub fn set_query_timeout(&mut self, query_timeout: u64) -> &mut Self {
88 self.driver.needs_send = true;
89 self.read_write.query_timeout = query_timeout;
90 self
91 }
92
93 #[must_use]
94 pub fn snapshot_transactions_enabled(&self) -> bool {
95 self.read_write.snapshot_transactions_enabled
96 }
97
98 pub fn set_snapshot_transactions_enabled(&mut self, enabled: bool) -> &mut Self {
99 self.driver.needs_send = true;
100 self.read_write.snapshot_transactions_enabled = enabled;
101 self
102 }
103
104 #[must_use]
105 pub fn timestamp_utc_enabled(&self) -> bool {
106 self.read_write.timestamp_utc_enabled
107 }
108
109 pub fn set_timestamp_utc_enabled(&mut self, enabled: bool) -> &mut Self {
110 self.driver.needs_send = true;
111 self.read_write.timestamp_utc_enabled = enabled;
112 self
113 }
114
115 #[must_use]
116 pub fn compression_enabled(&self) -> bool {
117 self.read_only.compression_enabled
118 }
119
120 #[must_use]
121 pub fn date_format(&self) -> &str {
122 &self.read_only.date_format
123 }
124
125 #[must_use]
126 pub fn date_language(&self) -> &str {
127 &self.read_only.date_language
128 }
129
130 #[must_use]
131 pub fn datetime_format(&self) -> &str {
132 &self.read_only.datetime_format
133 }
134
135 #[must_use]
136 pub fn default_like_escape_character(&self) -> &str {
137 &self.read_only.default_like_escape_character
138 }
139
140 #[must_use]
141 pub fn timezone(&self) -> &str {
142 &self.read_only.timezone
143 }
144
145 #[must_use]
146 pub fn timezone_behavior(&self) -> &str {
147 &self.read_only.timezone_behavior
148 }
149
150 #[must_use]
151 pub fn open_transaction(&self) -> bool {
152 self.driver.open_transaction
153 }
154
155 #[must_use]
156 pub fn fetch_size(&self) -> usize {
157 self.driver.fetch_size
158 }
159
160 pub fn set_fetch_size(&mut self, fetch_size: usize) -> &mut Self {
161 self.driver.fetch_size = fetch_size;
162 self
163 }
164
165 #[must_use]
166 pub fn encryption_enabled(&self) -> bool {
167 self.driver.encryption_enabled
168 }
169
170 #[must_use]
171 pub fn statement_cache_capacity(&self) -> usize {
172 self.driver.statement_cache_capacity
173 }
174
175 pub(crate) fn needs_send(&self) -> bool {
176 self.driver.needs_send
177 }
178
179 pub(crate) fn set_needs_send(&mut self, flag: bool) -> &mut Self {
180 self.driver.needs_send = flag;
181 self
182 }
183
184 pub(crate) fn set_autocommit(&mut self, autocommit: bool) -> &mut Self {
185 self.driver.needs_send = true;
186 self.read_write.autocommit = autocommit;
187 self.driver.open_transaction = !autocommit;
188 self
189 }
190
191 pub(crate) fn read_write(&self) -> &ExaRwAttributes<'static> {
192 &self.read_write
193 }
194
195 pub(crate) fn update(&mut self, other: ExaAttributesOpt) {
196 macro_rules! other_or_prev {
197 ($kind:tt, $field:tt) => {
198 if let Some(new) = other.$field {
199 self.$kind.$field = new.into();
200 }
201 };
202 }
203
204 self.read_write.current_schema = other.current_schema.map(From::from);
205
206 other_or_prev!(read_write, autocommit);
207 other_or_prev!(read_write, feedback_interval);
208 other_or_prev!(read_write, numeric_characters);
209 other_or_prev!(read_write, query_timeout);
210 other_or_prev!(read_write, snapshot_transactions_enabled);
211 other_or_prev!(read_write, timestamp_utc_enabled);
212 other_or_prev!(read_only, compression_enabled);
213 other_or_prev!(read_only, date_format);
214 other_or_prev!(read_only, date_language);
215 other_or_prev!(read_only, datetime_format);
216 other_or_prev!(read_only, default_like_escape_character);
217 other_or_prev!(read_only, timezone);
218 other_or_prev!(read_only, timezone_behavior);
219 }
220}
221
222#[derive(Clone, Debug, Serialize)]
227#[serde(rename_all = "camelCase")]
228pub struct ExaRwAttributes<'a> {
229 #[serde(skip_serializing_if = "Option::is_none")]
232 current_schema: Option<Cow<'a, str>>,
233 autocommit: bool,
234 feedback_interval: u64,
235 numeric_characters: Cow<'a, str>,
236 query_timeout: u64,
237 snapshot_transactions_enabled: bool,
238 timestamp_utc_enabled: bool,
239}
240
241impl<'a> ExaRwAttributes<'a> {
242 pub(crate) fn new(
243 current_schema: Option<Cow<'a, str>>,
244 feedback_interval: u64,
245 query_timeout: u64,
246 ) -> Self {
247 Self {
248 current_schema,
249 feedback_interval,
250 query_timeout,
251 ..Default::default()
252 }
253 }
254}
255
256impl Default for ExaRwAttributes<'_> {
257 fn default() -> Self {
258 Self {
259 autocommit: true,
260 current_schema: None,
261 feedback_interval: 1,
262 numeric_characters: Cow::Owned(".,".into()),
263 query_timeout: 0,
264 snapshot_transactions_enabled: false,
265 timestamp_utc_enabled: false,
266 }
267 }
268}
269
270#[derive(Clone, Debug)]
271struct ExaRoAttributes {
272 compression_enabled: bool,
273 date_format: String,
274 date_language: String,
275 datetime_format: String,
276 default_like_escape_character: String,
277 timezone: String,
278 timezone_behavior: String,
279}
280
281impl ExaRoAttributes {
282 fn new(compression_enabled: bool) -> Self {
283 Self {
284 compression_enabled,
285 date_format: "YYYY-MM-DD".to_owned(),
286 date_language: "ENG".to_owned(),
287 datetime_format: "YYYY-MM-DD HH24:MI:SS.FF6".to_owned(),
288 default_like_escape_character: "\\".to_owned(),
289 timezone: "UNIVERSAL".to_owned(),
290 timezone_behavior: "INVALID SHIFT AMBIGUOUS ST".to_owned(),
291 }
292 }
293}
294
295#[derive(Clone, Debug)]
296struct ExaDriverAttributes {
297 open_transaction: bool,
300 needs_send: bool,
301 fetch_size: usize,
302 encryption_enabled: bool,
303 statement_cache_capacity: usize,
304}
305
306impl ExaDriverAttributes {
307 fn new(fetch_size: usize, encryption_enabled: bool, statement_cache_capacity: usize) -> Self {
308 Self {
309 open_transaction: false,
310 needs_send: false,
311 fetch_size,
312 encryption_enabled,
313 statement_cache_capacity,
314 }
315 }
316}
317
318#[derive(Debug, Default, Deserialize)]
325#[serde(rename_all = "camelCase")]
326pub struct ExaAttributesOpt {
327 autocommit: Option<bool>,
331 #[serde(default)]
332 #[serde(deserialize_with = "ExaAttributesOpt::deserialize_current_schema")]
333 current_schema: Option<String>,
334 feedback_interval: Option<u64>,
335 numeric_characters: Option<String>,
336 query_timeout: Option<u64>,
337 snapshot_transactions_enabled: Option<bool>,
338 timestamp_utc_enabled: Option<bool>,
339 compression_enabled: Option<bool>,
343 date_format: Option<String>,
344 date_language: Option<String>,
345 datetime_format: Option<String>,
346 default_like_escape_character: Option<String>,
347 timezone: Option<String>,
348 timezone_behavior: Option<String>,
349}
350
351impl ExaAttributesOpt {
352 fn deserialize_current_schema<'de, D>(deserializer: D) -> Result<Option<String>, D::Error>
354 where
355 D: Deserializer<'de>,
356 {
357 let Some(value) = Option::deserialize(deserializer)? else {
358 return Ok(None);
359 };
360
361 Ok(String::is_empty(&value).not().then_some(value))
362 }
363}