1use crate::executor::database::Options;
2use crate::{Convert, TryConvert};
3use bytes::BytesMut;
4use odbc_api::buffers::{AnySlice, BufferDescription, BufferKind};
5use odbc_api::sys::{Date, Time, Timestamp, NULL_DATA};
6use odbc_api::DataType;
7use std::cmp::min;
8
9#[derive(Debug, Clone)]
10pub struct OdbcColumn {
11 pub name: String,
12 pub data_type: DataType,
13 pub nullable: bool,
14}
15
16impl OdbcColumn {
17 pub fn new(name: String, data_type: DataType, nullable: bool) -> Self {
18 Self {
19 name,
20 data_type,
21 nullable,
22 }
23 }
24}
25
26impl TryConvert<BufferDescription> for (&OdbcColumn, &Options) {
27 type Error = String;
28
29 fn try_convert(self) -> Result<BufferDescription, Self::Error> {
30 let c = self.0;
31 let option = self.1;
32 let mut description = BufferDescription {
33 nullable: c.nullable,
34 kind: BufferKind::from_data_type(c.data_type)
35 .ok_or_else(|| format!("covert DataType:{:?} to BufferKind error", c.data_type))?,
36 };
37
38 match description.kind {
42 BufferKind::Text { max_str_len } => {
45 description.kind = BufferKind::Text {
46 max_str_len: min(max_str_len, option.max_str_len),
47 };
48 }
49 BufferKind::WText { max_str_len } => {
50 description.kind = BufferKind::WText {
51 max_str_len: min(max_str_len, option.max_str_len),
52 };
53 }
54 BufferKind::Binary { length } => {
55 description.kind = BufferKind::Binary {
56 length: min(length, option.max_binary_len),
57 }
58 }
59 _ => {}
60 }
61
62 Ok(description)
63 }
64}
65
66#[derive(Debug)]
67pub struct OdbcColumnItem {
68 pub odbc_type: OdbcColumnType,
69 pub value: Option<BytesMut>,
70}
71
72#[derive(Debug)]
73pub enum OdbcColumnType {
74 Text,
75 WText,
76 Binary,
77 Date,
78 Time,
79 Timestamp,
80 F64,
81 F32,
82 I8,
83 I16,
84 I32,
85 I64,
86 U8,
87 Bit,
88}
89
90impl ToString for OdbcColumnItem {
91 fn to_string(&self) -> String {
92 format!("{:?}", self)
93 }
94}
95
96impl Convert<Vec<OdbcColumnItem>> for AnySlice<'_> {
97 fn convert(self) -> Vec<OdbcColumnItem> {
98 match self {
99 AnySlice::Text(view) => {
100 let mut buffer = Vec::with_capacity(view.len());
101 for v in view.iter() {
102 if let Some(x) = v {
103 buffer.push(OdbcColumnItem {
104 odbc_type: OdbcColumnType::Text,
105 value: Some(BytesMut::from(x)),
106 });
107 } else {
108 buffer.push(OdbcColumnItem {
109 odbc_type: OdbcColumnType::Text,
110 value: None,
111 })
112 }
113 }
114 buffer
115 }
116 AnySlice::WText(view) => {
117 let mut buffer = Vec::with_capacity(view.len());
118 for v in view.iter() {
119 if let Some(x) = v {
120 buffer.push(OdbcColumnItem {
121 odbc_type: OdbcColumnType::WText,
122 value: Some(BytesMut::from(x.to_string().unwrap().as_bytes())),
123 });
124 } else {
125 buffer.push(OdbcColumnItem {
126 odbc_type: OdbcColumnType::WText,
127 value: None,
128 })
129 }
130 }
131 buffer
132 }
133 AnySlice::Binary(view) => {
134 let mut buffer = vec![];
135 for value in view.iter() {
136 if let Some(bytes) = value {
137 buffer.push(OdbcColumnItem {
138 odbc_type: OdbcColumnType::Binary,
139 value: Some(BytesMut::from(bytes)),
140 })
141 } else {
142 buffer.push(OdbcColumnItem {
143 odbc_type: OdbcColumnType::Binary,
144 value: None,
145 })
146 }
147 }
148 buffer
149 }
150 AnySlice::Date(view) => {
151 let mut buffer = vec![];
152 for value in view.iter() {
153 let val = value.try_convert().unwrap();
154 buffer.push(OdbcColumnItem {
155 odbc_type: OdbcColumnType::Date,
156 value: Some(BytesMut::from(val.to_string().as_bytes())),
157 })
158 }
159 buffer
160 }
161 AnySlice::Timestamp(view) => {
162 let mut buffer = vec![];
163 for value in view.iter() {
164 let val: time::PrimitiveDateTime = value.try_convert().unwrap();
165 buffer.push(OdbcColumnItem {
166 odbc_type: OdbcColumnType::Timestamp,
167 value: Some(BytesMut::from(val.to_string().as_bytes())),
168 })
169 }
170 buffer
171 }
172 AnySlice::Time(view) => {
173 let mut buffer = vec![];
174 for value in view.iter() {
175 let val = value.try_convert().unwrap();
176 buffer.push(OdbcColumnItem {
177 odbc_type: OdbcColumnType::Time,
178 value: Some(BytesMut::from(val.to_string().as_bytes())),
179 })
180 }
181 buffer
182 }
183 AnySlice::I32(view) => {
184 let mut buffer = vec![];
185 for value in view.iter() {
186 buffer.push(OdbcColumnItem {
187 odbc_type: OdbcColumnType::I32,
188 value: Some(BytesMut::from(value.to_string().as_bytes())),
189 })
190 }
191 buffer
192 }
193 AnySlice::Bit(view) => {
194 let mut buffer = vec![];
195 for value in view.iter() {
196 buffer.push(OdbcColumnItem {
197 odbc_type: OdbcColumnType::Bit,
198 value: Some(BytesMut::from(value.as_bool().to_string().as_bytes())),
199 })
200 }
201 buffer
202 }
203
204 AnySlice::F64(view) => {
205 let mut buffer = vec![];
206 for value in view.iter() {
207 buffer.push(OdbcColumnItem {
208 odbc_type: OdbcColumnType::F64,
209 value: Some(BytesMut::from(value.to_string().as_bytes())),
210 })
211 }
212 buffer
213 }
214 AnySlice::F32(view) => {
215 let mut buffer = vec![];
216 for value in view.iter() {
217 buffer.push(OdbcColumnItem {
218 odbc_type: OdbcColumnType::F32,
219 value: Some(BytesMut::from(value.to_string().as_bytes())),
220 })
221 }
222 buffer
223 }
224 AnySlice::I8(view) => {
225 let mut buffer = vec![];
226 for value in view.iter() {
227 buffer.push(OdbcColumnItem {
228 odbc_type: OdbcColumnType::I8,
229 value: Some(BytesMut::from(value.to_string().as_bytes())),
230 })
231 }
232 buffer
233 }
234 AnySlice::I16(view) => {
235 let mut buffer = vec![];
236 for value in view.iter() {
237 buffer.push(OdbcColumnItem {
238 odbc_type: OdbcColumnType::I16,
239 value: Some(BytesMut::from(value.to_string().as_bytes())),
240 })
241 }
242 buffer
243 }
244 AnySlice::I64(view) => {
245 let mut buffer = vec![];
246 for value in view.iter() {
247 buffer.push(OdbcColumnItem {
248 odbc_type: OdbcColumnType::I64,
249 value: Some(BytesMut::from(value.to_string().as_bytes())),
250 })
251 }
252 buffer
253 }
254 AnySlice::U8(view) => {
255 let mut buffer = vec![];
256
257 for value in view.iter() {
258 buffer.push(OdbcColumnItem {
259 odbc_type: OdbcColumnType::U8,
260 value: Some(BytesMut::from(vec![*value].as_slice())),
261 })
262 }
263 buffer
264 }
265 AnySlice::NullableDate(view) => {
266 let (values, indicators) = view.raw_values();
267 let values = values.to_vec();
268
269 values
270 .iter()
271 .enumerate()
272 .map(|(index, value)| {
273 if indicators[index] != NULL_DATA {
274 let val = value.try_convert().unwrap();
275 OdbcColumnItem {
276 odbc_type: OdbcColumnType::Date,
277 value: Some(BytesMut::from(val.to_string().as_bytes())),
278 }
279 } else {
280 OdbcColumnItem {
281 odbc_type: OdbcColumnType::Date,
282 value: None,
283 }
284 }
285 })
286 .collect()
287 }
288 AnySlice::NullableTime(view) => {
289 let (values, indicators) = view.raw_values();
290 let values = values.to_vec();
291
292 values
293 .iter()
294 .enumerate()
295 .map(|(index, value)| {
296 if indicators[index] != NULL_DATA {
297 let val = value.try_convert().unwrap();
298 OdbcColumnItem {
299 odbc_type: OdbcColumnType::Time,
300 value: Some(BytesMut::from(val.to_string().as_bytes())),
301 }
302 } else {
303 OdbcColumnItem {
304 odbc_type: OdbcColumnType::Time,
305 value: None,
306 }
307 }
308 })
309 .collect()
310 }
311 AnySlice::NullableTimestamp(view) => {
312 let (values, indicators) = view.raw_values();
313 let values = values.to_vec();
314
315 values
316 .iter()
317 .enumerate()
318 .map(|(index, value)| {
319 if indicators[index] != NULL_DATA {
320 let val: time::PrimitiveDateTime = value.try_convert().unwrap();
321 OdbcColumnItem {
322 odbc_type: OdbcColumnType::Timestamp,
323 value: Some(BytesMut::from(val.to_string().as_bytes())),
324 }
325 } else {
326 OdbcColumnItem {
327 odbc_type: OdbcColumnType::Timestamp,
328 value: None,
329 }
330 }
331 })
332 .collect()
333 }
334 AnySlice::NullableF64(view) => {
335 let (values, indicators) = view.raw_values();
336 let values = values.to_vec();
337
338 values
339 .iter()
340 .enumerate()
341 .map(|(index, value)| {
342 if indicators[index] != NULL_DATA {
343 OdbcColumnItem {
344 odbc_type: OdbcColumnType::F64,
345 value: Some(BytesMut::from(value.to_string().as_bytes())),
346 }
347 } else {
348 OdbcColumnItem {
349 odbc_type: OdbcColumnType::F64,
350 value: None,
351 }
352 }
353 })
354 .collect()
355 }
356 AnySlice::NullableF32(view) => {
357 let (values, indicators) = view.raw_values();
358 let values = values.to_vec();
359
360 values
361 .iter()
362 .enumerate()
363 .map(|(index, value)| {
364 if indicators[index] != NULL_DATA {
365 OdbcColumnItem {
366 odbc_type: OdbcColumnType::F32,
367 value: Some(BytesMut::from(value.to_string().as_bytes())),
368 }
369 } else {
370 OdbcColumnItem {
371 odbc_type: OdbcColumnType::F32,
372 value: None,
373 }
374 }
375 })
376 .collect()
377 }
378 AnySlice::NullableI8(view) => {
379 let (values, indicators) = view.raw_values();
380 let values = values.to_vec();
381
382 values
383 .iter()
384 .enumerate()
385 .map(|(index, value)| {
386 if indicators[index] != NULL_DATA {
387 OdbcColumnItem {
388 odbc_type: OdbcColumnType::I8,
389 value: Some(BytesMut::from(value.to_string().as_bytes())),
390 }
391 } else {
392 OdbcColumnItem {
393 odbc_type: OdbcColumnType::I8,
394 value: None,
395 }
396 }
397 })
398 .collect()
399 }
400 AnySlice::NullableI16(view) => {
401 let (values, indicators) = view.raw_values();
402 let values = values.to_vec();
403
404 values
405 .iter()
406 .enumerate()
407 .map(|(index, value)| {
408 if indicators[index] != NULL_DATA {
409 OdbcColumnItem {
410 odbc_type: OdbcColumnType::I16,
411 value: Some(BytesMut::from(value.to_string().as_bytes())),
412 }
413 } else {
414 OdbcColumnItem {
415 odbc_type: OdbcColumnType::I16,
416 value: None,
417 }
418 }
419 })
420 .collect()
421 }
422 AnySlice::NullableI32(view) => {
423 let (values, indicators) = view.raw_values();
424 let values = values.to_vec();
425
426 values
427 .iter()
428 .enumerate()
429 .map(|(index, value)| {
430 if indicators[index] != NULL_DATA {
431 OdbcColumnItem {
432 odbc_type: OdbcColumnType::I32,
433 value: Some(BytesMut::from(value.to_string().as_bytes())),
434 }
435 } else {
436 OdbcColumnItem {
437 odbc_type: OdbcColumnType::I32,
438 value: None,
439 }
440 }
441 })
442 .collect()
443 }
444 AnySlice::NullableI64(view) => {
445 let (values, indicators) = view.raw_values();
446 let values = values.to_vec();
447
448 values
449 .iter()
450 .enumerate()
451 .map(|(index, value)| {
452 if indicators[index] != NULL_DATA {
453 OdbcColumnItem {
454 odbc_type: OdbcColumnType::I64,
455 value: Some(BytesMut::from(value.to_string().as_bytes())),
456 }
457 } else {
458 OdbcColumnItem {
459 odbc_type: OdbcColumnType::I64,
460 value: None,
461 }
462 }
463 })
464 .collect()
465 }
466 AnySlice::NullableU8(view) => {
467 let (values, indicators) = view.raw_values();
468 let values = values.to_vec();
469
470 values
471 .iter()
472 .enumerate()
473 .map(|(index, value)| {
474 if indicators[index] != NULL_DATA {
475 OdbcColumnItem {
476 odbc_type: OdbcColumnType::U8,
477 value: Some(BytesMut::from(vec![*value].as_slice())),
478 }
479 } else {
480 OdbcColumnItem {
481 odbc_type: OdbcColumnType::U8,
482 value: None,
483 }
484 }
485 })
486 .collect()
487 }
488 AnySlice::NullableBit(view) => {
489 let (values, indicators) = view.raw_values();
490 let values = values.to_vec();
491
492 values
493 .iter()
494 .enumerate()
495 .map(|(index, value)| {
496 if indicators[index] != NULL_DATA {
497 OdbcColumnItem {
498 odbc_type: OdbcColumnType::Bit,
499 value: Some(BytesMut::from(value.as_bool().to_string().as_bytes())),
500 }
501 } else {
502 OdbcColumnItem {
503 odbc_type: OdbcColumnType::Bit,
504 value: None,
505 }
506 }
507 })
508 .collect()
509 }
510 }
511 }
512}
513
514impl TryConvert<time::Date> for Date {
531 type Error = time::Error;
532
533 fn try_convert(self) -> Result<time::Date, Self::Error> {
534 Ok(time::Date::from_calendar_date(
535 self.year as i32,
536 time::Month::try_from(self.month as u8)?,
537 self.day as u8,
538 )?)
539 }
540}
541
542impl TryConvert<time::Time> for Time {
559 type Error = time::Error;
560 fn try_convert(self) -> Result<time::Time, Self::Error> {
561 Ok(time::Time::from_hms(
562 self.hour as u8,
563 self.minute as u8,
564 self.second as u8,
565 )?)
566 }
567}
568
569impl TryConvert<time::Time> for (Time, u32) {
570 type Error = time::Error;
571 fn try_convert(self) -> Result<time::Time, Self::Error> {
572 let time = self.0;
573 let nanosecond = self.1;
574
575 Ok(time::Time::from_hms_nano(
576 time.hour as u8,
577 time.minute as u8,
578 time.second as u8,
579 nanosecond,
580 )?)
581 }
582}
583
584impl TryConvert<(time::Date, time::Time)> for Timestamp {
585 type Error = time::Error;
586
587 fn try_convert(self) -> Result<(time::Date, time::Time), Self::Error> {
588 let date = Date {
589 year: self.year,
590 month: self.month,
591 day: self.day,
592 }
593 .try_convert()?;
594 let time = Time {
595 hour: self.hour,
596 minute: self.minute,
597 second: self.second,
598 };
599 let nanosecond = self.fraction as u32;
600 let time = (time, nanosecond).try_convert()?;
601 Ok((date, time))
602 }
603}
604
605impl TryConvert<time::PrimitiveDateTime> for Timestamp {
606 type Error = time::Error;
607
608 fn try_convert(self) -> Result<time::PrimitiveDateTime, Self::Error> {
609 let (date, time) = self.try_convert()?;
610 Ok(time::PrimitiveDateTime::new(date, time))
611 }
612}