Skip to content

Commit

Permalink
fix sqlite chrono tests
Browse files Browse the repository at this point in the history
  • Loading branch information
lovasoa committed Aug 11, 2023
1 parent 42296cf commit 38c5917
Show file tree
Hide file tree
Showing 7 changed files with 46 additions and 20 deletions.
18 changes: 15 additions & 3 deletions sqlx-core/src/sqlite/types/bigdecimal.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
use crate::bigdecimal::FromPrimitive;
use crate::decode::Decode;
use crate::encode::{Encode, IsNull};
use crate::error::BoxDynError;
use crate::sqlite::{
type_info::DataType, Sqlite, SqliteArgumentValue, SqliteTypeInfo, SqliteValueRef,
};
use crate::types::Type;
use crate::value::ValueRef;
use bigdecimal::BigDecimal;
use std::str::FromStr;

impl Type<Sqlite> for BigDecimal {
fn type_info() -> SqliteTypeInfo {
Expand All @@ -14,6 +17,8 @@ impl Type<Sqlite> for BigDecimal {

fn compatible(ty: &SqliteTypeInfo) -> bool {
<&str as Type<Sqlite>>::compatible(ty)
|| <f64 as Type<Sqlite>>::compatible(ty)
|| <i64 as Type<Sqlite>>::compatible(ty)
}
}

Expand All @@ -26,8 +31,15 @@ impl Encode<'_, Sqlite> for BigDecimal {

impl Decode<'_, Sqlite> for BigDecimal {
fn decode(value: SqliteValueRef<'_>) -> Result<Self, BoxDynError> {
let string_value = <&str as Decode<Sqlite>>::decode(value)?;

string_value.parse().map_err(Into::into)
let ty = &value.type_info();
if <i64 as Type<Sqlite>>::compatible(ty) {
Ok(BigDecimal::from(value.int64()))
} else if <f64 as Type<Sqlite>>::compatible(ty) {
Ok(BigDecimal::from_f64(value.double()).ok_or("bad float")?)
} else if <&str as Type<Sqlite>>::compatible(ty) {
Ok(BigDecimal::from_str(value.text()?)?)
} else {
Err("bad type".into())
}
}
}
30 changes: 24 additions & 6 deletions sqlx-core/src/sqlite/types/chrono.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use crate::types::chrono::FixedOffset;
use crate::value::ValueRef;
use crate::{
decode::Decode,
encode::{Encode, IsNull},
Expand Down Expand Up @@ -39,7 +40,10 @@ impl Type<Sqlite> for NaiveDate {
}

fn compatible(ty: &SqliteTypeInfo) -> bool {
matches!(ty.0, DataType::Date | DataType::Text)
matches!(
ty.0,
DataType::Date | DataType::Text | DataType::Int64 | DataType::Int
)
}
}

Expand Down Expand Up @@ -173,13 +177,27 @@ impl<'r> Decode<'r, Sqlite> for NaiveDateTime {

impl<'r> Decode<'r, Sqlite> for NaiveDate {
fn decode(value: SqliteValueRef<'r>) -> Result<Self, BoxDynError> {
let txt = value.text()?;
for fmt in ["%F", "%x", "%Y%m%d"] {
if let Ok(dt) = NaiveDate::parse_from_str(txt, fmt) {
return Ok(dt);
match value.type_info().0 {
DataType::Text => {
let txt = value.text()?;
for fmt in ["%F", "%x", "%Y%m%d"] {
if let Ok(dt) = NaiveDate::parse_from_str(txt, fmt) {
return Ok(dt);
}
}
Err(format!("invalid date: {}", txt).into())
}
DataType::Int | DataType::Int64 => {
// parse format 19940416
let int = value.int64();
let year = (int / 10_000) as i32;
let month = ((int % 10_000) / 100) as u32;
let day = (int % 100) as u32;
NaiveDate::from_ymd_opt(year, month, day)
.ok_or(format!("invalid date: {}", int).into())
}
other => Err(format!("invalid date type: {:?}", other).into()),
}
Err(format!("invalid date: {}", txt).into())
}
}

Expand Down
1 change: 1 addition & 0 deletions sqlx-core/src/sqlite/types/decimal.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use crate::value::ValueRef;
use bigdecimal_::FromPrimitive;
use rust_decimal::Decimal;

Expand Down
1 change: 1 addition & 0 deletions sqlx-core/src/sqlite/types/time.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use crate::value::ValueRef;
use crate::{
decode::Decode,
encode::{Encode, IsNull},
Expand Down
8 changes: 1 addition & 7 deletions sqlx-core/src/sqlite/value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,6 @@ impl<'r> SqliteValueRef<'r> {
SqliteValueData::Value(v) => v.text(),
}
}

pub(super) fn type_info(&self) -> SqliteTypeInfo {
match self.0 {
SqliteValueData::Value(v) => v.type_info.clone(),
}
}
}

impl<'r> ValueRef<'r> for SqliteValueRef<'r> {
Expand Down Expand Up @@ -181,7 +175,7 @@ impl<'r> From<SqliteValueRef<'r>> for crate::any::AnyValueRef<'r> {
#[inline]
fn from(value: SqliteValueRef<'r>) -> Self {
crate::any::AnyValueRef {
type_info: value.type_info().into(),
type_info: value.type_info().into_owned().into(),
kind: crate::any::value::AnyValueRefKind::Sqlite(value),
}
}
Expand Down
8 changes: 4 additions & 4 deletions tests/any/any.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ async fn it_has_bigdecimal() -> anyhow::Result<()> {
use sqlx_oldapi::types::BigDecimal;
use std::str::FromStr;
assert_eq!(
BigDecimal::from_str("1234567.89")?,
get_val::<BigDecimal>("CAST(1234567.89 AS DECIMAL(9,2))").await?
BigDecimal::from_str("1234567.25")?,
get_val::<BigDecimal>("CAST('1234567.25' AS DECIMAL(9,2))").await?
);
Ok(())
}
Expand All @@ -57,8 +57,8 @@ async fn it_has_decimal() -> anyhow::Result<()> {
use sqlx_oldapi::types::Decimal;
use std::str::FromStr;
assert_eq!(
Decimal::from_str("1234567.89")?,
get_val::<Decimal>("CAST(1234567.89 AS DECIMAL(9,2))").await?
Decimal::from_str("1234567.25")?,
get_val::<Decimal>("CAST('1234567.25' AS DECIMAL(9,2))").await?
);
Ok(())
}
Expand Down
Binary file modified tests/sqlite/sqlite.db
Binary file not shown.

0 comments on commit 38c5917

Please sign in to comment.