mirror of
https://github.com/launchbadge/sqlx
synced 2024-11-10 14:34:19 +00:00
fix: tweak lifetimes in Executor to limit the scope for the borrow on the query to the single execution
This commit is contained in:
parent
cc9d443434
commit
bb3b571a57
9 changed files with 227 additions and 183 deletions
|
@ -28,8 +28,9 @@ pub trait Executor<'c>: Send + Debug + Sized {
|
|||
type Database: Database;
|
||||
|
||||
/// Execute the query and return the total number of rows affected.
|
||||
fn execute<'q: 'c, E: 'c>(self, query: E) -> BoxFuture<'c, Result<u64, Error>>
|
||||
fn execute<'e, 'q: 'e, E: 'q>(self, query: E) -> BoxFuture<'e, Result<u64, Error>>
|
||||
where
|
||||
'c: 'e,
|
||||
E: Execute<'q, Self::Database>,
|
||||
{
|
||||
self.execute_many(query)
|
||||
|
@ -38,8 +39,9 @@ pub trait Executor<'c>: Send + Debug + Sized {
|
|||
}
|
||||
|
||||
/// Execute multiple queries and return the rows affected from each query, in a stream.
|
||||
fn execute_many<'q: 'c, E: 'c>(self, query: E) -> BoxStream<'c, Result<u64, Error>>
|
||||
fn execute_many<'e, 'q: 'e, E: 'q>(self, query: E) -> BoxStream<'e, Result<u64, Error>>
|
||||
where
|
||||
'c: 'e,
|
||||
E: Execute<'q, Self::Database>,
|
||||
{
|
||||
self.fetch_many(query)
|
||||
|
@ -53,11 +55,12 @@ pub trait Executor<'c>: Send + Debug + Sized {
|
|||
}
|
||||
|
||||
/// Execute the query and return the generated results as a stream.
|
||||
fn fetch<'q: 'c, E: 'c>(
|
||||
fn fetch<'e, 'q: 'e, E: 'q>(
|
||||
self,
|
||||
query: E,
|
||||
) -> BoxStream<'c, Result<<Self::Database as Database>::Row, Error>>
|
||||
) -> BoxStream<'e, Result<<Self::Database as Database>::Row, Error>>
|
||||
where
|
||||
'c: 'e,
|
||||
E: Execute<'q, Self::Database>,
|
||||
{
|
||||
self.fetch_many(query)
|
||||
|
@ -72,30 +75,33 @@ pub trait Executor<'c>: Send + Debug + Sized {
|
|||
|
||||
/// Execute multiple queries and return the generated results as a stream
|
||||
/// from each query, in a stream.
|
||||
fn fetch_many<'q: 'c, E: 'c>(
|
||||
fn fetch_many<'e, 'q: 'e, E: 'q>(
|
||||
self,
|
||||
query: E,
|
||||
) -> BoxStream<'c, Result<Either<u64, <Self::Database as Database>::Row>, Error>>
|
||||
) -> BoxStream<'e, Result<Either<u64, <Self::Database as Database>::Row>, Error>>
|
||||
where
|
||||
'c: 'e,
|
||||
E: Execute<'q, Self::Database>;
|
||||
|
||||
/// Execute the query and return all the generated results, collected into a [`Vec`].
|
||||
fn fetch_all<'q: 'c, E: 'c>(
|
||||
fn fetch_all<'e, 'q: 'e, E: 'q>(
|
||||
self,
|
||||
query: E,
|
||||
) -> BoxFuture<'c, Result<Vec<<Self::Database as Database>::Row>, Error>>
|
||||
) -> BoxFuture<'e, Result<Vec<<Self::Database as Database>::Row>, Error>>
|
||||
where
|
||||
'c: 'e,
|
||||
E: Execute<'q, Self::Database>,
|
||||
{
|
||||
self.fetch(query).try_collect().boxed()
|
||||
}
|
||||
|
||||
/// Execute the query and returns exactly one row.
|
||||
fn fetch_one<'q: 'c, E: 'c>(
|
||||
fn fetch_one<'e, 'q: 'e, E: 'q>(
|
||||
self,
|
||||
query: E,
|
||||
) -> BoxFuture<'c, Result<<Self::Database as Database>::Row, Error>>
|
||||
) -> BoxFuture<'e, Result<<Self::Database as Database>::Row, Error>>
|
||||
where
|
||||
'c: 'e,
|
||||
E: Execute<'q, Self::Database>,
|
||||
{
|
||||
self.fetch_optional(query)
|
||||
|
@ -107,11 +113,12 @@ pub trait Executor<'c>: Send + Debug + Sized {
|
|||
}
|
||||
|
||||
/// Execute the query and returns at most one row.
|
||||
fn fetch_optional<'q: 'c, E: 'c>(
|
||||
fn fetch_optional<'e, 'q: 'e, E: 'q>(
|
||||
self,
|
||||
query: E,
|
||||
) -> BoxFuture<'c, Result<Option<<Self::Database as Database>::Row>, Error>>
|
||||
) -> BoxFuture<'e, Result<Option<<Self::Database as Database>::Row>, Error>>
|
||||
where
|
||||
'c: 'e,
|
||||
E: Execute<'q, Self::Database>;
|
||||
|
||||
/// Prepare the SQL query and return type information about its parameters
|
||||
|
@ -120,11 +127,12 @@ pub trait Executor<'c>: Send + Debug + Sized {
|
|||
/// This is used by compile-time verification in the query macros to
|
||||
/// power their type inference.
|
||||
#[doc(hidden)]
|
||||
fn describe<'q: 'c, E: 'c>(
|
||||
fn describe<'e, 'q: 'e, E: 'q>(
|
||||
self,
|
||||
query: E,
|
||||
) -> BoxFuture<'c, Result<Describe<Self::Database>, Error>>
|
||||
) -> BoxFuture<'e, Result<Describe<Self::Database>, Error>>
|
||||
where
|
||||
'c: 'e,
|
||||
E: Execute<'q, Self::Database>;
|
||||
}
|
||||
|
||||
|
|
|
@ -198,11 +198,12 @@ impl MySqlConnection {
|
|||
impl<'c> Executor<'c> for &'c mut MySqlConnection {
|
||||
type Database = MySql;
|
||||
|
||||
fn fetch_many<'q: 'c, E: 'c>(
|
||||
fn fetch_many<'e, 'q: 'e, E: 'q>(
|
||||
self,
|
||||
mut query: E,
|
||||
) -> BoxStream<'c, Result<Either<u64, MySqlRow>, Error>>
|
||||
) -> BoxStream<'e, Result<Either<u64, MySqlRow>, Error>>
|
||||
where
|
||||
'c: 'e,
|
||||
E: Execute<'q, Self::Database>,
|
||||
{
|
||||
let s = query.query();
|
||||
|
@ -218,11 +219,12 @@ impl<'c> Executor<'c> for &'c mut MySqlConnection {
|
|||
})
|
||||
}
|
||||
|
||||
fn fetch_optional<'q: 'c, E: 'c>(
|
||||
fn fetch_optional<'e, 'q: 'e, E: 'q>(
|
||||
self,
|
||||
query: E,
|
||||
) -> BoxFuture<'c, Result<Option<MySqlRow>, Error>>
|
||||
) -> BoxFuture<'e, Result<Option<MySqlRow>, Error>>
|
||||
where
|
||||
'c: 'e,
|
||||
E: Execute<'q, Self::Database>,
|
||||
{
|
||||
let mut s = self.fetch_many(query);
|
||||
|
@ -239,8 +241,9 @@ impl<'c> Executor<'c> for &'c mut MySqlConnection {
|
|||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
fn describe<'q: 'c, E: 'c>(self, query: E) -> BoxFuture<'c, Result<Describe<MySql>, Error>>
|
||||
fn describe<'e, 'q: 'e, E: 'q>(self, query: E) -> BoxFuture<'e, Result<Describe<MySql>, Error>>
|
||||
where
|
||||
'c: 'e,
|
||||
E: Execute<'q, Self::Database>,
|
||||
{
|
||||
let query = query.query();
|
||||
|
|
|
@ -11,22 +11,24 @@ use crate::error::Error;
|
|||
use crate::executor::{Execute, Executor};
|
||||
use crate::pool::Pool;
|
||||
|
||||
impl<'p, C> Executor<'p> for &'p Pool<C>
|
||||
impl<'p, C> Executor<'p> for &'_ Pool<C>
|
||||
where
|
||||
C: Connect,
|
||||
C: 'static + Connect,
|
||||
for<'c> &'c mut C: Executor<'c, Database = C::Database>,
|
||||
{
|
||||
type Database = C::Database;
|
||||
|
||||
fn fetch_many<'q, E: 'p>(
|
||||
fn fetch_many<'e, 'q: 'e, E: 'q>(
|
||||
self,
|
||||
query: E,
|
||||
) -> BoxStream<'p, Result<Either<u64, <Self::Database as Database>::Row>, Error>>
|
||||
) -> BoxStream<'e, Result<Either<u64, <Self::Database as Database>::Row>, Error>>
|
||||
where
|
||||
E: Execute<'q, Self::Database>,
|
||||
{
|
||||
let pool = self.clone();
|
||||
|
||||
Box::pin(try_stream! {
|
||||
let mut conn = self.acquire().await?;
|
||||
let mut conn = pool.acquire().await?;
|
||||
let mut s = conn.fetch_many(query);
|
||||
|
||||
for v in s.try_next().await? {
|
||||
|
@ -35,51 +37,61 @@ where
|
|||
})
|
||||
}
|
||||
|
||||
fn fetch_optional<'q, E: 'p>(
|
||||
fn fetch_optional<'e, 'q: 'e, E: 'q>(
|
||||
self,
|
||||
query: E,
|
||||
) -> BoxFuture<'p, Result<Option<<Self::Database as Database>::Row>, Error>>
|
||||
) -> BoxFuture<'e, Result<Option<<Self::Database as Database>::Row>, Error>>
|
||||
where
|
||||
E: Execute<'q, Self::Database>,
|
||||
{
|
||||
Box::pin(async move { self.acquire().await?.fetch_optional(query).await })
|
||||
let pool = self.clone();
|
||||
|
||||
Box::pin(async move { pool.acquire().await?.fetch_optional(query).await })
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
fn describe<'q, E: 'p>(self, query: E) -> BoxFuture<'p, Result<Describe<Self::Database>, Error>>
|
||||
fn describe<'e, 'q: 'e, E: 'q>(
|
||||
self,
|
||||
query: E,
|
||||
) -> BoxFuture<'e, Result<Describe<Self::Database>, Error>>
|
||||
where
|
||||
E: Execute<'q, Self::Database>,
|
||||
{
|
||||
Box::pin(async move { self.acquire().await?.describe(query).await })
|
||||
let pool = self.clone();
|
||||
|
||||
Box::pin(async move { pool.acquire().await?.describe(query).await })
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE: required due to lack of lazy normalization
|
||||
#[allow(unused_macros)]
|
||||
macro_rules! impl_executor_for_pool_connection {
|
||||
($DB:ident, $C:ident, $R:ident) => {
|
||||
impl<'c> crate::executor::Executor<'c> for &'c mut crate::pool::PoolConnection<$C> {
|
||||
type Database = $DB;
|
||||
|
||||
#[inline]
|
||||
fn fetch_many<'q: 'c, E: 'c>(
|
||||
fn fetch_many<'e, 'q: 'e, E: 'q>(
|
||||
self,
|
||||
query: E,
|
||||
) -> futures_core::stream::BoxStream<
|
||||
'c,
|
||||
'e,
|
||||
Result<either::Either<u64, $R>, crate::error::Error>,
|
||||
>
|
||||
where
|
||||
'c: 'e,
|
||||
E: crate::executor::Execute<'q, $DB>,
|
||||
{
|
||||
(&mut **self).fetch_many(query)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn fetch_optional<'q: 'c, E: 'c>(
|
||||
fn fetch_optional<'e, 'q: 'e, E: 'q>(
|
||||
self,
|
||||
query: E,
|
||||
) -> futures_core::future::BoxFuture<'c, Result<Option<$R>, crate::error::Error>>
|
||||
) -> futures_core::future::BoxFuture<'e, Result<Option<$R>, crate::error::Error>>
|
||||
where
|
||||
'c: 'e,
|
||||
E: crate::executor::Execute<'q, $DB>,
|
||||
{
|
||||
(&mut **self).fetch_optional(query)
|
||||
|
@ -87,14 +99,15 @@ macro_rules! impl_executor_for_pool_connection {
|
|||
|
||||
#[doc(hidden)]
|
||||
#[inline]
|
||||
fn describe<'q: 'c, E: 'c>(
|
||||
fn describe<'e, 'q: 'e, E: 'q>(
|
||||
self,
|
||||
query: E,
|
||||
) -> futures_core::future::BoxFuture<
|
||||
'c,
|
||||
'e,
|
||||
Result<crate::describe::Describe<$DB>, crate::error::Error>,
|
||||
>
|
||||
where
|
||||
'c: 'e,
|
||||
E: crate::executor::Execute<'q, $DB>,
|
||||
{
|
||||
(&mut **self).describe(query)
|
||||
|
|
|
@ -242,11 +242,12 @@ SELECT oid FROM pg_catalog.pg_type WHERE typname ILIKE $1
|
|||
impl<'c> Executor<'c> for &'c mut PgConnection {
|
||||
type Database = Postgres;
|
||||
|
||||
fn fetch_many<'q: 'c, E: 'c>(
|
||||
fn fetch_many<'e, 'q: 'e, E: 'q>(
|
||||
self,
|
||||
mut query: E,
|
||||
) -> BoxStream<'c, Result<Either<u64, PgRow>, Error>>
|
||||
) -> BoxStream<'e, Result<Either<u64, PgRow>, Error>>
|
||||
where
|
||||
'c: 'e,
|
||||
E: Execute<'q, Self::Database>,
|
||||
{
|
||||
let s = query.query();
|
||||
|
@ -262,11 +263,12 @@ impl<'c> Executor<'c> for &'c mut PgConnection {
|
|||
})
|
||||
}
|
||||
|
||||
fn fetch_optional<'q: 'c, E: 'c>(
|
||||
fn fetch_optional<'e, 'q: 'e, E: 'q>(
|
||||
self,
|
||||
mut query: E,
|
||||
) -> BoxFuture<'c, Result<Option<PgRow>, Error>>
|
||||
) -> BoxFuture<'e, Result<Option<PgRow>, Error>>
|
||||
where
|
||||
'c: 'e,
|
||||
E: Execute<'q, Self::Database>,
|
||||
{
|
||||
let s = query.query();
|
||||
|
@ -287,8 +289,12 @@ impl<'c> Executor<'c> for &'c mut PgConnection {
|
|||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
fn describe<'q: 'c, E: 'c>(self, query: E) -> BoxFuture<'c, Result<Describe<Postgres>, Error>>
|
||||
fn describe<'e, 'q: 'e, E: 'q>(
|
||||
self,
|
||||
query: E,
|
||||
) -> BoxFuture<'e, Result<Describe<Postgres>, Error>>
|
||||
where
|
||||
'c: 'e,
|
||||
E: Execute<'q, Self::Database>,
|
||||
{
|
||||
let s = query.query();
|
||||
|
|
|
@ -195,26 +195,35 @@ impl PgListener {
|
|||
impl<'c> Executor<'c> for &'c mut PgListener {
|
||||
type Database = Postgres;
|
||||
|
||||
fn fetch_many<'q: 'c, E: 'c>(self, query: E) -> BoxStream<'c, Result<Either<u64, PgRow>, Error>>
|
||||
fn fetch_many<'e, 'q: 'e, E: 'q>(
|
||||
self,
|
||||
query: E,
|
||||
) -> BoxStream<'e, Result<Either<u64, PgRow>, Error>>
|
||||
where
|
||||
'c: 'e,
|
||||
E: Execute<'q, Self::Database>,
|
||||
{
|
||||
self.connection().fetch_many(query)
|
||||
}
|
||||
|
||||
fn fetch_optional<'q: 'c, E: 'c>(self, query: E) -> BoxFuture<'c, Result<Option<PgRow>, Error>>
|
||||
fn fetch_optional<'e, 'q: 'e, E: 'q>(
|
||||
self,
|
||||
query: E,
|
||||
) -> BoxFuture<'e, Result<Option<PgRow>, Error>>
|
||||
where
|
||||
'c: 'e,
|
||||
E: Execute<'q, Self::Database>,
|
||||
{
|
||||
self.connection().fetch_optional(query)
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
fn describe<'q: 'c, E: 'c>(
|
||||
fn describe<'e, 'q: 'e, E: 'q>(
|
||||
self,
|
||||
query: E,
|
||||
) -> BoxFuture<'c, Result<Describe<Self::Database>, Error>>
|
||||
) -> BoxFuture<'e, Result<Describe<Self::Database>, Error>>
|
||||
where
|
||||
'c: 'e,
|
||||
E: Execute<'q, Self::Database>,
|
||||
{
|
||||
self.connection().describe(query)
|
||||
|
|
|
@ -2,9 +2,8 @@ use std::marker::PhantomData;
|
|||
|
||||
use async_stream::try_stream;
|
||||
use either::Either;
|
||||
use futures_core::future::BoxFuture;
|
||||
use futures_core::stream::BoxStream;
|
||||
use futures_util::{future, FutureExt, StreamExt, TryFutureExt, TryStreamExt};
|
||||
use futures_util::{future, StreamExt, TryFutureExt, TryStreamExt};
|
||||
|
||||
use crate::arguments::{Arguments, IntoArguments};
|
||||
use crate::database::{Database, HasArguments};
|
||||
|
@ -71,7 +70,7 @@ impl<'q, DB: Database> Query<'q, DB, <DB as HasArguments<'q>>::Arguments> {
|
|||
impl<'q, DB, A: Send> Query<'q, DB, A>
|
||||
where
|
||||
DB: Database,
|
||||
A: IntoArguments<'q, DB>,
|
||||
A: 'q + IntoArguments<'q, DB>,
|
||||
{
|
||||
/// Map each row in the result to another type.
|
||||
///
|
||||
|
@ -104,10 +103,10 @@ where
|
|||
|
||||
/// Execute the query and return the total number of rows affected.
|
||||
#[inline]
|
||||
pub async fn execute<'c, E>(self, executor: E) -> Result<u64, Error>
|
||||
pub async fn execute<'e, 'c: 'e, E>(self, executor: E) -> Result<u64, Error>
|
||||
where
|
||||
'q: 'c,
|
||||
A: 'c,
|
||||
'q: 'e,
|
||||
A: 'e,
|
||||
E: Executor<'c, Database = DB>,
|
||||
{
|
||||
executor.execute(self).await
|
||||
|
@ -115,10 +114,10 @@ where
|
|||
|
||||
/// Execute multiple queries and return the rows affected from each query, in a stream.
|
||||
#[inline]
|
||||
pub async fn execute_many<'c, E>(self, executor: E) -> BoxStream<'c, Result<u64, Error>>
|
||||
pub async fn execute_many<'e, 'c: 'e, E>(self, executor: E) -> BoxStream<'e, Result<u64, Error>>
|
||||
where
|
||||
'q: 'c,
|
||||
A: 'c,
|
||||
'q: 'e,
|
||||
A: 'e,
|
||||
E: Executor<'c, Database = DB>,
|
||||
{
|
||||
executor.execute_many(self)
|
||||
|
@ -126,10 +125,10 @@ where
|
|||
|
||||
/// Execute the query and return the generated results as a stream.
|
||||
#[inline]
|
||||
pub fn fetch<'c, E>(self, executor: E) -> BoxStream<'c, Result<DB::Row, Error>>
|
||||
pub fn fetch<'e, 'c: 'e, E>(self, executor: E) -> BoxStream<'e, Result<DB::Row, Error>>
|
||||
where
|
||||
'q: 'c,
|
||||
A: 'c,
|
||||
'q: 'e,
|
||||
A: 'e,
|
||||
E: Executor<'c, Database = DB>,
|
||||
{
|
||||
executor.fetch(self)
|
||||
|
@ -138,13 +137,13 @@ where
|
|||
/// Execute multiple queries and return the generated results as a stream
|
||||
/// from each query, in a stream.
|
||||
#[inline]
|
||||
pub fn fetch_many<'c, E>(
|
||||
pub fn fetch_many<'e, 'c: 'e, E>(
|
||||
self,
|
||||
executor: E,
|
||||
) -> BoxStream<'c, Result<Either<u64, DB::Row>, Error>>
|
||||
) -> BoxStream<'e, Result<Either<u64, DB::Row>, Error>>
|
||||
where
|
||||
'q: 'c,
|
||||
A: 'c,
|
||||
'q: 'e,
|
||||
A: 'e,
|
||||
E: Executor<'c, Database = DB>,
|
||||
{
|
||||
executor.fetch_many(self)
|
||||
|
@ -152,10 +151,10 @@ where
|
|||
|
||||
/// Execute the query and return all the generated results, collected into a [`Vec`].
|
||||
#[inline]
|
||||
pub async fn fetch_all<'c, E>(self, executor: E) -> Result<Vec<DB::Row>, Error>
|
||||
pub async fn fetch_all<'e, 'c: 'e, E>(self, executor: E) -> Result<Vec<DB::Row>, Error>
|
||||
where
|
||||
'q: 'c,
|
||||
A: 'c,
|
||||
'q: 'e,
|
||||
A: 'e,
|
||||
E: Executor<'c, Database = DB>,
|
||||
{
|
||||
executor.fetch_all(self).await
|
||||
|
@ -163,10 +162,10 @@ where
|
|||
|
||||
/// Execute the query and returns exactly one row.
|
||||
#[inline]
|
||||
pub async fn fetch_one<'c, E>(self, executor: E) -> Result<DB::Row, Error>
|
||||
pub async fn fetch_one<'e, 'c: 'e, E>(self, executor: E) -> Result<DB::Row, Error>
|
||||
where
|
||||
'q: 'c,
|
||||
A: 'c,
|
||||
'q: 'e,
|
||||
A: 'e,
|
||||
E: Executor<'c, Database = DB>,
|
||||
{
|
||||
executor.fetch_one(self).await
|
||||
|
@ -174,10 +173,10 @@ where
|
|||
|
||||
/// Execute the query and returns at most one row.
|
||||
#[inline]
|
||||
pub async fn fetch_optional<'c, E>(self, executor: E) -> Result<Option<DB::Row>, Error>
|
||||
pub async fn fetch_optional<'e, 'c: 'e, E>(self, executor: E) -> Result<Option<DB::Row>, Error>
|
||||
where
|
||||
'q: 'c,
|
||||
A: 'c,
|
||||
'q: 'e,
|
||||
A: 'e,
|
||||
E: Executor<'c, Database = DB>,
|
||||
{
|
||||
executor.fetch_optional(self).await
|
||||
|
@ -207,16 +206,14 @@ where
|
|||
O: Send + Unpin,
|
||||
A: 'q + Send + IntoArguments<'q, DB>,
|
||||
{
|
||||
// FIXME: This is very close 1:1 with [`Executor::fetch`]
|
||||
// noinspection DuplicatedCode
|
||||
/// Execute the query and return the generated results as a stream.
|
||||
pub fn fetch<'c, E>(self, executor: E) -> BoxStream<'c, Result<O, Error>>
|
||||
pub fn fetch<'e, 'c: 'e, E>(self, executor: E) -> BoxStream<'e, Result<O, Error>>
|
||||
where
|
||||
'q: 'c,
|
||||
E: 'c + Executor<'c, Database = DB>,
|
||||
DB: 'c,
|
||||
F: 'c,
|
||||
O: 'c,
|
||||
'q: 'e,
|
||||
E: 'e + Executor<'c, Database = DB>,
|
||||
DB: 'e,
|
||||
F: 'e,
|
||||
O: 'e,
|
||||
{
|
||||
self.fetch_many(executor)
|
||||
.try_filter_map(|step| async move {
|
||||
|
@ -230,13 +227,16 @@ where
|
|||
|
||||
/// Execute multiple queries and return the generated results as a stream
|
||||
/// from each query, in a stream.
|
||||
pub fn fetch_many<'c, E>(self, executor: E) -> BoxStream<'c, Result<Either<u64, O>, Error>>
|
||||
pub fn fetch_many<'e, 'c: 'e, E>(
|
||||
self,
|
||||
executor: E,
|
||||
) -> BoxStream<'e, Result<Either<u64, O>, Error>>
|
||||
where
|
||||
'q: 'c,
|
||||
E: 'c + Executor<'c, Database = DB>,
|
||||
DB: 'c,
|
||||
F: 'c,
|
||||
O: 'c,
|
||||
'q: 'e,
|
||||
E: 'e + Executor<'c, Database = DB>,
|
||||
DB: 'e,
|
||||
F: 'e,
|
||||
O: 'e,
|
||||
{
|
||||
Box::pin(try_stream! {
|
||||
let mut s = executor.fetch_many(self.inner);
|
||||
|
@ -253,54 +253,50 @@ where
|
|||
}
|
||||
|
||||
/// Execute the query and return all the generated results, collected into a [`Vec`].
|
||||
#[inline]
|
||||
pub fn fetch_all<'c, E>(self, executor: E) -> BoxFuture<'c, Result<Vec<O>, Error>>
|
||||
pub async fn fetch_all<'e, 'c: 'e, E>(self, executor: E) -> Result<Vec<O>, Error>
|
||||
where
|
||||
'q: 'c,
|
||||
E: 'c + Executor<'c, Database = DB>,
|
||||
DB: 'c,
|
||||
F: 'c,
|
||||
O: 'c,
|
||||
'q: 'e,
|
||||
E: 'e + Executor<'c, Database = DB>,
|
||||
DB: 'e,
|
||||
F: 'e,
|
||||
O: 'e,
|
||||
{
|
||||
self.fetch(executor).try_collect().boxed()
|
||||
self.fetch(executor).try_collect().await
|
||||
}
|
||||
|
||||
// FIXME: This is very close 1:1 with [`Executor::fetch_one`]
|
||||
// noinspection DuplicatedCode
|
||||
/// Execute the query and returns exactly one row.
|
||||
pub fn fetch_one<'c, E>(self, executor: E) -> BoxFuture<'c, Result<O, Error>>
|
||||
pub async fn fetch_one<'e, 'c: 'e, E>(self, executor: E) -> Result<O, Error>
|
||||
where
|
||||
'q: 'c,
|
||||
E: 'c + Executor<'c, Database = DB>,
|
||||
DB: 'c,
|
||||
F: 'c,
|
||||
O: 'c,
|
||||
'q: 'e,
|
||||
E: 'e + Executor<'c, Database = DB>,
|
||||
DB: 'e,
|
||||
F: 'e,
|
||||
O: 'e,
|
||||
{
|
||||
self.fetch_optional(executor)
|
||||
.and_then(|row| match row {
|
||||
Some(row) => future::ok(row),
|
||||
None => future::err(Error::RowNotFound),
|
||||
})
|
||||
.boxed()
|
||||
.await
|
||||
}
|
||||
|
||||
/// Execute the query and returns at most one row.
|
||||
pub fn fetch_optional<'c, E>(self, executor: E) -> BoxFuture<'c, Result<Option<O>, Error>>
|
||||
pub async fn fetch_optional<'e, 'c: 'e, E>(self, executor: E) -> Result<Option<O>, Error>
|
||||
where
|
||||
'q: 'c,
|
||||
E: 'c + Executor<'c, Database = DB>,
|
||||
DB: 'c,
|
||||
F: 'c,
|
||||
O: 'c,
|
||||
'q: 'e,
|
||||
E: 'e + Executor<'c, Database = DB>,
|
||||
DB: 'e,
|
||||
F: 'e,
|
||||
O: 'e,
|
||||
{
|
||||
Box::pin(async move {
|
||||
let row = executor.fetch_optional(self.inner).await?;
|
||||
|
||||
if let Some(row) = row {
|
||||
(self.mapper)(row).map(Some)
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ pub struct QueryAs<'q, DB: Database, O, A> {
|
|||
impl<'q, DB, O: Send, A: Send> Execute<'q, DB> for QueryAs<'q, DB, O, A>
|
||||
where
|
||||
DB: Database,
|
||||
A: IntoArguments<'q, DB>,
|
||||
A: 'q + IntoArguments<'q, DB>,
|
||||
{
|
||||
#[inline]
|
||||
fn query(&self) -> &'q str {
|
||||
|
@ -52,17 +52,17 @@ impl<'q, DB: Database, O> QueryAs<'q, DB, O, <DB as HasArguments<'q>>::Arguments
|
|||
impl<'q, DB, O, A> QueryAs<'q, DB, O, A>
|
||||
where
|
||||
DB: Database,
|
||||
A: IntoArguments<'q, DB>,
|
||||
A: 'q + IntoArguments<'q, DB>,
|
||||
O: Send + Unpin + for<'r> FromRow<'r, DB::Row>,
|
||||
{
|
||||
/// Execute the query and return the generated results as a stream.
|
||||
pub fn fetch<'c, E>(self, executor: E) -> BoxStream<'c, Result<O, Error>>
|
||||
pub fn fetch<'e, 'c: 'e, E>(self, executor: E) -> BoxStream<'e, Result<O, Error>>
|
||||
where
|
||||
'q: 'c,
|
||||
E: 'c + Executor<'c, Database = DB>,
|
||||
DB: 'c,
|
||||
O: 'c,
|
||||
A: 'c,
|
||||
'q: 'e,
|
||||
E: 'e + Executor<'c, Database = DB>,
|
||||
DB: 'e,
|
||||
O: 'e,
|
||||
A: 'e,
|
||||
{
|
||||
self.fetch_many(executor)
|
||||
.try_filter_map(|step| async move { Ok(step.right()) })
|
||||
|
@ -71,13 +71,16 @@ where
|
|||
|
||||
/// Execute multiple queries and return the generated results as a stream
|
||||
/// from each query, in a stream.
|
||||
pub fn fetch_many<'c, E>(self, executor: E) -> BoxStream<'c, Result<Either<u64, O>, Error>>
|
||||
pub fn fetch_many<'e, 'c: 'e, E>(
|
||||
self,
|
||||
executor: E,
|
||||
) -> BoxStream<'e, Result<Either<u64, O>, Error>>
|
||||
where
|
||||
'q: 'c,
|
||||
E: 'c + Executor<'c, Database = DB>,
|
||||
DB: 'c,
|
||||
O: 'c,
|
||||
A: 'c,
|
||||
'q: 'e,
|
||||
E: 'e + Executor<'c, Database = DB>,
|
||||
DB: 'e,
|
||||
O: 'e,
|
||||
A: 'e,
|
||||
{
|
||||
Box::pin(try_stream! {
|
||||
let mut s = executor.fetch_many(self.inner);
|
||||
|
@ -95,25 +98,25 @@ where
|
|||
|
||||
/// Execute the query and return all the generated results, collected into a [`Vec`].
|
||||
#[inline]
|
||||
pub async fn fetch_all<'c, E>(self, executor: E) -> Result<Vec<O>, Error>
|
||||
pub async fn fetch_all<'e, 'c: 'e, E>(self, executor: E) -> Result<Vec<O>, Error>
|
||||
where
|
||||
'q: 'c,
|
||||
E: 'c + Executor<'c, Database = DB>,
|
||||
DB: 'c,
|
||||
A: 'c,
|
||||
O: 'c,
|
||||
'q: 'e,
|
||||
E: 'e + Executor<'c, Database = DB>,
|
||||
DB: 'e,
|
||||
O: 'e,
|
||||
A: 'e,
|
||||
{
|
||||
self.fetch(executor).try_collect().await
|
||||
}
|
||||
|
||||
/// Execute the query and returns exactly one row.
|
||||
pub async fn fetch_one<'c, E>(self, executor: E) -> Result<O, Error>
|
||||
pub async fn fetch_one<'e, 'c: 'e, E>(self, executor: E) -> Result<O, Error>
|
||||
where
|
||||
'q: 'c,
|
||||
E: 'c + Executor<'c, Database = DB>,
|
||||
DB: 'c,
|
||||
O: 'c,
|
||||
A: 'c,
|
||||
'q: 'e,
|
||||
E: 'e + Executor<'c, Database = DB>,
|
||||
DB: 'e,
|
||||
O: 'e,
|
||||
A: 'e,
|
||||
{
|
||||
self.fetch_optional(executor)
|
||||
.await
|
||||
|
@ -121,13 +124,13 @@ where
|
|||
}
|
||||
|
||||
/// Execute the query and returns at most one row.
|
||||
pub async fn fetch_optional<'c, E>(self, executor: E) -> Result<Option<O>, Error>
|
||||
pub async fn fetch_optional<'e, 'c: 'e, E>(self, executor: E) -> Result<Option<O>, Error>
|
||||
where
|
||||
'q: 'c,
|
||||
E: 'c + Executor<'c, Database = DB>,
|
||||
DB: 'c,
|
||||
O: 'c,
|
||||
A: 'c,
|
||||
'q: 'e,
|
||||
E: 'e + Executor<'c, Database = DB>,
|
||||
DB: 'e,
|
||||
O: 'e,
|
||||
A: 'e,
|
||||
{
|
||||
let row = executor.fetch_optional(self.inner).await?;
|
||||
if let Some(row) = row {
|
||||
|
|
|
@ -19,7 +19,7 @@ pub struct QueryScalar<'q, DB: Database, O, A> {
|
|||
|
||||
impl<'q, DB: Database, O: Send, A: Send> Execute<'q, DB> for QueryScalar<'q, DB, O, A>
|
||||
where
|
||||
A: IntoArguments<'q, DB>,
|
||||
A: 'q + IntoArguments<'q, DB>,
|
||||
{
|
||||
#[inline]
|
||||
fn query(&self) -> &'q str {
|
||||
|
@ -48,18 +48,18 @@ impl<'q, DB, O, A> QueryScalar<'q, DB, O, A>
|
|||
where
|
||||
DB: Database,
|
||||
O: Send + Unpin,
|
||||
A: IntoArguments<'q, DB>,
|
||||
A: 'q + IntoArguments<'q, DB>,
|
||||
(O,): Send + Unpin + for<'r> FromRow<'r, DB::Row>,
|
||||
{
|
||||
/// Execute the query and return the generated results as a stream.
|
||||
#[inline]
|
||||
pub fn fetch<'c, E>(self, executor: E) -> BoxStream<'c, Result<O, Error>>
|
||||
pub fn fetch<'e, 'c: 'e, E>(self, executor: E) -> BoxStream<'e, Result<O, Error>>
|
||||
where
|
||||
'q: 'c,
|
||||
E: 'c + Executor<'c, Database = DB>,
|
||||
DB: 'c,
|
||||
A: 'c,
|
||||
O: 'c,
|
||||
'q: 'e,
|
||||
E: 'e + Executor<'c, Database = DB>,
|
||||
DB: 'e,
|
||||
A: 'e,
|
||||
O: 'e,
|
||||
{
|
||||
self.inner.fetch(executor).map_ok(|it| it.0).boxed()
|
||||
}
|
||||
|
@ -67,13 +67,16 @@ where
|
|||
/// Execute multiple queries and return the generated results as a stream
|
||||
/// from each query, in a stream.
|
||||
#[inline]
|
||||
pub fn fetch_many<'c, E>(self, executor: E) -> BoxStream<'c, Result<Either<u64, O>, Error>>
|
||||
pub fn fetch_many<'e, 'c: 'e, E>(
|
||||
self,
|
||||
executor: E,
|
||||
) -> BoxStream<'e, Result<Either<u64, O>, Error>>
|
||||
where
|
||||
'q: 'c,
|
||||
E: 'c + Executor<'c, Database = DB>,
|
||||
DB: 'c,
|
||||
O: 'c,
|
||||
A: 'c,
|
||||
'q: 'e,
|
||||
E: 'e + Executor<'c, Database = DB>,
|
||||
DB: 'e,
|
||||
A: 'e,
|
||||
O: 'e,
|
||||
{
|
||||
self.inner
|
||||
.fetch_many(executor)
|
||||
|
@ -83,13 +86,13 @@ where
|
|||
|
||||
/// Execute the query and return all the generated results, collected into a [`Vec`].
|
||||
#[inline]
|
||||
pub async fn fetch_all<'c, E>(self, executor: E) -> Result<Vec<O>, Error>
|
||||
pub async fn fetch_all<'e, 'c: 'e, E>(self, executor: E) -> Result<Vec<O>, Error>
|
||||
where
|
||||
'q: 'c,
|
||||
E: 'c + Executor<'c, Database = DB>,
|
||||
DB: 'c,
|
||||
(O,): 'c,
|
||||
A: 'c,
|
||||
'q: 'e,
|
||||
E: 'e + Executor<'c, Database = DB>,
|
||||
DB: 'e,
|
||||
(O,): 'e,
|
||||
A: 'e,
|
||||
{
|
||||
self.inner
|
||||
.fetch(executor)
|
||||
|
@ -100,26 +103,26 @@ where
|
|||
|
||||
/// Execute the query and returns exactly one row.
|
||||
#[inline]
|
||||
pub async fn fetch_one<'c, E>(self, executor: E) -> Result<O, Error>
|
||||
pub async fn fetch_one<'e, 'c: 'e, E>(self, executor: E) -> Result<O, Error>
|
||||
where
|
||||
'q: 'c,
|
||||
E: 'c + Executor<'c, Database = DB>,
|
||||
DB: 'c,
|
||||
O: 'c,
|
||||
A: 'c,
|
||||
'q: 'e,
|
||||
E: 'e + Executor<'c, Database = DB>,
|
||||
DB: 'e,
|
||||
O: 'e,
|
||||
A: 'e,
|
||||
{
|
||||
self.inner.fetch_one(executor).map_ok(|it| it.0).await
|
||||
}
|
||||
|
||||
/// Execute the query and returns at most one row.
|
||||
#[inline]
|
||||
pub async fn fetch_optional<'c, E>(self, executor: E) -> Result<Option<O>, Error>
|
||||
pub async fn fetch_optional<'e, 'c: 'e, E>(self, executor: E) -> Result<Option<O>, Error>
|
||||
where
|
||||
'q: 'c,
|
||||
E: 'c + Executor<'c, Database = DB>,
|
||||
DB: 'c,
|
||||
O: 'c,
|
||||
A: 'c,
|
||||
'q: 'e,
|
||||
E: 'e + Executor<'c, Database = DB>,
|
||||
DB: 'e,
|
||||
O: 'e,
|
||||
A: 'e,
|
||||
{
|
||||
Ok(self.inner.fetch_optional(executor).await?.map(|it| it.0))
|
||||
}
|
||||
|
|
|
@ -74,11 +74,12 @@ fn emplace_row_metadata(
|
|||
impl<'c> Executor<'c> for &'c mut SqliteConnection {
|
||||
type Database = Sqlite;
|
||||
|
||||
fn fetch_many<'q: 'c, E: 'c>(
|
||||
fn fetch_many<'e, 'q: 'e, E: 'q>(
|
||||
self,
|
||||
mut query: E,
|
||||
) -> BoxStream<'c, Result<Either<u64, SqliteRow>, Error>>
|
||||
) -> BoxStream<'e, Result<Either<u64, SqliteRow>, Error>>
|
||||
where
|
||||
'c: 'e,
|
||||
E: Execute<'q, Self::Database>,
|
||||
{
|
||||
let s = query.query();
|
||||
|
@ -148,11 +149,12 @@ impl<'c> Executor<'c> for &'c mut SqliteConnection {
|
|||
})
|
||||
}
|
||||
|
||||
fn fetch_optional<'q: 'c, E: 'c>(
|
||||
fn fetch_optional<'e, 'q: 'e, E: 'q>(
|
||||
self,
|
||||
query: E,
|
||||
) -> BoxFuture<'c, Result<Option<SqliteRow>, Error>>
|
||||
) -> BoxFuture<'e, Result<Option<SqliteRow>, Error>>
|
||||
where
|
||||
'c: 'e,
|
||||
E: Execute<'q, Self::Database>,
|
||||
{
|
||||
let mut s = self.fetch_many(query);
|
||||
|
@ -169,8 +171,9 @@ impl<'c> Executor<'c> for &'c mut SqliteConnection {
|
|||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
fn describe<'q: 'c, E: 'c>(self, query: E) -> BoxFuture<'c, Result<Describe<Sqlite>, Error>>
|
||||
fn describe<'e, 'q: 'e, E: 'q>(self, query: E) -> BoxFuture<'e, Result<Describe<Sqlite>, Error>>
|
||||
where
|
||||
'c: 'e,
|
||||
E: Execute<'q, Self::Database>,
|
||||
{
|
||||
let query = query.query();
|
||||
|
|
Loading…
Reference in a new issue