From 5d6516da689967cd807b51308c0b43d73640946e Mon Sep 17 00:00:00 2001 From: Ryan Leckey Date: Thu, 2 Jul 2020 23:00:46 -0700 Subject: [PATCH] fix: re-add MapRow and TryMapRow to fix HRTB normalization when more than one driver is in-use --- sqlx-core/src/any/mod.rs | 4 +-- sqlx-core/src/lib.rs | 4 ++- sqlx-core/src/mssql/mod.rs | 4 +-- sqlx-core/src/mysql/mod.rs | 4 +-- sqlx-core/src/postgres/mod.rs | 4 +-- sqlx-core/src/query.rs | 61 ++++++++++++++++++++++++++++++++++ sqlx-core/src/sqlite/mod.rs | 4 +-- src/lib.rs | 1 + tests/sqlite/sqlite.db | Bin 36864 -> 36864 bytes 9 files changed, 74 insertions(+), 12 deletions(-) diff --git a/sqlx-core/src/any/mod.rs b/sqlx-core/src/any/mod.rs index f3f548e0..a5cd03e4 100644 --- a/sqlx-core/src/any/mod.rs +++ b/sqlx-core/src/any/mod.rs @@ -35,7 +35,7 @@ pub type AnyPool = crate::pool::Pool; impl_into_arguments_for_arguments!(AnyArguments<'q>); impl_executor_for_pool_connection!(Any, AnyConnection, AnyRow); impl_executor_for_transaction!(Any, AnyRow); +impl_map_row!(Any, AnyRow); -// required because some databases have a different handling -// of NULL +// required because some databases have a different handling of NULL impl_encode_for_option!(Any); diff --git a/sqlx-core/src/lib.rs b/sqlx-core/src/lib.rs index 5db5b076..efbb69e4 100644 --- a/sqlx-core/src/lib.rs +++ b/sqlx-core/src/lib.rs @@ -43,6 +43,9 @@ pub mod decode; #[macro_use] pub mod types; +#[macro_use] +pub mod query; + mod common; pub mod database; pub mod describe; @@ -50,7 +53,6 @@ pub mod executor; pub mod from_row; mod io; mod net; -pub mod query; pub mod query_as; pub mod query_scalar; pub mod row; diff --git a/sqlx-core/src/mssql/mod.rs b/sqlx-core/src/mssql/mod.rs index 9708f229..22cc58de 100644 --- a/sqlx-core/src/mssql/mod.rs +++ b/sqlx-core/src/mssql/mod.rs @@ -30,6 +30,4 @@ pub type MssqlPool = crate::pool::Pool; impl_into_arguments_for_arguments!(MssqlArguments); impl_executor_for_pool_connection!(Mssql, MssqlConnection, MssqlRow); impl_executor_for_transaction!(Mssql, MssqlRow); - -// FIXME: RPC NULL parameter values / results -// FIXME: RPC Empty String parameter values +impl_map_row!(Mssql, MssqlRow); diff --git a/sqlx-core/src/mysql/mod.rs b/sqlx-core/src/mysql/mod.rs index 64a5bbba..aca0cf22 100644 --- a/sqlx-core/src/mysql/mod.rs +++ b/sqlx-core/src/mysql/mod.rs @@ -30,7 +30,7 @@ pub type MySqlPool = crate::pool::Pool; impl_into_arguments_for_arguments!(MySqlArguments); impl_executor_for_pool_connection!(MySql, MySqlConnection, MySqlRow); impl_executor_for_transaction!(MySql, MySqlRow); +impl_map_row!(MySql, MySqlRow); -// required because some databases have a different handling -// of NULL +// required because some databases have a different handling of NULL impl_encode_for_option!(MySql); diff --git a/sqlx-core/src/postgres/mod.rs b/sqlx-core/src/postgres/mod.rs index c49cc7a6..60c335a4 100644 --- a/sqlx-core/src/postgres/mod.rs +++ b/sqlx-core/src/postgres/mod.rs @@ -33,7 +33,7 @@ pub type PgPool = crate::pool::Pool; impl_into_arguments_for_arguments!(PgArguments); impl_executor_for_pool_connection!(Postgres, PgConnection, PgRow); impl_executor_for_transaction!(Postgres, PgRow); +impl_map_row!(Postgres, PgRow); -// required because some databases have a different handling -// of NULL +// required because some databases have a different handling of NULL impl_encode_for_option!(Postgres); diff --git a/sqlx-core/src/query.rs b/sqlx-core/src/query.rs index 84e4f29c..61dec8cd 100644 --- a/sqlx-core/src/query.rs +++ b/sqlx-core/src/query.rs @@ -302,6 +302,40 @@ where } } +// A (hopefully) temporary workaround for an internal compiler error (ICE) involving higher-ranked +// trait bounds (HRTBs), associated types and closures. +// +// See https://github.com/rust-lang/rust/issues/62529 + +pub trait TryMapRow { + type Output: Unpin; + + fn try_map_row(&mut self, row: DB::Row) -> Result; +} + +pub trait MapRow { + type Output: Unpin; + + fn map_row(&mut self, row: DB::Row) -> Self::Output; +} + +// A private adapter that implements [MapRow] in terms of [TryMapRow] +// Just ends up Ok wrapping it + +struct MapRowAdapter(F); + +impl TryMapRow for MapRowAdapter +where + O: Unpin, + F: MapRow, +{ + type Output = O; + + fn try_map_row(&mut self, row: DB::Row) -> Result { + Ok(self.0.map_row(row)) + } +} + /// Make a SQL query. #[inline] pub fn query(sql: &str) -> Query<'_, DB, >::Arguments> @@ -328,3 +362,30 @@ where query: sql, } } + +#[allow(unused_macros)] +macro_rules! impl_map_row { + ($DB:ident, $R:ident) => { + impl crate::query::MapRow<$DB> for F + where + F: FnMut($R) -> O, + { + type Output = O; + + fn map_row(&mut self, row: $R) -> O { + (self)(row) + } + } + + impl crate::query::TryMapRow<$DB> for F + where + F: FnMut($R) -> Result, + { + type Output = O; + + fn try_map_row(&mut self, row: $R) -> Result { + (self)(row) + } + } + }; +} diff --git a/sqlx-core/src/sqlite/mod.rs b/sqlx-core/src/sqlite/mod.rs index bb25f45f..ff891dc8 100644 --- a/sqlx-core/src/sqlite/mod.rs +++ b/sqlx-core/src/sqlite/mod.rs @@ -34,7 +34,7 @@ pub type SqlitePool = crate::pool::Pool; impl_into_arguments_for_arguments!(SqliteArguments<'q>); impl_executor_for_pool_connection!(Sqlite, SqliteConnection, SqliteRow); impl_executor_for_transaction!(Sqlite, SqliteRow); +impl_map_row!(Sqlite, SqliteRow); -// required because some databases have a different handling -// of NULL +// required because some databases have a different handling of NULL impl_encode_for_option!(Sqlite); diff --git a/src/lib.rs b/src/lib.rs index 5d9d9b52..5c9803be 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -113,6 +113,7 @@ pub mod decode { /// Return types for the `query` family of functions and macros. pub mod query { pub use sqlx_core::query::{Map, Query}; + pub use sqlx_core::query::{MapRow, TryMapRow}; pub use sqlx_core::query_as::QueryAs; pub use sqlx_core::query_scalar::QueryScalar; } diff --git a/tests/sqlite/sqlite.db b/tests/sqlite/sqlite.db index fa00c6fb1e0d674cdf9624d6e752d2b3e3134353..77339064b5f5200eef7b521a4f91270446c8138c 100644 GIT binary patch delta 240 zcmZozz|^pSX@WGP(L@<%Mx%`hOZ1t=_~ItB8z}Pd?d4m=H=VDAuaGZpv!H+$U%j9h zGlOPHMrN@B5G5*`pg delta 55 zcmZozz|^pSX@WGP&O{k!MxBibOZ1rq_%2LlH&EOxD6oQW^94H-MrHy2jg#3OKq8&| Kn>YIVI{*OKfDrZo