Update time to 0.3.2 (#1455)

Co-authored-by: Tyler Hill <tyhi@tyhi.rs>
This commit is contained in:
Paolo Barbolini 2022-04-15 00:11:46 +02:00 committed by GitHub
parent 08296a28a0
commit ba123e62fa
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 82 additions and 237 deletions

151
Cargo.lock generated
View file

@ -248,12 +248,6 @@ version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
[[package]]
name = "base-x"
version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4521f3e3d031370679b3b140beb36dfe4801b09ac77e30c61941f97df3ef28b"
[[package]]
name = "base64"
version = "0.13.0"
@ -354,7 +348,7 @@ version = "0.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4c24dab4283a142afa2fdca129b80ad2c6284e073930f964c3a1293c225ee39a"
dependencies = [
"rustc_version 0.4.0",
"rustc_version",
]
[[package]]
@ -466,12 +460,6 @@ version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e4c78c047431fee22c1a7bb92e00ad095a02a983affe4d8a72e2a2c62c1b94f3"
[[package]]
name = "const_fn"
version = "0.4.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f92cfa0fd5690b3cf8c1ef2cabbd9b7ef22fa53cf5e1f92b05103f6d5d1cf6e7"
[[package]]
name = "core-foundation"
version = "0.9.2"
@ -723,12 +711,6 @@ dependencies = [
"winapi",
]
[[package]]
name = "discard"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "212d0f5754cb6769937f4501cc0e67f4f4483c8d2c3e1e922ee9edbe4ab4c7c0"
[[package]]
name = "dotenv"
version = "0.15.0"
@ -1837,12 +1819,6 @@ dependencies = [
"version_check",
]
[[package]]
name = "proc-macro-hack"
version = "0.5.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5"
[[package]]
name = "proc-macro2"
version = "1.0.36"
@ -2060,22 +2036,13 @@ dependencies = [
"serde",
]
[[package]]
name = "rustc_version"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
dependencies = [
"semver 0.9.0",
]
[[package]]
name = "rustc_version"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366"
dependencies = [
"semver 1.0.4",
"semver",
]
[[package]]
@ -2182,27 +2149,12 @@ dependencies = [
"libc",
]
[[package]]
name = "semver"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
dependencies = [
"semver-parser",
]
[[package]]
name = "semver"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "568a8e6258aa33c13358f81fd834adb854c6f7c9468520910a9b1e8fac068012"
[[package]]
name = "semver-parser"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
[[package]]
name = "serde"
version = "1.0.132"
@ -2255,12 +2207,6 @@ dependencies = [
"digest",
]
[[package]]
name = "sha1"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2579985fda508104f7587689507983eadd6a6e84dd35d6d115361f530916fa0d"
[[package]]
name = "sha2"
version = "0.10.2"
@ -2368,7 +2314,7 @@ dependencies = [
"sqlx-macros",
"sqlx-rt",
"sqlx-test",
"time 0.2.27",
"time 0.3.5",
"tokio",
"trybuild",
"url",
@ -2469,7 +2415,7 @@ dependencies = [
"sqlx-rt",
"stringprep",
"thiserror",
"time 0.2.27",
"time 0.3.5",
"tokio",
"tokio-stream",
"url",
@ -2595,64 +2541,6 @@ dependencies = [
"tokio",
]
[[package]]
name = "standback"
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e113fb6f3de07a243d434a56ec6f186dfd51cb08448239fe7bcae73f87ff28ff"
dependencies = [
"version_check",
]
[[package]]
name = "stdweb"
version = "0.4.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d022496b16281348b52d0e30ae99e01a73d737b2f45d38fed4edf79f9325a1d5"
dependencies = [
"discard",
"rustc_version 0.2.3",
"stdweb-derive",
"stdweb-internal-macros",
"stdweb-internal-runtime",
"wasm-bindgen",
]
[[package]]
name = "stdweb-derive"
version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c87a60a40fccc84bef0652345bbbbbe20a605bf5d0ce81719fc476f5c03b50ef"
dependencies = [
"proc-macro2",
"quote",
"serde",
"serde_derive",
"syn",
]
[[package]]
name = "stdweb-internal-macros"
version = "0.2.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "58fa5ff6ad0d98d1ffa8cb115892b6e69d67799f6763e162a1c9db421dc22e11"
dependencies = [
"base-x",
"proc-macro2",
"quote",
"serde",
"serde_derive",
"serde_json",
"sha1",
"syn",
]
[[package]]
name = "stdweb-internal-runtime"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "213701ba3370744dcd1a12960caa4843b3d68b4d1c0a5d575e0d65b2ee9d16c0"
[[package]]
name = "stringprep"
version = "0.1.2"
@ -2803,41 +2691,20 @@ dependencies = [
[[package]]
name = "time"
version = "0.2.27"
version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4752a97f8eebd6854ff91f1c1824cd6160626ac4bd44287f7f4ea2035a02a242"
checksum = "41effe7cfa8af36f439fac33861b66b049edc6f9a32331e2312660529c1c24ad"
dependencies = [
"const_fn",
"itoa 0.4.8",
"libc",
"standback",
"stdweb",
"time-macros",
"version_check",
"winapi",
]
[[package]]
name = "time-macros"
version = "0.1.1"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "957e9c6e26f12cb6d0dd7fc776bb67a706312e7299aed74c8dd5b17ebb27e2f1"
dependencies = [
"proc-macro-hack",
"time-macros-impl",
]
[[package]]
name = "time-macros-impl"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fd3c141a1b43194f3f56a1411225df8646c55781d5f26db825b3d98507eb482f"
dependencies = [
"proc-macro-hack",
"proc-macro2",
"quote",
"standback",
"syn",
]
checksum = "25eb0ca3468fc0acc11828786797f6ef9aa1555e4a211a60d64cc8e4d1be47d6"
[[package]]
name = "tinytemplate"

View file

@ -137,7 +137,7 @@ sqlx-macros = { version = "0.5.12", path = "sqlx-macros", default-features = fal
[dev-dependencies]
anyhow = "1.0.52"
time_ = { version = "0.2.27", package = "time" }
time_ = { version = "0.3.2", package = "time" }
futures = "0.3.19"
env_logger = "0.8.4"
async-std = { version = "1.10.0", features = ["attributes"] }

View file

@ -155,7 +155,7 @@ sha-1 = { version = "0.10.0", default-features = false, optional = true }
sha2 = { version = "0.10.0", default-features = false, optional = true }
sqlformat = "0.1.8"
thiserror = "1.0.30"
time = { version = "0.2.27", optional = true }
time = { version = "0.3.2", features = ["macros", "formatting", "parsing"], optional = true }
tokio-stream = { version = "0.1.8", features = ["fs"], optional = true }
smallvec = "1.7.0"
url = { version = "2.2.2", default-features = false }

View file

@ -1,8 +1,8 @@
use std::borrow::Cow;
use std::convert::TryFrom;
use byteorder::{ByteOrder, LittleEndian};
use bytes::Buf;
use time::macros::format_description;
use time::{Date, OffsetDateTime, PrimitiveDateTime, Time, UtcOffset};
use crate::decode::Decode;
@ -87,7 +87,7 @@ impl<'r> Decode<'r, MySql> for Time {
// are 0 then the length is 0 and no further data is send
// https://dev.mysql.com/doc/internals/en/binary-protocol-value.html
if len == 0 {
return Ok(Time::try_from_hms_micro(0, 0, 0, 0).unwrap());
return Ok(Time::MIDNIGHT);
}
// is negative : int<1>
@ -101,21 +101,11 @@ impl<'r> Decode<'r, MySql> for Time {
decode_time(len - 5, buf)
}
MySqlValueFormat::Text => {
let s = value.as_str()?;
// If there are less than 9 digits after the decimal point
// We need to zero-pad
// TODO: Ask [time] to add a parse % for less-than-fixed-9 nanos
let s = if s.len() < 20 {
Cow::Owned(format!("{:0<19}", s))
} else {
Cow::Borrowed(s)
};
Time::parse(&*s, "%H:%M:%S.%N").map_err(Into::into)
}
MySqlValueFormat::Text => Time::parse(
value.as_str()?,
&format_description!("[hour]:[minute]:[second].[subsecond]"),
)
.map_err(Into::into),
}
}
}
@ -148,7 +138,7 @@ impl<'r> Decode<'r, MySql> for Date {
}
MySqlValueFormat::Text => {
let s = value.as_str()?;
Date::parse(s, "%Y-%m-%d").map_err(Into::into)
Date::parse(s, &format_description!("[year]-[month]-[day]")).map_err(Into::into)
}
}
}
@ -211,21 +201,22 @@ impl<'r> Decode<'r, MySql> for PrimitiveDateTime {
MySqlValueFormat::Text => {
let s = value.as_str()?;
// If there are less than 9 digits after the decimal point
// We need to zero-pad
// TODO: Ask [time] to add a parse % for less-than-fixed-9 nanos
let s = if s.len() < 31 {
if s.contains('.') {
Cow::Owned(format!("{:0<30}", s))
} else {
Cow::Owned(format!("{}.000000000", s))
}
// If there are no nanoseconds parse without them
if s.contains('.') {
PrimitiveDateTime::parse(
s,
&format_description!(
"[year]-[month]-[day] [hour]:[minute]:[second].[subsecond]"
),
)
.map_err(Into::into)
} else {
Cow::Borrowed(s)
};
PrimitiveDateTime::parse(&*s, "%Y-%m-%d %H:%M:%S.%N").map_err(Into::into)
PrimitiveDateTime::parse(
s,
&format_description!("[year]-[month]-[day] [hour]:[minute]:[second]"),
)
.map_err(Into::into)
}
}
}
}
@ -237,7 +228,7 @@ fn encode_date(date: &Date, buf: &mut Vec<u8>) {
.unwrap_or_else(|_| panic!("Date out of range for Mysql: {}", date));
buf.extend_from_slice(&year.to_le_bytes());
buf.push(date.month());
buf.push(date.month().into());
buf.push(date.day());
}
@ -247,9 +238,9 @@ fn decode_date(buf: &[u8]) -> Result<Option<Date>, BoxDynError> {
return Ok(None);
}
Date::try_from_ymd(
Date::from_calendar_date(
LittleEndian::read_u16(buf) as i32,
buf[2] as u8,
time::Month::try_from(buf[2] as u8)?,
buf[3] as u8,
)
.map_err(Into::into)
@ -278,6 +269,6 @@ fn decode_time(len: u8, mut buf: &[u8]) -> Result<Time, BoxDynError> {
0
};
Time::try_from_hms_micro(hour, minute, seconds, micros as u32)
Time::from_hms_micro(hour, minute, seconds, micros as u32)
.map_err(|e| format!("Time out of range for MySQL: {}", e).into())
}

