From 751efdf31bcd02c9d1397f1087fe87c49dd53f9b Mon Sep 17 00:00:00 2001 From: Ryan Leckey Date: Fri, 13 Mar 2020 02:21:01 -0700 Subject: [PATCH] generalize MaybeOwnedConnection and clean up the connection file --- sqlx-core/src/connection.rs | 52 +++++++----------------------- sqlx-core/src/cursor.rs | 10 +++--- sqlx-core/src/executor.rs | 10 ++++-- sqlx-core/src/io/buf_stream.rs | 1 + sqlx-core/src/lib.rs | 2 ++ sqlx-core/src/maybe_owned.rs | 42 ++++++++++++++++++++++++ sqlx-core/src/mysql/cursor.rs | 9 ++---- sqlx-core/src/mysql/executor.rs | 5 ++- sqlx-core/src/pool/connection.rs | 19 +++++++++++ sqlx-core/src/pool/executor.rs | 10 ++++-- sqlx-core/src/postgres/cursor.rs | 9 ++---- sqlx-core/src/postgres/executor.rs | 5 ++- sqlx-core/src/url.rs | 1 + 13 files changed, 110 insertions(+), 65 deletions(-) create mode 100644 sqlx-core/src/maybe_owned.rs diff --git a/sqlx-core/src/connection.rs b/sqlx-core/src/connection.rs index 18459d776..1f05984dc 100644 --- a/sqlx-core/src/connection.rs +++ b/sqlx-core/src/connection.rs @@ -3,6 +3,7 @@ use std::convert::TryInto; use futures_core::future::BoxFuture; use crate::executor::Executor; +use crate::maybe_owned::MaybeOwned; use crate::pool::{Pool, PoolConnection}; use crate::transaction::Transaction; use crate::url::Url; @@ -42,63 +43,32 @@ pub trait Connect: Connection { Self: Sized; } -mod internal { - #[allow(dead_code)] - pub enum MaybeOwnedConnection<'c, C> - where - C: super::Connect, - { - Borrowed(&'c mut C), - Owned(super::PoolConnection), - } +pub(crate) enum ConnectionSource<'c, C> +where + C: Connect, +{ + Connection(MaybeOwned<'c, PoolConnection, C>), #[allow(dead_code)] - pub enum ConnectionSource<'c, C> - where - C: super::Connect, - { - Connection(MaybeOwnedConnection<'c, C>), - Pool(super::Pool), - } + Pool(Pool), } -pub(crate) use self::internal::{ConnectionSource, MaybeOwnedConnection}; - impl<'c, C> ConnectionSource<'c, C> where C: Connect, { #[allow(dead_code)] - pub(crate) async fn resolve_by_ref(&mut self) -> crate::Result<&'_ mut C> { + pub(crate) async fn resolve(&mut self) -> crate::Result<&'_ mut C> { if let ConnectionSource::Pool(pool) = self { - *self = - ConnectionSource::Connection(MaybeOwnedConnection::Owned(pool.acquire().await?)); + *self = ConnectionSource::Connection(MaybeOwned::Owned(pool.acquire().await?)); } Ok(match self { ConnectionSource::Connection(conn) => match conn { - MaybeOwnedConnection::Borrowed(conn) => &mut *conn, - MaybeOwnedConnection::Owned(ref mut conn) => conn, + MaybeOwned::Borrowed(conn) => &mut *conn, + MaybeOwned::Owned(ref mut conn) => conn, }, ConnectionSource::Pool(_) => unreachable!(), }) } } - -impl<'c, C> From<&'c mut C> for MaybeOwnedConnection<'c, C> -where - C: Connect, -{ - fn from(conn: &'c mut C) -> Self { - MaybeOwnedConnection::Borrowed(conn) - } -} - -impl<'c, C> From> for MaybeOwnedConnection<'c, C> -where - C: Connect, -{ - fn from(conn: PoolConnection) -> Self { - MaybeOwnedConnection::Owned(conn) - } -} diff --git a/sqlx-core/src/cursor.rs b/sqlx-core/src/cursor.rs index 6bc26937c..cccd1b229 100644 --- a/sqlx-core/src/cursor.rs +++ b/sqlx-core/src/cursor.rs @@ -1,6 +1,5 @@ use futures_core::future::BoxFuture; -use crate::connection::{Connect, MaybeOwnedConnection}; use crate::database::{Database, HasRow}; use crate::executor::Execute; use crate::pool::Pool; @@ -19,18 +18,17 @@ where { type Database: Database; - #[doc(hidden)] fn from_pool(pool: &Pool<::Connection>, query: E) -> Self where Self: Sized, E: Execute<'q, Self::Database>; - #[doc(hidden)] - fn from_connection(conn: C, query: E) -> Self + fn from_connection( + connection: &'c mut ::Connection, + query: E, + ) -> Self where Self: Sized, - ::Connection: Connect, - C: Into::Connection>>, E: Execute<'q, Self::Database>; /// Fetch the next row in the result. Returns `None` if there are no more rows. diff --git a/sqlx-core/src/executor.rs b/sqlx-core/src/executor.rs index 634f78cb8..bdc06db3d 100644 --- a/sqlx-core/src/executor.rs +++ b/sqlx-core/src/executor.rs @@ -24,7 +24,10 @@ where /// discarding any potential result rows. /// /// Returns the number of rows affected, or 0 if not applicable. - fn execute<'e, 'q, E: 'e>(&'e mut self, query: E) -> BoxFuture<'e, crate::Result> + fn execute<'e, 'q: 'e, 'c: 'e, E: 'e>( + &'c mut self, + query: E, + ) -> BoxFuture<'e, crate::Result> where E: Execute<'q, Self::Database>; @@ -89,7 +92,10 @@ where { type Database = T::Database; - fn execute<'e, 'q, E: 'e>(&'e mut self, query: E) -> BoxFuture<'e, crate::Result> + fn execute<'e, 'q: 'e, 'c: 'e, E: 'e>( + &'c mut self, + query: E, + ) -> BoxFuture<'e, crate::Result> where E: Execute<'q, Self::Database>, { diff --git a/sqlx-core/src/io/buf_stream.rs b/sqlx-core/src/io/buf_stream.rs index aeae57b6c..c33d5faba 100644 --- a/sqlx-core/src/io/buf_stream.rs +++ b/sqlx-core/src/io/buf_stream.rs @@ -45,6 +45,7 @@ where } } + #[cfg(feature = "postgres")] #[inline] pub fn buffer<'c>(&'c self) -> &'c [u8] { &self.rbuf[self.rbuf_rindex..] diff --git a/sqlx-core/src/lib.rs b/sqlx-core/src/lib.rs index d8351e9d8..405242f19 100644 --- a/sqlx-core/src/lib.rs +++ b/sqlx-core/src/lib.rs @@ -15,6 +15,8 @@ pub mod error; #[macro_use] mod io; +mod maybe_owned; + pub mod connection; pub mod cursor; pub mod database; diff --git a/sqlx-core/src/maybe_owned.rs b/sqlx-core/src/maybe_owned.rs new file mode 100644 index 000000000..dde5080f6 --- /dev/null +++ b/sqlx-core/src/maybe_owned.rs @@ -0,0 +1,42 @@ +use core::borrow::{Borrow, BorrowMut}; +use core::ops::{Deref, DerefMut}; + +pub(crate) enum MaybeOwned<'a, O, B = O> { + #[allow(dead_code)] + Borrowed(&'a mut B), + + #[allow(dead_code)] + Owned(O), +} + +impl<'a, O, B> From<&'a mut B> for MaybeOwned<'a, O, B> { + fn from(val: &'a mut B) -> Self { + MaybeOwned::Borrowed(val) + } +} + +impl<'a, O, B> Deref for MaybeOwned<'a, O, B> +where + O: Borrow, +{ + type Target = B; + + fn deref(&self) -> &Self::Target { + match self { + MaybeOwned::Borrowed(val) => val, + MaybeOwned::Owned(ref val) => val.borrow(), + } + } +} + +impl<'a, O, B> DerefMut for MaybeOwned<'a, O, B> +where + O: BorrowMut, +{ + fn deref_mut(&mut self) -> &mut Self::Target { + match self { + MaybeOwned::Borrowed(val) => val, + MaybeOwned::Owned(ref mut val) => val.borrow_mut(), + } + } +} diff --git a/sqlx-core/src/mysql/cursor.rs b/sqlx-core/src/mysql/cursor.rs index 7dc8b5534..5035ca8bb 100644 --- a/sqlx-core/src/mysql/cursor.rs +++ b/sqlx-core/src/mysql/cursor.rs @@ -3,7 +3,7 @@ use std::sync::Arc; use futures_core::future::BoxFuture; -use crate::connection::{ConnectionSource, MaybeOwnedConnection}; +use crate::connection::ConnectionSource; use crate::cursor::Cursor; use crate::executor::Execute; use crate::mysql::protocol::{ColumnCount, ColumnDefinition, Row, Status, TypeId}; @@ -21,7 +21,6 @@ pub struct MySqlCursor<'c, 'q> { impl<'c, 'q> Cursor<'c, 'q> for MySqlCursor<'c, 'q> { type Database = MySql; - #[doc(hidden)] fn from_pool(pool: &Pool, query: E) -> Self where Self: Sized, @@ -36,11 +35,9 @@ impl<'c, 'q> Cursor<'c, 'q> for MySqlCursor<'c, 'q> { } } - #[doc(hidden)] - fn from_connection(conn: C, query: E) -> Self + fn from_connection(conn: &'c mut MySqlConnection, query: E) -> Self where Self: Sized, - C: Into>, E: Execute<'q, MySql>, { Self { @@ -60,7 +57,7 @@ impl<'c, 'q> Cursor<'c, 'q> for MySqlCursor<'c, 'q> { async fn next<'a, 'c: 'a, 'q: 'a>( cursor: &'a mut MySqlCursor<'c, 'q>, ) -> crate::Result>> { - let mut conn = cursor.source.resolve_by_ref().await?; + let mut conn = cursor.source.resolve().await?; // The first time [next] is called we need to actually execute our // contained query. We guard against this happening on _all_ next calls diff --git a/sqlx-core/src/mysql/executor.rs b/sqlx-core/src/mysql/executor.rs index a589e0a41..77fd2ef42 100644 --- a/sqlx-core/src/mysql/executor.rs +++ b/sqlx-core/src/mysql/executor.rs @@ -202,7 +202,10 @@ impl super::MySqlConnection { impl Executor for super::MySqlConnection { type Database = MySql; - fn execute<'e, 'q, E: 'e>(&'e mut self, query: E) -> BoxFuture<'e, crate::Result> + fn execute<'e, 'q: 'e, 'c: 'e, E: 'e>( + &'c mut self, + query: E, + ) -> BoxFuture<'e, crate::Result> where E: Execute<'q, Self::Database>, { diff --git a/sqlx-core/src/pool/connection.rs b/sqlx-core/src/pool/connection.rs index a45a9ca7c..c6759e6aa 100644 --- a/sqlx-core/src/pool/connection.rs +++ b/sqlx-core/src/pool/connection.rs @@ -1,4 +1,5 @@ use futures_core::future::BoxFuture; +use std::borrow::{Borrow, BorrowMut}; use std::ops::{Deref, DerefMut}; use std::sync::Arc; use std::time::Instant; @@ -35,6 +36,24 @@ pub(super) struct Floating<'p, C> { const DEREF_ERR: &str = "(bug) connection already released to pool"; +impl Borrow for PoolConnection +where + C: Connect, +{ + fn borrow(&self) -> &C { + &*self + } +} + +impl BorrowMut for PoolConnection +where + C: Connect, +{ + fn borrow_mut(&mut self) -> &mut C { + &mut *self + } +} + impl Deref for PoolConnection where C: Connect, diff --git a/sqlx-core/src/pool/executor.rs b/sqlx-core/src/pool/executor.rs index 705953afd..5904eeb1f 100644 --- a/sqlx-core/src/pool/executor.rs +++ b/sqlx-core/src/pool/executor.rs @@ -17,7 +17,10 @@ where { type Database = DB; - fn execute<'e, 'q, E: 'e>(&'e mut self, query: E) -> BoxFuture<'e, crate::Result> + fn execute<'e, 'q: 'e, 'c: 'e, E: 'e>( + &'c mut self, + query: E, + ) -> BoxFuture<'e, crate::Result> where E: Execute<'q, Self::Database>, { @@ -65,7 +68,10 @@ where { type Database = C::Database; - fn execute<'e, 'q, E: 'e>(&'e mut self, query: E) -> BoxFuture<'e, crate::Result> + fn execute<'e, 'q: 'e, 'c: 'e, E: 'e>( + &'c mut self, + query: E, + ) -> BoxFuture<'e, crate::Result> where E: Execute<'q, Self::Database>, { diff --git a/sqlx-core/src/postgres/cursor.rs b/sqlx-core/src/postgres/cursor.rs index fcfe11304..e1a91b868 100644 --- a/sqlx-core/src/postgres/cursor.rs +++ b/sqlx-core/src/postgres/cursor.rs @@ -3,7 +3,7 @@ use std::sync::Arc; use futures_core::future::BoxFuture; -use crate::connection::{ConnectionSource, MaybeOwnedConnection}; +use crate::connection::ConnectionSource; use crate::cursor::Cursor; use crate::executor::Execute; use crate::pool::Pool; @@ -22,7 +22,6 @@ pub struct PgCursor<'c, 'q> { impl<'c, 'q> Cursor<'c, 'q> for PgCursor<'c, 'q> { type Database = Postgres; - #[doc(hidden)] fn from_pool(pool: &Pool, query: E) -> Self where Self: Sized, @@ -36,11 +35,9 @@ impl<'c, 'q> Cursor<'c, 'q> for PgCursor<'c, 'q> { } } - #[doc(hidden)] - fn from_connection(conn: C, query: E) -> Self + fn from_connection(conn: &'c mut PgConnection, query: E) -> Self where Self: Sized, - C: Into>, E: Execute<'q, Postgres>, { Self { @@ -128,7 +125,7 @@ async fn get_or_describe( async fn next<'a, 'c: 'a, 'q: 'a>( cursor: &'a mut PgCursor<'c, 'q>, ) -> crate::Result>> { - let mut conn = cursor.source.resolve_by_ref().await?; + let mut conn = cursor.source.resolve().await?; // The first time [next] is called we need to actually execute our // contained query. We guard against this happening on _all_ next calls diff --git a/sqlx-core/src/postgres/executor.rs b/sqlx-core/src/postgres/executor.rs index d96e8f461..17c36f2e4 100644 --- a/sqlx-core/src/postgres/executor.rs +++ b/sqlx-core/src/postgres/executor.rs @@ -368,7 +368,10 @@ impl PgConnection { impl Executor for super::PgConnection { type Database = Postgres; - fn execute<'e, 'q, E: 'e>(&'e mut self, query: E) -> BoxFuture<'e, crate::Result> + fn execute<'e, 'q: 'e, 'c: 'e, E: 'e>( + &'c mut self, + query: E, + ) -> BoxFuture<'e, crate::Result> where E: Execute<'q, Self::Database>, { diff --git a/sqlx-core/src/url.rs b/sqlx-core/src/url.rs index ac4ff2805..cc4a2d6da 100644 --- a/sqlx-core/src/url.rs +++ b/sqlx-core/src/url.rs @@ -29,6 +29,7 @@ impl<'s> TryFrom<&'s String> for Url { } impl Url { + #[allow(dead_code)] pub(crate) fn as_str(&self) -> &str { self.0.as_str() }