From 55b05a0fec5569e14360fc3a859246adbeb47a14 Mon Sep 17 00:00:00 2001 From: Ivan Krivosheev Date: Wed, 30 Mar 2022 21:19:59 +0300 Subject: [PATCH 1/2] issues-280 Fix driver for work with types --- src/driver/rusqlite.rs | 54 ++++++++++++-------------- src/driver/sqlx_mysql.rs | 62 ++++++++++++++---------------- src/driver/sqlx_postgres.rs | 65 +++++++++++++++---------------- src/driver/sqlx_sqlite.rs | 62 ++++++++++++++---------------- src/value.rs | 76 ------------------------------------- 5 files changed, 113 insertions(+), 206 deletions(-) diff --git a/src/driver/rusqlite.rs b/src/driver/rusqlite.rs index b6c59bc04..aa90da41e 100644 --- a/src/driver/rusqlite.rs +++ b/src/driver/rusqlite.rs @@ -75,35 +75,31 @@ macro_rules! sea_query_driver_rusqlite { Value::Double(v) => to_sql!(v, f64), Value::String(v) => box_to_sql!(v, String), Value::Bytes(v) => box_to_sql!(v, Vec), - _ => { - if self.0.is_json() { - ty_to_sql!(self.0.as_ref_json()) - } else if self.0.is_chrono_date() { - ty_to_sql!(self.0.as_ref_chrono_date()) - } else if self.0.is_chrono_time() { - ty_to_sql!(self.0.as_ref_chrono_time()) - } else if self.0.is_chrono_date_time() { - ty_to_sql!(self.0.as_ref_chrono_date_time()) - } else if self.0.is_chrono_date_time_utc() { - ty_to_sql!(self.0.as_ref_chrono_date_time_utc()) - } else if self.0.is_chrono_date_time_local() { - ty_to_sql!(self.0.as_ref_chrono_date_time_local()) - } else if self.0.is_chrono_date_time_with_time_zone() { - ty_to_sql!(self.0.as_ref_chrono_date_time_with_time_zone()) - } else if self.0.is_time_date() { - opt_string_to_sql!(self.0.time_as_naive_utc_in_string()) - } else if self.0.is_time_time() { - opt_string_to_sql!(self.0.time_as_naive_utc_in_string()) - } else if self.0.is_time_date_time() { - opt_string_to_sql!(self.0.time_as_naive_utc_in_string()) - } else if self.0.is_time_date_time_with_time_zone() { - ty_to_sql!(self.0.as_ref_time_date_time_with_time_zone()) - } else if self.0.is_uuid() { - ty_to_sql!(self.0.as_ref_uuid()) - } else { - unimplemented!(); - } - } + #[cfg(feature = "with-json")] + Value::Json(v) => ty_to_sql!(v), + #[cfg(feature = "with-chrono")] + Value::ChronoDate(v) => ty_to_sql!(v), + #[cfg(feature = "with-chrono")] + Value::ChronoTime(v) => ty_to_sql!(v), + #[cfg(feature = "with-chrono")] + Value::ChronoDateTime(v) => ty_to_sql!(v), + #[cfg(feature = "with-chrono")] + Value::ChronoDateTimeUtc(v) => ty_to_sql!(v), + #[cfg(feature = "with-chrono")] + Value::ChronoDateTimeLocal(v) => ty_to_sql!(v), + #[cfg(feature = "with-chrono")] + Value::ChronoDateTimeWithTimeZone(v) => ty_to_sql!(v), + #[cfg(feature = "with-time")] + Value::TimeDate(v) => opt_string_to_sql!(v), + #[cfg(feature = "with-time")] + Value::TimeTime(v) => opt_string_to_sql!(v), + #[cfg(feature = "with-time")] + Value::TimeDateTime(v) => opt_string_to_sql!(v), + #[cfg(feature = "with-time")] + Value::TimeDateTimeWithTimeZone(v) => opt_string_to_sql!(v), + #[cfg(feature = "with-uuid")] + Value::Uuid(v) => ty_to_sql!(v), + _ => unimplemented!(), } } } diff --git a/src/driver/sqlx_mysql.rs b/src/driver/sqlx_mysql.rs index 531c5c980..821ef6e1e 100644 --- a/src/driver/sqlx_mysql.rs +++ b/src/driver/sqlx_mysql.rs @@ -33,39 +33,35 @@ macro_rules! bind_params_sqlx_mysql { Value::Double(v) => bind!(v, f64), Value::String(v) => bind_box!(v, String), Value::Bytes(v) => bind_box!(v, Vec), - _ => { - if value.is_json() { - query.bind(value.as_ref_json()) - } else if value.is_chrono_date() { - query.bind(value.as_ref_chrono_date()) - } else if value.is_chrono_time() { - query.bind(value.as_ref_chrono_time()) - } else if value.is_chrono_date_time() { - query.bind(value.as_ref_chrono_date_time()) - } else if value.is_chrono_date_time_utc() { - query.bind(value.as_ref_chrono_date_time_utc()) - } else if value.is_chrono_date_time_local() { - query.bind(value.as_ref_chrono_date_time_local()) - } else if value.is_chrono_date_time_with_time_zone() { - query.bind(value.chrono_as_naive_utc_in_string()) - } else if value.is_time_date() { - query.bind(value.as_ref_time_date()) - } else if value.is_time_time() { - query.bind(value.as_ref_time_time()) - } else if value.is_time_date_time() { - query.bind(value.as_ref_time_date_time()) - } else if value.is_time_date_time_with_time_zone() { - query.bind(value.time_as_naive_utc_in_string()) - } else if value.is_decimal() { - query.bind(value.as_ref_decimal()) - } else if value.is_big_decimal() { - query.bind(value.as_ref_big_decimal()) - } else if value.is_uuid() { - query.bind(value.as_ref_uuid()) - } else { - unimplemented!(); - } - } + #[cfg(feature = "with-json")] + Value::Json(v) => query.bind(v), + #[cfg(feature = "with-chrono")] + Value::ChronoDate(v) => query.bind(v), + #[cfg(feature = "with-chrono")] + Value::ChronoTime(v) => query.bind(v), + #[cfg(feature = "with-chrono")] + Value::ChronoDateTime(v) => query.bind(v), + #[cfg(feature = "with-chrono")] + Value::ChronoDateTimeUtc(v) => query.bind(v), + #[cfg(feature = "with-chrono")] + Value::ChronoDateTimeLocal(v) => query.bind(v), + #[cfg(feature = "with-chrono")] + Value::ChronoDateTimeWithTimeZone(v) => query.bind(v), + #[cfg(feature = "with-time")] + Value::TimeDate(v) => query.bind(v), + #[cfg(feature = "with-time")] + Value::TimeTime(v) => query.bind(v), + #[cfg(feature = "with-time")] + Value::TimeDateTime(v) => query.bind(v), + #[cfg(feature = "with-time")] + Value::TimeDateTimeWithTimeZone(v) => query.bind(v), + #[cfg(feature = "with-uuid")] + Value::Uuid(v) => query.bind(v), + #[cfg(feature = "with-rust_decimal")] + Value::Decimal(v) => query.bind(v), + #[cfg(feature = "with-bigdecimal")] + Value::BigDecimal(v) => query.bind(v), + _ => unimplemented!(), }; } query diff --git a/src/driver/sqlx_postgres.rs b/src/driver/sqlx_postgres.rs index c8f32e196..a72fa7437 100644 --- a/src/driver/sqlx_postgres.rs +++ b/src/driver/sqlx_postgres.rs @@ -33,41 +33,36 @@ macro_rules! bind_params_sqlx_postgres { Value::Double(v) => bind!(v, f64), Value::String(v) => bind_box!(v, String), Value::Bytes(v) => bind_box!(v, Vec), - _ => { - if value.is_json() { - query.bind(value.as_ref_json()) - } else if value.is_chrono_date() { - query.bind(value.as_ref_chrono_date()) - } else if value.is_chrono_time() { - query.bind(value.as_ref_chrono_time()) - } else if value.is_chrono_date_time() { - query.bind(value.as_ref_chrono_date_time()) - } else if value.is_chrono_date_time_utc() { - query.bind(value.as_ref_chrono_date_time_utc()) - } else if value.is_chrono_date_time_local() { - query.bind(value.as_ref_chrono_date_time_local()) - } else if value.is_chrono_date_time_with_time_zone() { - query.bind(value.as_ref_chrono_date_time_with_time_zone()) - } else if value.is_time_date() { - query.bind(value.as_ref_time_date()) - } else if value.is_time_time() { - query.bind(value.as_ref_time_time()) - } else if value.is_time_date_time() { - query.bind(value.as_ref_time_date_time()) - } else if value.is_time_date_time_with_time_zone() { - query.bind(value.as_ref_time_date_time_with_time_zone()) - } else if value.is_decimal() { - query.bind(value.as_ref_decimal()) - } else if value.is_big_decimal() { - query.bind(value.as_ref_big_decimal()) - } else if value.is_uuid() { - query.bind(value.as_ref_uuid()) - } else if value.is_array() { - unimplemented!("SQLx array is not supported"); - } else { - unimplemented!(); - } - } + #[cfg(feature = "with-json")] + Value::Json(v) => query.bind(v), + #[cfg(feature = "with-chrono")] + Value::ChronoDate(v) => query.bind(v), + #[cfg(feature = "with-chrono")] + Value::ChronoTime(v) => query.bind(v), + #[cfg(feature = "with-chrono")] + Value::ChronoDateTime(v) => query.bind(v), + #[cfg(feature = "with-chrono")] + Value::ChronoDateTimeUtc(v) => query.bind(v), + #[cfg(feature = "with-chrono")] + Value::ChronoDateTimeLocal(v) => query.bind(v), + #[cfg(feature = "with-chrono")] + Value::ChronoDateTimeWithTimeZone(v) => query.bind(v), + #[cfg(feature = "with-time")] + Value::TimeDate(v) => query.bind(v), + #[cfg(feature = "with-time")] + Value::TimeTime(v) => query.bind(v), + #[cfg(feature = "with-time")] + Value::TimeDateTime(v) => query.bind(v), + #[cfg(feature = "with-time")] + Value::TimeDateTimeWithTimeZone(v) => query.bind(v), + #[cfg(feature = "with-uuid")] + Value::Uuid(v) => query.bind(v), + #[cfg(feature = "with-rust_decimal")] + Value::Decimal(v) => query.bind(v), + #[cfg(feature = "with-bigdecimal")] + Value::BigDecimal(v) => query.bind(v), + #[cfg(feature = "postgres-array")] + Value::Array(_) => unimplemented!("SQLx array is not supported"), }; } query diff --git a/src/driver/sqlx_sqlite.rs b/src/driver/sqlx_sqlite.rs index 5af7e3cf2..a3dfbcb0c 100644 --- a/src/driver/sqlx_sqlite.rs +++ b/src/driver/sqlx_sqlite.rs @@ -33,39 +33,35 @@ macro_rules! bind_params_sqlx_sqlite { Value::Double(v) => bind!(v, f64), Value::String(v) => bind_box!(v, String), Value::Bytes(v) => bind_box!(v, Vec), - _ => { - if value.is_json() { - query.bind(value.as_ref_json()) - } else if value.is_chrono_date() { - query.bind(value.as_ref_chrono_date()) - } else if value.is_chrono_time() { - query.bind(value.as_ref_chrono_time()) - } else if value.is_chrono_date_time() { - query.bind(value.as_ref_chrono_date_time()) - } else if value.is_chrono_date_time_utc() { - query.bind(value.chrono_as_naive_utc_in_string()) - } else if value.is_chrono_date_time_local() { - query.bind(value.chrono_as_naive_utc_in_string()) - } else if value.is_chrono_date_time_with_time_zone() { - query.bind(value.chrono_as_naive_utc_in_string()) - } else if value.is_time_date() { - query.bind(value.time_as_naive_utc_in_string()) - } else if value.is_time_time() { - query.bind(value.time_as_naive_utc_in_string()) - } else if value.is_time_date_time() { - query.bind(value.time_as_naive_utc_in_string()) - } else if value.is_time_date_time_with_time_zone() { - query.bind(value.time_as_naive_utc_in_string()) - } else if value.is_decimal() { - query.bind(value.decimal_to_f64()) - } else if value.is_big_decimal() { - query.bind(value.big_decimal_to_f64()) - } else if value.is_uuid() { - query.bind(value.as_ref_uuid()) - } else { - unimplemented!(); - } - } + #[cfg(feature = "with-json")] + Value::Json(v) => query.bind(v), + #[cfg(feature = "with-chrono")] + Value::ChronoDate(v) => query.bind(v), + #[cfg(feature = "with-chrono")] + Value::ChronoTime(v) => query.bind(v), + #[cfg(feature = "with-chrono")] + Value::ChronoDateTime(v) => query.bind(v), + #[cfg(feature = "with-chrono")] + Value::ChronoDateTimeUtc(v) => query.bind(v), + #[cfg(feature = "with-chrono")] + Value::ChronoDateTimeLocal(v) => query.bind(v), + #[cfg(feature = "with-chrono")] + Value::ChronoDateTimeWithTimeZone(v) => query.bind(v), + #[cfg(feature = "with-time")] + Value::TimeDate(v) => query.bind(v), + #[cfg(feature = "with-time")] + Value::TimeTime(v) => query.bind(v), + #[cfg(feature = "with-time")] + Value::TimeDateTime(v) => query.bind(v), + #[cfg(feature = "with-time")] + Value::TimeDateTimeWithTimeZone(v) => query.bind(v), + #[cfg(feature = "with-uuid")] + Value::Uuid(v) => query.bind(v), + #[cfg(feature = "with-rust_decimal")] + Value::Decimal(v) => query.bind(v), + #[cfg(feature = "with-bigdecimal")] + Value::BigDecimal(v) => query.bind(v), + _ => unimplemented!(), }; } query diff --git a/src/value.rs b/src/value.rs index e3b5b2557..5fa5de9a2 100644 --- a/src/value.rs +++ b/src/value.rs @@ -591,10 +591,6 @@ impl Value { _ => panic!("not Value::Json"), } } - #[cfg(not(feature = "with-json"))] - pub fn as_ref_json(&self) -> Option<&bool> { - panic!("not Value::Json") - } } impl Value { @@ -611,10 +607,6 @@ impl Value { _ => panic!("not Value::ChronoDate"), } } - #[cfg(not(feature = "with-chrono"))] - pub fn as_ref_chrono_date(&self) -> Option<&bool> { - panic!("not Value::ChronoDate") - } } impl Value { @@ -631,10 +623,6 @@ impl Value { _ => panic!("not Value::TimeDate"), } } - #[cfg(not(feature = "with-time"))] - pub fn as_ref_time_date(&self) -> Option<&bool> { - panic!("not Value::TimeDate") - } } impl Value { @@ -651,10 +639,6 @@ impl Value { _ => panic!("not Value::ChronoTime"), } } - #[cfg(not(feature = "with-chrono"))] - pub fn as_ref_chrono_time(&self) -> Option<&bool> { - panic!("not Value::ChronoTime") - } } impl Value { @@ -671,10 +655,6 @@ impl Value { _ => panic!("not Value::TimeTime"), } } - #[cfg(not(feature = "with-time"))] - pub fn as_ref_time_time(&self) -> Option<&bool> { - panic!("not Value::TimeTime") - } } impl Value { @@ -691,10 +671,6 @@ impl Value { _ => panic!("not Value::ChronoDateTime"), } } - #[cfg(not(feature = "with-chrono"))] - pub fn as_ref_chrono_date_time(&self) -> Option<&bool> { - panic!("not Value::ChronoDateTime") - } } impl Value { @@ -711,10 +687,6 @@ impl Value { _ => panic!("not Value::TimeDateTime"), } } - #[cfg(not(feature = "with-time"))] - pub fn as_ref_time_date_time(&self) -> Option<&bool> { - panic!("not Value::TimeDateTime") - } } impl Value { @@ -731,10 +703,6 @@ impl Value { _ => panic!("not Value::ChronoDateTimeUtc"), } } - #[cfg(not(feature = "with-chrono"))] - pub fn as_ref_chrono_date_time_utc(&self) -> Option<&bool> { - panic!("not Value::ChronoDateTimeUtc") - } } impl Value { @@ -751,10 +719,6 @@ impl Value { _ => panic!("not Value::ChronoDateTimeLocal"), } } - #[cfg(not(feature = "with-chrono"))] - pub fn as_ref_chrono_date_time_local(&self) -> Option<&bool> { - panic!("not Value::ChronoDateTimeLocal") - } } impl Value { @@ -771,10 +735,6 @@ impl Value { _ => panic!("not Value::ChronoDateTimeWithTimeZone"), } } - #[cfg(not(feature = "with-chrono"))] - pub fn as_ref_chrono_date_time_with_time_zone(&self) -> Option<&bool> { - panic!("not Value::ChronoDateTimeWithTimeZone") - } } impl Value { @@ -791,10 +751,6 @@ impl Value { _ => panic!("not Value::TimeDateTimeWithTimeZone"), } } - #[cfg(not(feature = "with-time"))] - pub fn as_ref_time_date_time_with_time_zone(&self) -> Option<&bool> { - panic!("not Value::TimeDateTimeWithTimeZone") - } } impl Value { @@ -810,10 +766,6 @@ impl Value { _ => panic!("not chrono Value"), } } - #[cfg(not(feature = "with-chrono"))] - pub fn chrono_as_naive_utc_in_string(&self) -> Option<&bool> { - panic!("not chrono Value") - } } impl Value { @@ -829,10 +781,6 @@ impl Value { _ => panic!("not time Value"), } } - #[cfg(not(feature = "with-time"))] - pub fn time_as_naive_utc_in_string(&self) -> Option<&bool> { - panic!("not time Value") - } } impl Value { @@ -854,14 +802,6 @@ impl Value { use rust_decimal::prelude::ToPrimitive; self.as_ref_decimal().map(|d| d.to_f64().unwrap()) } - #[cfg(not(feature = "with-rust_decimal"))] - pub fn as_ref_decimal(&self) -> Option<&bool> { - panic!("not Value::Decimal") - } - #[cfg(not(feature = "with-rust_decimal"))] - pub fn decimal_to_f64(&self) -> Option { - None - } } impl Value { @@ -883,14 +823,6 @@ impl Value { use bigdecimal::ToPrimitive; self.as_ref_big_decimal().map(|d| d.to_f64().unwrap()) } - #[cfg(not(feature = "with-bigdecimal"))] - pub fn as_ref_big_decimal(&self) -> Option<&bool> { - panic!("not Value::BigDecimal") - } - #[cfg(not(feature = "with-bigdecimal"))] - pub fn big_decimal_to_f64(&self) -> Option { - None - } } impl Value { @@ -907,10 +839,6 @@ impl Value { _ => panic!("not Value::Uuid"), } } - #[cfg(not(feature = "with-uuid"))] - pub fn as_ref_uuid(&self) -> Option<&bool> { - panic!("not Value::Uuid") - } } impl Value { @@ -928,10 +856,6 @@ impl Value { _ => panic!("not Value::Array"), } } - #[cfg(not(feature = "postgres-array"))] - pub fn as_ref_array(&self) -> Option<&bool> { - panic!("not Value::Array") - } } impl IntoIterator for ValueTuple { From 6dbd1d947c5066a0de354778f461caa9a35ca1c4 Mon Sep 17 00:00:00 2001 From: Ivan Krivosheev Date: Wed, 30 Mar 2022 21:38:01 +0300 Subject: [PATCH 2/2] issues-280 Fixes --- src/backend/query_builder.rs | 18 +++++++----------- src/driver/sqlx_postgres.rs | 2 ++ src/value.rs | 27 ++++++++++++--------------- 3 files changed, 21 insertions(+), 26 deletions(-) diff --git a/src/backend/query_builder.rs b/src/backend/query_builder.rs index 75ee8dc6e..46983d481 100644 --- a/src/backend/query_builder.rs +++ b/src/backend/query_builder.rs @@ -1026,28 +1026,24 @@ pub trait QueryBuilder: QuotedBuilder { #[cfg(feature = "with-json")] Value::Json(Some(v)) => self.write_string_quoted(&v.to_string(), &mut s), #[cfg(feature = "with-chrono")] - Value::ChronoDate(Some(v)) => { - write!(s, "\'{}\'", v.format("%Y-%m-%d").to_string()).unwrap() - } + Value::ChronoDate(Some(v)) => write!(s, "\'{}\'", v.format("%Y-%m-%d")).unwrap(), #[cfg(feature = "with-chrono")] - Value::ChronoTime(Some(v)) => { - write!(s, "\'{}\'", v.format("%H:%M:%S").to_string()).unwrap() - } + Value::ChronoTime(Some(v)) => write!(s, "\'{}\'", v.format("%H:%M:%S")).unwrap(), #[cfg(feature = "with-chrono")] Value::ChronoDateTime(Some(v)) => { - write!(s, "\'{}\'", v.format("%Y-%m-%d %H:%M:%S").to_string()).unwrap() + write!(s, "\'{}\'", v.format("%Y-%m-%d %H:%M:%S")).unwrap() } #[cfg(feature = "with-chrono")] Value::ChronoDateTimeUtc(Some(v)) => { - write!(s, "\'{}\'", v.format("%Y-%m-%d %H:%M:%S %:z").to_string()).unwrap() + write!(s, "\'{}\'", v.format("%Y-%m-%d %H:%M:%S %:z")).unwrap() } #[cfg(feature = "with-chrono")] Value::ChronoDateTimeLocal(Some(v)) => { - write!(s, "\'{}\'", v.format("%Y-%m-%d %H:%M:%S %:z").to_string()).unwrap() + write!(s, "\'{}\'", v.format("%Y-%m-%d %H:%M:%S %:z")).unwrap() } #[cfg(feature = "with-chrono")] Value::ChronoDateTimeWithTimeZone(Some(v)) => { - write!(s, "\'{}\'", v.format("%Y-%m-%d %H:%M:%S %:z").to_string()).unwrap() + write!(s, "\'{}\'", v.format("%Y-%m-%d %H:%M:%S %:z")).unwrap() } #[cfg(feature = "with-time")] Value::TimeDate(Some(v)) => write!(s, "\'{}\'", v.format("%Y-%m-%d")).unwrap(), @@ -1066,7 +1062,7 @@ pub trait QueryBuilder: QuotedBuilder { #[cfg(feature = "with-bigdecimal")] Value::BigDecimal(Some(v)) => write!(s, "{}", v).unwrap(), #[cfg(feature = "with-uuid")] - Value::Uuid(Some(v)) => write!(s, "\'{}\'", v.to_string()).unwrap(), + Value::Uuid(Some(v)) => write!(s, "\'{}\'", v).unwrap(), #[cfg(feature = "postgres-array")] Value::Array(Some(v)) => write!( s, diff --git a/src/driver/sqlx_postgres.rs b/src/driver/sqlx_postgres.rs index a72fa7437..e3531f7c0 100644 --- a/src/driver/sqlx_postgres.rs +++ b/src/driver/sqlx_postgres.rs @@ -63,6 +63,8 @@ macro_rules! bind_params_sqlx_postgres { Value::BigDecimal(v) => query.bind(v), #[cfg(feature = "postgres-array")] Value::Array(_) => unimplemented!("SQLx array is not supported"), + #[allow(unreachable_patterns)] + _ => unimplemented!(), }; } query diff --git a/src/value.rs b/src/value.rs index 5fa5de9a2..b5375463d 100644 --- a/src/value.rs +++ b/src/value.rs @@ -1079,15 +1079,15 @@ where /// Escape a SQL string literal pub fn escape_string(string: &str) -> String { string - .replace("\\", "\\\\") - .replace("\"", "\\\"") - .replace("'", "\\'") - .replace("\0", "\\0") - .replace("\x08", "\\b") - .replace("\x09", "\\t") - .replace("\x1a", "\\z") - .replace("\n", "\\n") - .replace("\r", "\\r") + .replace('\\', "\\\\") + .replace('"', "\\\"") + .replace('\'', "\\'") + .replace('\0', "\\0") + .replace('\x08', "\\b") + .replace('\x09', "\\t") + .replace('\x1a', "\\z") + .replace('\n', "\\n") + .replace('\r', "\\r") } /// Unescape a SQL string literal @@ -1197,12 +1197,9 @@ pub fn sea_value_to_json_value(value: &Value) -> Json { #[cfg(feature = "with-uuid")] Value::Uuid(Some(v)) => Json::String(v.to_string()), #[cfg(feature = "postgres-array")] - Value::Array(Some(v)) => Json::Array( - v.as_ref() - .iter() - .map(|v| sea_value_to_json_value(v)) - .collect(), - ), + Value::Array(Some(v)) => { + Json::Array(v.as_ref().iter().map(sea_value_to_json_value).collect()) + } } }