View file

@ -7,6 +7,7 @@ use crate::postgres::{
};
use crate::types::Type;
use std::mem;
use time::macros::format_description;
use time::{Date, Duration};
impl Type<Postgres> for Date {
@ -42,7 +43,10 @@ impl<'r> Decode<'r, Postgres> for Date {
PG_EPOCH + Duration::days(days.into())
}
PgValueFormat::Text => Date::parse(value.as_str()?, "%Y-%m-%d")?,
PgValueFormat::Text => Date::parse(
value.as_str()?,
&format_description!("[year]-[month]-[day]"),
)?,
})
}
}

View file

@ -8,7 +8,9 @@ use crate::postgres::{
use crate::types::Type;
use std::borrow::Cow;
use std::mem;
use time::{offset, Duration, OffsetDateTime, PrimitiveDateTime};
use time::macros::format_description;
use time::macros::offset;
use time::{Duration, OffsetDateTime, PrimitiveDateTime};
impl Type<Postgres> for PrimitiveDateTime {
fn type_info() -> PgTypeInfo {
@ -56,35 +58,28 @@ impl<'r> Decode<'r, Postgres> for PrimitiveDateTime {
}
PgValueFormat::Text => {
// If there are less than 9 digits after the decimal point
// We need to zero-pad
// TODO: De-duplicate with MySQL
// TODO: Ask [time] to add a parse % for less-than-fixed-9 nanos
let s = value.as_str()?;
let s = if let Some(plus) = s.rfind('+') {
let mut big = String::from(&s[..plus]);
while big.len() < 31 {
big.push('0');
}
big.push_str(&s[plus..]);
Cow::Owned(big)
} else if s.len() < 31 {
if s.contains('.') {
Cow::Owned(format!("{:0<30}", s))
} else {
Cow::Owned(format!("{}.000000000", s))
}
} else {
// If there is no decimal point we need to add one.
let s = if s.contains('.') {
Cow::Borrowed(s)
} else {
Cow::Owned(format!("{}.0", s))
};
PrimitiveDateTime::parse(&*s, "%Y-%m-%d %H:%M:%S.%N")?
// Contains a time-zone specifier
// This is given for timestamptz for some reason
// Postgres already guarantees this to always be UTC
if s.contains('+') {
PrimitiveDateTime::parse(&*s, &format_description!("[year]-[month]-[day] [hour]:[minute]:[second].[subsecond][offset_hour]"))?
} else {
PrimitiveDateTime::parse(
&*s,
&format_description!(
"[year]-[month]-[day] [hour]:[minute]:[second].[subsecond]"
),
)?
}
}
})
}

View file

@ -3,4 +3,4 @@ mod datetime;
mod time;
#[rustfmt::skip]
const PG_EPOCH: ::time::Date = ::time::date!(2000-1-1);
const PG_EPOCH: ::time::Date = ::time::macros::date!(2000-1-1);

View file

@ -5,8 +5,8 @@ use crate::postgres::{
PgArgumentBuffer, PgHasArrayType, PgTypeInfo, PgValueFormat, PgValueRef, Postgres,
};
use crate::types::Type;
use std::borrow::Cow;
use std::mem;
use time::macros::format_description;
use time::{Duration, Time};
impl Type<Postgres> for Time {
@ -24,7 +24,7 @@ impl PgHasArrayType for Time {
impl Encode<'_, Postgres> for Time {
fn encode_by_ref(&self, buf: &mut PgArgumentBuffer) -> IsNull {
// TIME is encoded as the microseconds since midnight
let us = (*self - Time::midnight()).whole_microseconds() as i64;
let us = (*self - Time::MIDNIGHT).whole_microseconds() as i64;
Encode::<Postgres>::encode(&us, buf)
}
@ -39,25 +39,13 @@ impl<'r> Decode<'r, Postgres> for Time {
PgValueFormat::Binary => {
// TIME is encoded as the microseconds since midnight
let us = Decode::<Postgres>::decode(value)?;
Time::midnight() + Duration::microseconds(us)
Time::MIDNIGHT + Duration::microseconds(us)
}
PgValueFormat::Text => {
// If there are less than 9 digits after the decimal point
// We need to zero-pad
// FIXME: Ask [time] to add a parse % for less-than-fixed-9 nanos
let s = value.as_str()?;
let s = if s.len() < 20 {
Cow::Owned(format!("{:0<19}", s))
} else {
Cow::Borrowed(s)
};
Time::parse(&*s, "%H:%M:%S.%N")?
}
PgValueFormat::Text => Time::parse(
value.as_str()?,
&format_description!("[hour]:[minute]:[second].[subsecond]"),
)?,
})
}
}

