Skip to content

Commit

Permalink
Support (Pg)Interval with chrono::Duration
Browse files Browse the repository at this point in the history
  • Loading branch information
Rudi3 committed Jan 15, 2022
1 parent 5d6ef72 commit 3a21d56
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 0 deletions.
4 changes: 4 additions & 0 deletions src/backend/query_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -756,6 +756,8 @@ pub trait QueryBuilder: QuotedBuilder {
Value::Uuid(None) => write!(s, "NULL").unwrap(),
#[cfg(feature = "postgres-array")]
Value::Array(None) => write!(s, "NULL").unwrap(),
#[cfg(all(feature = "postgres-interval", feature = "with-chrono"))]
Value::Interval(None) => write!(s, "NULL").unwrap(),
Value::Bool(Some(b)) => write!(s, "{}", if *b { "TRUE" } else { "FALSE" }).unwrap(),
Value::TinyInt(Some(v)) => write!(s, "{}", v).unwrap(),
Value::SmallInt(Some(v)) => write!(s, "{}", v).unwrap(),
Expand Down Expand Up @@ -804,6 +806,8 @@ pub trait QueryBuilder: QuotedBuilder {
.join(",")
)
.unwrap(),
#[cfg(all(feature = "postgres-interval", feature = "with-chrono"))]
Value::Interval(Some(v)) => write!(s, "\'{}\'", v.to_string()).unwrap(),
};
s
}
Expand Down
2 changes: 2 additions & 0 deletions src/driver/postgres.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ impl ToSql for Value {
Value::Uuid(v) => box_to_sql!(v, uuid::Uuid),
#[cfg(feature = "postgres-array")]
Value::Array(v) => box_to_sql!(v, Vec<Value>),
#[cfg(all(feature = "postgres-interval", feature = "with-chrono"))]
Value::Interval(_) => unimplemented!("chrono::Duration Not supported by postgres-types"),
#[allow(unreachable_patterns)]
_ => unimplemented!(),
}
Expand Down
2 changes: 2 additions & 0 deletions src/driver/sqlx_postgres.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ macro_rules! bind_params_sqlx_postgres {
query.bind(value.as_ref_big_decimal())
} else if value.is_uuid() {
query.bind(value.as_ref_uuid())
} else if value.is_interval() {
query.bind(value.as_ref_interval())
} else if value.is_array() {
unimplemented!("SQLx array is not supported");
} else {
Expand Down
42 changes: 42 additions & 0 deletions src/value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ use uuid::Uuid;

use crate::ColumnType;

#[cfg(all(feature = "postgres-interval", feature = "with-chrono"))]
use chrono::Duration;

/// Value variants
///
/// We want Value to be exactly 1 pointer sized, so anything larger should be boxed.
Expand Down Expand Up @@ -76,6 +79,10 @@ pub enum Value {
#[cfg(feature = "postgres-array")]
#[cfg_attr(docsrs, doc(cfg(feature = "postgres-array")))]
Array(Option<Box<Vec<Value>>>),

#[cfg(all(feature = "postgres-interval", feature = "with-chrono"))]
#[cfg_attr(docsrs, doc(cfg(all(feature = "postgres-interval", feature = "with-chrono"))))]
Interval(Option<Box<Duration>>),
}

pub trait ValueType: Sized {
Expand Down Expand Up @@ -436,6 +443,15 @@ mod with_array {
}
}

#[cfg(all(feature = "postgres-interval", feature = "with-chrono"))]
#[cfg_attr(docsrs, doc(cfg(all(feature = "postgres-interval", feature = "with-chrono"))))]
mod with_interval {
use chrono::Duration;
use super::*;

type_to_box_value!(Duration, Interval, Interval(None,None));
}

#[allow(unused_macros)]
macro_rules! box_to_opt_ref {
( $v: expr ) => {
Expand Down Expand Up @@ -635,6 +651,28 @@ impl Value {
}
}

impl Value {
#[cfg(all(feature = "postgres-interval", feature = "with-chrono"))]
pub fn is_interval(&self) -> bool {
return matches!(self, Self::Interval(_));
}
#[cfg(not(all(feature = "postgres-interval", feature = "with-chrono")))]
pub fn is_interval(&self) -> bool {
return false;
}
#[cfg(all(feature = "postgres-interval", feature = "with-chrono"))]
pub fn as_ref_interval(&self) -> Option<&Duration> {
match self {
Self::Interval(v) => box_to_opt_ref!(v),
_ => panic!("not Value::Interval"),
}
}
#[cfg(not(all(feature = "postgres-interval", feature = "with-chrono")))]
pub fn as_ref_interval(&self) -> Option<&bool> {
panic!("not Value::Interval")
}
}

impl Value {
pub fn is_array(&self) -> bool {
#[cfg(feature = "postgres-array")]
Expand Down Expand Up @@ -948,6 +986,8 @@ pub fn sea_value_to_json_value(value: &Value) -> Json {
Value::Uuid(None) => Json::Null,
#[cfg(feature = "postgres-array")]
Value::Array(None) => Json::Null,
#[cfg(all(feature = "postgres-interval", feature = "with-chrono"))]
Value::Interval(None) => Json::Null,
Value::Bool(Some(b)) => Json::Bool(*b),
Value::TinyInt(Some(v)) => (*v).into(),
Value::SmallInt(Some(v)) => (*v).into(),
Expand Down Expand Up @@ -989,6 +1029,8 @@ pub fn sea_value_to_json_value(value: &Value) -> Json {
.map(|v| sea_value_to_json_value(v))
.collect(),
),
#[cfg(all(feature = "postgres-interval", feature = "with-chrono"))]
Value::Interval(Some(v)) => Json::String(v.as_ref().to_string()),
}
}

Expand Down

0 comments on commit 3a21d56

Please sign in to comment.