Skip to content

Commit

Permalink
Chrono support (#188)
Browse files Browse the repository at this point in the history
  • Loading branch information
dean-shaff authored Jan 22, 2025
1 parent ee53080 commit c8c65ef
Show file tree
Hide file tree
Showing 7 changed files with 614 additions and 35 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ jobs:
- run: rustup show active-toolchain -v
- run: cargo build
- run: cargo build --no-default-features
- run: cargo build --features uuid,time
- run: cargo build --features uuid,time,chrono
- run: cargo build --all-features

rustfmt:
Expand Down
23 changes: 18 additions & 5 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ required-features = ["rustls-tls"]

[[example]]
name = "data_types_derive_simple"
required-features = ["time", "uuid"]
required-features = ["time", "uuid", "chrono"]

[[example]]
name = "data_types_variant"
Expand All @@ -69,17 +69,29 @@ watch = ["dep:sha-1", "dep:serde_json", "serde/derive"]
uuid = ["dep:uuid"]
time = ["dep:time"]
lz4 = ["dep:lz4_flex", "dep:cityhash-rs"]

chrono = ["dep:chrono"]
## TLS
native-tls = ["dep:hyper-tls"]
# ext: native-tls-alpn
# ext: native-tls-vendored

rustls-tls = ["rustls-tls-aws-lc", "rustls-tls-webpki-roots"]
rustls-tls-aws-lc = ["dep:rustls", "dep:hyper-rustls", "hyper-rustls?/aws-lc-rs"]
rustls-tls-aws-lc = [
"dep:rustls",
"dep:hyper-rustls",
"hyper-rustls?/aws-lc-rs",
]
rustls-tls-ring = ["dep:rustls", "dep:hyper-rustls", "hyper-rustls?/ring"]
rustls-tls-webpki-roots = ["dep:rustls", "dep:hyper-rustls", "hyper-rustls?/webpki-tokio"]
rustls-tls-native-roots = ["dep:rustls", "dep:hyper-rustls", "hyper-rustls?/native-tokio"]
rustls-tls-webpki-roots = [
"dep:rustls",
"dep:hyper-rustls",
"hyper-rustls?/webpki-tokio",
]
rustls-tls-native-roots = [
"dep:rustls",
"dep:hyper-rustls",
"hyper-rustls?/native-tokio",
]

[dependencies]
clickhouse-derive = { version = "0.2.0", path = "derive" }
Expand Down Expand Up @@ -110,6 +122,7 @@ lz4_flex = { version = "0.11.3", default-features = false, features = [
cityhash-rs = { version = "=1.0.1", optional = true } # exact version for safety
uuid = { version = "1", optional = true }
time = { version = "0.3", optional = true }
chrono = { version = "0.4", optional = true, features = ["serde"] }
bstr = { version = "1.11.0", default-features = false }
quanta = { version = "0.12", optional = true }
replace_with = { version = "0.1.7" }
Expand Down
40 changes: 36 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,7 @@ See [examples](https://github.com/ClickHouse/clickhouse-rs/tree/main/examples).
* `watch` — enables `client.watch` functionality. See the corresponding section for details.
* `uuid` — adds `serde::uuid` to work with [uuid](https://docs.rs/uuid) crate.
* `time` — adds `serde::time` to work with [time](https://docs.rs/time) crate.
* `chrono` — adds `serde::chrono` to work with [chrono](https://docs.rs/chrono) crate.

### TLS
By default, TLS is disabled and one or more following features must be enabled to use HTTPS urls:
Expand Down Expand Up @@ -328,7 +329,9 @@ How to choose between all these features? Here are some considerations:
}
```
</details>
* `Date` maps to/from `u16` or a newtype around it and represents a number of days elapsed since `1970-01-01`. Also, [`time::Date`](https://docs.rs/time/latest/time/struct.Date.html) is supported by using `serde::time::date`, that requires the `time` feature.
* `Date` maps to/from `u16` or a newtype around it and represents a number of days elapsed since `1970-01-01`. The following external types are supported:
* [`time::Date`](https://docs.rs/time/latest/time/struct.Date.html) is supported by using `serde::time::date`, requiring the `time` feature.
* [`chrono::NaiveDate`](https://docs.rs/chrono/latest/chrono/struct.NaiveDate.html) is supported by using `serde::chrono::date`, requiring the `chrono` feature.
<details>
<summary>Example</summary>
Expand All @@ -338,10 +341,16 @@ How to choose between all these features? Here are some considerations:
days: u16,
#[serde(with = "clickhouse::serde::time::date")]
date: Date,
// if you prefer using chrono:
#[serde(with = "clickhouse::serde::chrono::date")]
date_chrono: NaiveDate,
}
```
</details>
* `Date32` maps to/from `i32` or a newtype around it and represents a number of days elapsed since `1970-01-01`. Also, [`time::Date`](https://docs.rs/time/latest/time/struct.Date.html) is supported by using `serde::time::date32`, that requires the `time` feature.
* `Date32` maps to/from `i32` or a newtype around it and represents a number of days elapsed since `1970-01-01`. The following external types are supported:
* [`time::Date`](https://docs.rs/time/latest/time/struct.Date.html) is supported by using `serde::time::date32`, requiring the `time` feature.
* [`chrono::NaiveDate`](https://docs.rs/chrono/latest/chrono/struct.NaiveDate.html) is supported by using `serde::chrono::date32`, requiring the `chrono` feature.
<details>
<summary>Example</summary>
Expand All @@ -351,10 +360,17 @@ How to choose between all these features? Here are some considerations:
days: i32,
#[serde(with = "clickhouse::serde::time::date32")]
date: Date,
// if you prefer using chrono:
#[serde(with = "clickhouse::serde::chrono::date32")]
date_chrono: NaiveDate,
}
```
</details>
* `DateTime` maps to/from `u32` or a newtype around it and represents a number of seconds elapsed since UNIX epoch. Also, [`time::OffsetDateTime`](https://docs.rs/time/latest/time/struct.OffsetDateTime.html) is supported by using `serde::time::datetime`, that requires the `time` feature.
* `DateTime` maps to/from `u32` or a newtype around it and represents a number of seconds elapsed since UNIX epoch. The following external types are supported:
* [`time::OffsetDateTime`](https://docs.rs/time/latest/time/struct.OffsetDateTime.html) is supported by using `serde::time::datetime`, requiring the `time` feature.
* [`chrono::DateTime<Utc>`](https://docs.rs/chrono/latest/chrono/struct.DateTime.html) is supported by using `serde::chrono::datetime`, requiring the `chrono` feature.
<details>
<summary>Example</summary>
Expand All @@ -364,10 +380,15 @@ How to choose between all these features? Here are some considerations:
ts: u32,
#[serde(with = "clickhouse::serde::time::datetime")]
dt: OffsetDateTime,
// if you prefer using chrono:
#[serde(with = "clickhouse::serde::chrono::datetime")]
dt_chrono: DateTime<Utc>,
}
```
</details>
* `DateTime64(_)` maps to/from `i64` or a newtype around it and represents a time elapsed since UNIX epoch. Also, [`time::OffsetDateTime`](https://docs.rs/time/latest/time/struct.OffsetDateTime.html) is supported by using `serde::time::datetime64::*`, that requires the `time` feature.
* `DateTime64(_)` maps to/from `i64` or a newtype around it and represents a time elapsed since UNIX epoch. The following external types are supported:
* [`time::OffsetDateTime`](https://docs.rs/time/latest/time/struct.OffsetDateTime.html) is supported by using `serde::time::datetime64::*`, requiring the `time` feature.
* [`chrono::DateTime<Utc>`](https://docs.rs/chrono/latest/chrono/struct.DateTime.html) is supported by using `serde::chrono::datetime64::*`, requiring the `chrono` feature.
<details>
<summary>Example</summary>
Expand All @@ -383,7 +404,18 @@ How to choose between all these features? Here are some considerations:
dt64us: OffsetDateTime, // `DateTime64(6)`
#[serde(with = "clickhouse::serde::time::datetime64::nanos")]
dt64ns: OffsetDateTime, // `DateTime64(9)`
// if you prefer using chrono:
#[serde(with = "clickhouse::serde::chrono::datetime64::secs")]
dt64s_chrono: DateTime<Utc>, // `DateTime64(0)`
#[serde(with = "clickhouse::serde::chrono::datetime64::millis")]
dt64ms_chrono: DateTime<Utc>, // `DateTime64(3)`
#[serde(with = "clickhouse::serde::chrono::datetime64::micros")]
dt64us_chrono: DateTime<Utc>, // `DateTime64(6)`
#[serde(with = "clickhouse::serde::chrono::datetime64::nanos")]
dt64ns_chrono: DateTime<Utc>, // `DateTime64(9)`
}
```
</details>
* `Tuple(A, B, ...)` maps to/from `(A, B, ...)` or a newtype around it.
Expand Down
79 changes: 54 additions & 25 deletions examples/data_types_derive_simple.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
use std::str::FromStr;

use fixnum::typenum::{U12, U4, U8};
use fixnum::FixedPoint;
use rand::distributions::Alphanumeric;
use rand::seq::SliceRandom;
use rand::Rng;
use chrono::{DateTime, NaiveDate, Utc};
use fixnum::{
typenum::{U12, U4, U8},
FixedPoint,
};
use rand::{distributions::Alphanumeric, seq::SliceRandom, Rng};
use time::{Date, Month, OffsetDateTime, Time};

use clickhouse::sql::Identifier;
use clickhouse::{error::Result, Client};
use clickhouse::{error::Result, sql::Identifier, Client};

// This example covers derivation of _simpler_ ClickHouse data types.
// See also: https://clickhouse.com/docs/en/sql-reference/data-types
Expand Down Expand Up @@ -121,23 +121,42 @@ pub struct Row {
pub decimal64_18_8: Decimal64,
pub decimal128_38_12: Decimal128,
#[serde(with = "clickhouse::serde::time::date")]
pub date: Date,
pub time_date: Date,
#[serde(with = "clickhouse::serde::time::date32")]
pub date32: Date,
pub time_date32: Date,
#[serde(with = "clickhouse::serde::time::datetime")]
pub datetime: OffsetDateTime,
pub time_datetime: OffsetDateTime,
#[serde(with = "clickhouse::serde::time::datetime")]
pub datetime_tz: OffsetDateTime,
pub time_datetime_tz: OffsetDateTime,
#[serde(with = "clickhouse::serde::time::datetime64::secs")]
pub datetime64_0: OffsetDateTime,
pub time_datetime64_0: OffsetDateTime,
#[serde(with = "clickhouse::serde::time::datetime64::millis")]
pub datetime64_3: OffsetDateTime,
pub time_datetime64_3: OffsetDateTime,
#[serde(with = "clickhouse::serde::time::datetime64::micros")]
pub datetime64_6: OffsetDateTime,
pub time_datetime64_6: OffsetDateTime,
#[serde(with = "clickhouse::serde::time::datetime64::nanos")]
pub datetime64_9: OffsetDateTime,
pub time_datetime64_9: OffsetDateTime,
#[serde(with = "clickhouse::serde::time::datetime64::nanos")]
pub datetime64_9_tz: OffsetDateTime,
pub time_datetime64_9_tz: OffsetDateTime,

#[serde(with = "clickhouse::serde::chrono::date")]
pub chrono_date: NaiveDate,
#[serde(with = "clickhouse::serde::chrono::date32")]
pub chrono_date32: NaiveDate,
#[serde(with = "clickhouse::serde::chrono::datetime")]
pub chrono_datetime: DateTime<Utc>,
#[serde(with = "clickhouse::serde::chrono::datetime")]
pub chrono_datetime_tz: DateTime<Utc>,
#[serde(with = "clickhouse::serde::chrono::datetime64::secs")]
pub chrono_datetime64_0: DateTime<Utc>,
#[serde(with = "clickhouse::serde::chrono::datetime64::millis")]
pub chrono_datetime64_3: DateTime<Utc>,
#[serde(with = "clickhouse::serde::chrono::datetime64::micros")]
pub chrono_datetime64_6: DateTime<Utc>,
#[serde(with = "clickhouse::serde::chrono::datetime64::nanos")]
pub chrono_datetime64_9: DateTime<Utc>,
#[serde(with = "clickhouse::serde::chrono::datetime64::nanos")]
pub chrono_datetime64_9_tz: DateTime<Utc>,
}

// See ClickHouse decimal sizes: https://clickhouse.com/docs/en/sql-reference/data-types/decimal
Expand Down Expand Up @@ -206,15 +225,25 @@ impl Row {
// See
// - https://clickhouse.com/docs/en/sql-reference/data-types/date
// - https://clickhouse.com/docs/en/sql-reference/data-types/date32
date: Date::from_calendar_date(2149, Month::June, 6).unwrap(),
date32: Date::from_calendar_date(2299, Month::December, 31).unwrap(),
datetime: max_datetime(),
datetime_tz: max_datetime(),
datetime64_0: max_datetime64(),
datetime64_3: max_datetime64(),
datetime64_6: max_datetime64(),
datetime64_9: max_datetime64_nanos(),
datetime64_9_tz: max_datetime64_nanos(),
time_date: Date::from_calendar_date(2149, Month::June, 6).unwrap(),
time_date32: Date::from_calendar_date(2299, Month::December, 31).unwrap(),
time_datetime: max_datetime(),
time_datetime_tz: max_datetime(),
time_datetime64_0: max_datetime64(),
time_datetime64_3: max_datetime64(),
time_datetime64_6: max_datetime64(),
time_datetime64_9: max_datetime64_nanos(),
time_datetime64_9_tz: max_datetime64_nanos(),

chrono_date: NaiveDate::from_ymd_opt(2149, 6, 6).unwrap(),
chrono_date32: NaiveDate::from_ymd_opt(2299, 12, 31).unwrap(),
chrono_datetime: Utc::now(),
chrono_datetime_tz: Utc::now(),
chrono_datetime64_0: Utc::now(),
chrono_datetime64_3: Utc::now(),
chrono_datetime64_6: Utc::now(),
chrono_datetime64_9: Utc::now(),
chrono_datetime64_9_tz: Utc::now(),
}
}
}
Expand Down
Loading

0 comments on commit c8c65ef

Please sign in to comment.