View file

@ -143,7 +143,7 @@ mod time {
impl Encode<'_, Postgres> for PgTimeTz<Time, UtcOffset> {
fn encode_by_ref(&self, buf: &mut PgArgumentBuffer) -> IsNull {
let _ = <Time as Encode<'_, Postgres>>::encode(self.time, buf);
let _ = <i32 as Encode<'_, Postgres>>::encode(-self.offset.as_seconds(), buf);
let _ = <i32 as Encode<'_, Postgres>>::encode(-self.offset.whole_seconds(), buf);
IsNull::No
}
@ -161,14 +161,14 @@ mod time {
// TIME is encoded as the microseconds since midnight
let us = buf.read_i64::<BigEndian>()?;
let time = Time::midnight() + Duration::microseconds(us);
let time = Time::MIDNIGHT + Duration::microseconds(us);
// OFFSET is encoded as seconds from UTC
let seconds = buf.read_i32::<BigEndian>()?;
Ok(PgTimeTz {
time,
offset: UtcOffset::west_seconds(seconds as u32),
offset: -UtcOffset::from_whole_seconds(seconds)?,
})
}

View file

@ -131,7 +131,7 @@ mod chrono {
mod time_tests {
use super::*;
use sqlx::types::time::{Date, OffsetDateTime, PrimitiveDateTime, Time};
use time::{date, time};
use time::macros::{date, time};
test_type!(time_date<Date>(
MySql,

View file

@ -279,7 +279,7 @@ mod chrono {
mod time_tests {
use super::*;
use sqlx::types::time::{Date, OffsetDateTime, PrimitiveDateTime, Time, UtcOffset};
use time::{date, time};
use time::macros::{date, time};
type PgTimeTz = sqlx::postgres::types::PgTimeTz<Time, UtcOffset>;
@ -297,8 +297,7 @@ mod time_tests {
test_type!(time_date_time<PrimitiveDateTime>(
Postgres,
"TIMESTAMP '2019-01-02 05:10:20'" == date!(2019 - 1 - 2).with_time(time!(5:10:20)),
"TIMESTAMP '2019-01-02 05:10:20.115100'"
== date!(2019 - 1 - 2).with_time(time!(5:10:20.115100))
"TIMESTAMP '2019-01-02 05:10:20.1151'" == date!(2019 - 1 - 2).with_time(time!(5:10:20.115100))
));
test_type!(time_timestamp<OffsetDateTime>(
@ -310,10 +309,11 @@ mod time_tests {
));
test_prepared_type!(time_time_tz<PgTimeTz>(Postgres,
"TIMETZ '05:10:20.115100+00'" == PgTimeTz { time: time!(5:10:20.115100), offset: UtcOffset::east_seconds(0) },
"TIMETZ '05:10:20.115100+06:30'" == PgTimeTz { time: time!(5:10:20.115100), offset: UtcOffset::east_seconds(60 * 60 * 6 + 1800) },
"TIMETZ '05:10:20.115100-05'" == PgTimeTz { time: time!(5:10:20.115100), offset: UtcOffset::west_seconds(60 * 60 * 5) },
"TIMETZ '05:10:20+02'" == PgTimeTz { time: time!(5:10:20), offset: UtcOffset::east_seconds(60 * 60 * 2 )}
"TIMETZ '05:10:20.115100+00'" == PgTimeTz { time: time!(5:10:20.115100), offset: UtcOffset::from_whole_seconds(0).unwrap() },
"TIMETZ '05:10:20.115100+00'" == PgTimeTz { time: time!(5:10:20.115100), offset: UtcOffset::from_whole_seconds(0).unwrap() },
"TIMETZ '05:10:20.115100+06:30'" == PgTimeTz { time: time!(5:10:20.115100), offset: UtcOffset::from_whole_seconds(60 * 60 * 6 + 1800).unwrap() },
"TIMETZ '05:10:20.115100-05'" == PgTimeTz { time: time!(5:10:20.115100), offset: UtcOffset::from_whole_seconds(-(60 * 60 * 5)).unwrap() },
"TIMETZ '05:10:20+02'" == PgTimeTz { time: time!(5:10:20), offset: UtcOffset::from_whole_seconds(60 * 60 * 2 ).unwrap() }
));
}