fix: re-add MapRow and TryMapRow to fix HRTB normalization when more than one driver is in-use

This commit is contained in:
Ryan Leckey 2020-07-02 23:00:46 -07:00
parent c7c46f237b
commit 5d6516da68
9 changed files with 74 additions and 12 deletions

View file

@ -35,7 +35,7 @@ pub type AnyPool = crate::pool::Pool<Any>;
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);

View file

@ -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;

View file

@ -30,6 +30,4 @@ pub type MssqlPool = crate::pool::Pool<Mssql>;
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);

View file

@ -30,7 +30,7 @@ pub type MySqlPool = crate::pool::Pool<MySql>;
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);

View file

@ -33,7 +33,7 @@ pub type PgPool = crate::pool::Pool<Postgres>;
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);

View file

@ -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<DB: Database> {
type Output: Unpin;
fn try_map_row(&mut self, row: DB::Row) -> Result<Self::Output, Error>;
}
pub trait MapRow<DB: Database> {
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>(F);
impl<DB: Database, O, F> TryMapRow<DB> for MapRowAdapter<F>
where
O: Unpin,
F: MapRow<DB, Output = O>,
{
type Output = O;
fn try_map_row(&mut self, row: DB::Row) -> Result<Self::Output, Error> {
Ok(self.0.map_row(row))
}
}
/// Make a SQL query.
#[inline]
pub fn query<DB>(sql: &str) -> Query<'_, DB, <DB as HasArguments<'_>>::Arguments>
@ -328,3 +362,30 @@ where
query: sql,
}
}
#[allow(unused_macros)]
macro_rules! impl_map_row {
($DB:ident, $R:ident) => {
impl<O: Unpin, F> 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<O: Unpin, F> crate::query::TryMapRow<$DB> for F
where
F: FnMut($R) -> Result<O, crate::error::Error>,
{
type Output = O;
fn try_map_row(&mut self, row: $R) -> Result<O, crate::error::Error> {
(self)(row)
}
}
};
}

View file

@ -34,7 +34,7 @@ pub type SqlitePool = crate::pool::Pool<Sqlite>;
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);

View file

@ -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;
}

Binary file not shown.