Skip to main content

dinoco_engine/databases/sqlite/
row.rs

1use std::str;
2
3use chrono::{DateTime, NaiveDate, NaiveDateTime, Utc};
4use rusqlite::Row as RusqliteRow;
5use rusqlite::types::ValueRef;
6
7use crate::{DinocoError, DinocoGenericRow, DinocoResult, DinocoValue};
8
9impl<'stmt> DinocoGenericRow for RusqliteRow<'stmt> {
10    fn get_value(&self, idx: usize) -> DinocoResult<DinocoValue> {
11        let value_ref = self.get_ref(idx).map_err(|error| match error {
12            rusqlite::Error::InvalidColumnIndex(invalid_index) => {
13                DinocoError::ParseError(format!("Column index {} not found in sqlite row", invalid_index))
14            }
15            other => DinocoError::from(other),
16        })?;
17
18        match value_ref {
19            ValueRef::Null => Ok(DinocoValue::Null),
20            ValueRef::Integer(i) => Ok(DinocoValue::Integer(i)),
21            ValueRef::Real(f) => Ok(DinocoValue::Float(f)),
22            ValueRef::Text(t) => {
23                let text_str = str::from_utf8(t).unwrap_or_default().to_string();
24
25                if let Ok(date) = NaiveDate::parse_from_str(&text_str, "%Y-%m-%d") {
26                    return Ok(DinocoValue::Date(date));
27                }
28
29                if let Ok(datetime) = DateTime::parse_from_rfc3339(&text_str) {
30                    return Ok(DinocoValue::DateTime(datetime.with_timezone(&Utc)));
31                }
32
33                if let Some(value) = text_str.strip_suffix(" UTC") {
34                    if let Ok(datetime) = NaiveDateTime::parse_from_str(value, "%Y-%m-%d %H:%M:%S%.f") {
35                        return Ok(DinocoValue::DateTime(DateTime::<Utc>::from_naive_utc_and_offset(datetime, Utc)));
36                    }
37
38                    if let Ok(datetime) = NaiveDateTime::parse_from_str(value, "%Y-%m-%d %H:%M:%S") {
39                        return Ok(DinocoValue::DateTime(DateTime::<Utc>::from_naive_utc_and_offset(datetime, Utc)));
40                    }
41                }
42
43                if let Ok(datetime) = NaiveDateTime::parse_from_str(&text_str, "%Y-%m-%d %H:%M:%S%.f") {
44                    return Ok(DinocoValue::DateTime(DateTime::<Utc>::from_naive_utc_and_offset(datetime, Utc)));
45                }
46
47                if let Ok(datetime) = NaiveDateTime::parse_from_str(&text_str, "%Y-%m-%d %H:%M:%S") {
48                    return Ok(DinocoValue::DateTime(DateTime::<Utc>::from_naive_utc_and_offset(datetime, Utc)));
49                }
50
51                Ok(DinocoValue::String(text_str))
52            }
53            ValueRef::Blob(b) => Ok(DinocoValue::Bytes(b.to_vec())),
54        }
55    }
56}