|
1 |
| -//! Traits dealing with DuckDB data types. |
2 |
| -//! |
3 |
| -//! DuckDB uses a [dynamic type system](https://www.sqlite.org/datatype3.html). Implementations of |
4 |
| -//! the [`ToSql`] and [`FromSql`] traits are provided for the basic types that |
5 |
| -//! DuckDB provides methods for: |
6 |
| -//! |
7 |
| -//! * Strings (`String` and `&str`) |
8 |
| -//! * Blobs (`Vec<u8>` and `&[u8]`) |
9 |
| -//! * Numbers |
10 |
| -//! |
11 |
| -//! The number situation is a little complicated due to the fact that all |
12 |
| -//! numbers in DuckDB are stored as `INTEGER` (`i64`) or `REAL` (`f64`). |
13 |
| -//! |
14 |
| -//! [`ToSql`] and [`FromSql`] are implemented for all primitive number types. |
15 |
| -//! [`FromSql`] has different behaviour depending on the SQL and Rust types, and |
16 |
| -//! the value. |
17 |
| -//! |
18 |
| -//! * `INTEGER` to integer: returns an |
19 |
| -//! [`Error::IntegralValueOutOfRange`](crate::Error::IntegralValueOutOfRange) |
20 |
| -//! error if the value does not fit in the Rust type. |
21 |
| -//! * `REAL` to integer: always returns an |
22 |
| -//! [`Error::InvalidColumnType`](crate::Error::InvalidColumnType) error. |
23 |
| -//! * `INTEGER` to float: casts using `as` operator. Never fails. |
24 |
| -//! * `REAL` to float: casts using `as` operator. Never fails. |
25 |
| -//! |
26 |
| -//! [`ToSql`] always succeeds except when storing a `u64` or `usize` value that |
27 |
| -//! cannot fit in an `INTEGER` (`i64`). Also note that DuckDB ignores column |
28 |
| -//! types, so if you store an `i64` in a column with type `REAL` it will be |
29 |
| -//! stored as an `INTEGER`, not a `REAL`. |
30 |
| -//! |
31 |
| -//! If the `time` feature is enabled, implementations are |
32 |
| -//! provided for `time::OffsetDateTime` that use the RFC 3339 date/time format, |
33 |
| -//! `"%Y-%m-%dT%H:%M:%S.%fZ"`, to store time values as strings. These values |
34 |
| -//! can be parsed by SQLite's builtin |
35 |
| -//! [datetime](https://www.sqlite.org/lang_datefunc.html) functions. If you |
36 |
| -//! want different storage for datetimes, you can use a newtype. |
37 |
| -#![cfg_attr( |
38 |
| - feature = "time", |
39 |
| - doc = r##" |
40 |
| -For example, to store datetimes as `i64`s counting the number of seconds since |
41 |
| -the Unix epoch: |
42 |
| -
|
43 |
| -``` |
44 |
| -use duckdb::types::{FromSql, FromSqlResult, ToSql, ToSqlOutput, ValueRef}; |
45 |
| -use duckdb::Result; |
46 |
| -
|
47 |
| -pub struct DateTimeSql(pub time::OffsetDateTime); |
48 |
| -
|
49 |
| -impl FromSql for DateTimeSql { |
50 |
| - fn column_result(value: ValueRef) -> FromSqlResult<Self> { |
51 |
| - i64::column_result(value).map(|as_i64| { |
52 |
| - DateTimeSql(time::OffsetDateTime::from_unix_timestamp(as_i64)) |
53 |
| - }) |
54 |
| - } |
55 |
| -} |
56 |
| -
|
57 |
| -impl ToSql for DateTimeSql { |
58 |
| - fn to_sql(&self) -> Result<ToSqlOutput> { |
59 |
| - Ok(self.0.timestamp().into()) |
60 |
| - } |
61 |
| -} |
62 |
| -``` |
63 |
| -
|
64 |
| -"## |
65 |
| -)] |
66 | 1 | //! [`ToSql`] and [`FromSql`] are also implemented for `Option<T>` where `T`
|
67 | 2 | //! implements [`ToSql`] or [`FromSql`] for the cases where you want to know if
|
68 | 3 | //! a value was NULL (which gets translated to `None`).
|
@@ -395,10 +330,6 @@ mod test {
|
395 | 330 | assert!(is_invalid_column_type(row.get::<_, i64>(0).err().unwrap()));
|
396 | 331 | assert!(is_invalid_column_type(row.get::<_, c_double>(0).err().unwrap()));
|
397 | 332 | assert!(is_invalid_column_type(row.get::<_, String>(0).err().unwrap()));
|
398 |
| - #[cfg(feature = "time")] |
399 |
| - assert!(is_invalid_column_type( |
400 |
| - row.get::<_, time::OffsetDateTime>(0).err().unwrap() |
401 |
| - )); |
402 | 333 | assert!(is_invalid_column_type(row.get::<_, Option<c_int>>(0).err().unwrap()));
|
403 | 334 |
|
404 | 335 | // 1 is actually a text (String)
|
@@ -426,10 +357,6 @@ mod test {
|
426 | 357 | assert!(is_invalid_column_type(row.get::<_, c_double>(4).err().unwrap()));
|
427 | 358 | assert!(is_invalid_column_type(row.get::<_, String>(4).err().unwrap()));
|
428 | 359 | assert!(is_invalid_column_type(row.get::<_, Vec<u8>>(4).err().unwrap()));
|
429 |
| - #[cfg(feature = "time")] |
430 |
| - assert!(is_invalid_column_type( |
431 |
| - row.get::<_, time::OffsetDateTime>(4).err().unwrap() |
432 |
| - )); |
433 | 360 | Ok(())
|
434 | 361 | }
|
435 | 362 |
|
|
0 commit comments