mirror of
https://github.com/isar/rusqlite.git
synced 2025-04-19 07:47:44 +08:00
Merge pull request #1551 from gwenn/jiff
Add support to jiff Date / DateTime / Time
This commit is contained in:
commit
90320c9d37
2
.github/workflows/main.yml
vendored
2
.github/workflows/main.yml
vendored
@ -21,7 +21,7 @@ permissions:
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.head_ref }}
|
||||
group: ${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
|
19
Cargo.toml
19
Cargo.toml
@ -47,7 +47,10 @@ trace = []
|
||||
release_memory = []
|
||||
bundled = ["libsqlite3-sys/bundled", "modern_sqlite"]
|
||||
bundled-sqlcipher = ["libsqlite3-sys/bundled-sqlcipher", "bundled"]
|
||||
bundled-sqlcipher-vendored-openssl = ["libsqlite3-sys/bundled-sqlcipher-vendored-openssl", "bundled-sqlcipher"]
|
||||
bundled-sqlcipher-vendored-openssl = [
|
||||
"libsqlite3-sys/bundled-sqlcipher-vendored-openssl",
|
||||
"bundled-sqlcipher",
|
||||
]
|
||||
buildtime_bindgen = ["libsqlite3-sys/buildtime_bindgen"]
|
||||
limits = []
|
||||
loadable_extension = ["libsqlite3-sys/loadable_extension"]
|
||||
@ -97,6 +100,7 @@ modern-full = [
|
||||
"functions",
|
||||
"hooks",
|
||||
"i128_blob",
|
||||
"jiff",
|
||||
"limits",
|
||||
"load_extension",
|
||||
"serde_json",
|
||||
@ -113,10 +117,19 @@ modern-full = [
|
||||
bundled-full = ["modern-full", "bundled"]
|
||||
|
||||
[dependencies]
|
||||
time = { version = "0.3.36", features = ["formatting", "macros", "parsing"], optional = true }
|
||||
jiff = { version = "0.1", optional = true, default-features = false, features = [
|
||||
"std",
|
||||
] }
|
||||
time = { version = "0.3.36", features = [
|
||||
"formatting",
|
||||
"macros",
|
||||
"parsing",
|
||||
], optional = true }
|
||||
bitflags = "2.6.0"
|
||||
hashlink = "0.9"
|
||||
chrono = { version = "0.4.38", optional = true, default-features = false, features = ["clock"] }
|
||||
chrono = { version = "0.4.38", optional = true, default-features = false, features = [
|
||||
"clock",
|
||||
] }
|
||||
serde_json = { version = "1.0", optional = true }
|
||||
csv = { version = "1.1", optional = true }
|
||||
url = { version = "2.1", optional = true }
|
||||
|
137
src/types/jiff.rs
Normal file
137
src/types/jiff.rs
Normal file
@ -0,0 +1,137 @@
|
||||
//! Convert some `jiff` types.
|
||||
|
||||
use jiff::civil::{Date, DateTime, Time};
|
||||
use std::str::FromStr;
|
||||
|
||||
use crate::types::{FromSql, FromSqlError, FromSqlResult, ToSql, ToSqlOutput, ValueRef};
|
||||
use crate::Result;
|
||||
|
||||
/// Gregorian calendar date => "YYYY-MM-DD"
|
||||
impl ToSql for Date {
|
||||
#[inline]
|
||||
fn to_sql(&self) -> Result<ToSqlOutput<'_>> {
|
||||
let s = self.to_string();
|
||||
Ok(ToSqlOutput::from(s))
|
||||
}
|
||||
}
|
||||
|
||||
/// "YYYY-MM-DD" => Gregorian calendar date.
|
||||
impl FromSql for Date {
|
||||
#[inline]
|
||||
fn column_result(value: ValueRef<'_>) -> FromSqlResult<Self> {
|
||||
value.as_str().and_then(|s| match Date::from_str(s) {
|
||||
Ok(d) => Ok(d),
|
||||
Err(err) => Err(FromSqlError::Other(Box::new(err))),
|
||||
})
|
||||
}
|
||||
}
|
||||
/// time => "HH:MM:SS.SSS"
|
||||
impl ToSql for Time {
|
||||
#[inline]
|
||||
fn to_sql(&self) -> Result<ToSqlOutput<'_>> {
|
||||
let date_str = self.to_string();
|
||||
Ok(ToSqlOutput::from(date_str))
|
||||
}
|
||||
}
|
||||
|
||||
/// "HH:MM:SS.SSS" => time.
|
||||
impl FromSql for Time {
|
||||
fn column_result(value: ValueRef<'_>) -> FromSqlResult<Self> {
|
||||
value.as_str().and_then(|s| match Time::from_str(s) {
|
||||
Ok(t) => Ok(t),
|
||||
Err(err) => Err(FromSqlError::Other(Box::new(err))),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// Gregorian datetime => "YYYY-MM-DDTHH:MM:SS.SSS"
|
||||
impl ToSql for DateTime {
|
||||
#[inline]
|
||||
fn to_sql(&self) -> Result<ToSqlOutput<'_>> {
|
||||
let s = self.to_string();
|
||||
Ok(ToSqlOutput::from(s))
|
||||
}
|
||||
}
|
||||
|
||||
/// "YYYY-MM-DDTHH:MM:SS.SSS" => Gregorian datetime.
|
||||
impl FromSql for DateTime {
|
||||
fn column_result(value: ValueRef<'_>) -> FromSqlResult<Self> {
|
||||
value.as_str().and_then(|s| match DateTime::from_str(s) {
|
||||
Ok(dt) => Ok(dt),
|
||||
Err(err) => Err(FromSqlError::Other(Box::new(err))),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use crate::{Connection, Result};
|
||||
use jiff::civil::{Date, DateTime, Time};
|
||||
|
||||
fn checked_memory_handle() -> Result<Connection> {
|
||||
let db = Connection::open_in_memory()?;
|
||||
db.execute_batch("CREATE TABLE foo (t TEXT, b BLOB)")?;
|
||||
Ok(db)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_date() -> Result<()> {
|
||||
let db = checked_memory_handle()?;
|
||||
let date = Date::constant(2016, 2, 23);
|
||||
db.execute("INSERT INTO foo (t) VALUES (?1)", [date])?;
|
||||
|
||||
let s: String = db.one_column("SELECT t FROM foo")?;
|
||||
assert_eq!("2016-02-23", s);
|
||||
let t: Date = db.one_column("SELECT t FROM foo")?;
|
||||
assert_eq!(date, t);
|
||||
|
||||
db.execute("UPDATE foo set b = date(t)", [])?;
|
||||
let t: Date = db.one_column("SELECT b FROM foo")?;
|
||||
assert_eq!(date, t);
|
||||
|
||||
let r: Result<Date> = db.one_column("SELECT '2023-02-29'");
|
||||
assert!(r.is_err());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_time() -> Result<()> {
|
||||
let db = checked_memory_handle()?;
|
||||
let time = Time::constant(23, 56, 4, 0);
|
||||
db.execute("INSERT INTO foo (t) VALUES (?1)", [time])?;
|
||||
|
||||
let s: String = db.one_column("SELECT t FROM foo")?;
|
||||
assert_eq!("23:56:04", s);
|
||||
let v: Time = db.one_column("SELECT t FROM foo")?;
|
||||
assert_eq!(time, v);
|
||||
|
||||
db.execute("UPDATE foo set b = time(t)", [])?;
|
||||
let v: Time = db.one_column("SELECT b FROM foo")?;
|
||||
assert_eq!(time, v);
|
||||
|
||||
let r: Result<Time> = db.one_column("SELECT '25:22:45'");
|
||||
assert!(r.is_err());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_date_time() -> Result<()> {
|
||||
let db = checked_memory_handle()?;
|
||||
let dt = DateTime::constant(2016, 2, 23, 23, 56, 4, 0);
|
||||
|
||||
db.execute("INSERT INTO foo (t) VALUES (?1)", [dt])?;
|
||||
|
||||
let s: String = db.one_column("SELECT t FROM foo")?;
|
||||
assert_eq!("2016-02-23T23:56:04", s);
|
||||
let v: DateTime = db.one_column("SELECT t FROM foo")?;
|
||||
assert_eq!(dt, v);
|
||||
|
||||
db.execute("UPDATE foo set b = datetime(t)", [])?;
|
||||
let v: DateTime = db.one_column("SELECT b FROM foo")?;
|
||||
assert_eq!(dt, v);
|
||||
|
||||
let r: Result<DateTime> = db.one_column("SELECT '2023-02-29T00:00:00'");
|
||||
assert!(r.is_err());
|
||||
Ok(())
|
||||
}
|
||||
}
|
@ -81,6 +81,9 @@ use std::fmt;
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "chrono")))]
|
||||
mod chrono;
|
||||
mod from_sql;
|
||||
#[cfg(feature = "jiff")]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "jiff")))]
|
||||
mod jiff;
|
||||
#[cfg(feature = "serde_json")]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "serde_json")))]
|
||||
mod serde_json;
|
||||
|
Loading…
x
Reference in New Issue
Block a user