Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Chrono support #188

Merged
merged 11 commits into from
Jan 22, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading