typed_sql/
fetch.rs

1use crate::query::select::{SelectStatement, Selectable, WildCard};
2use crate::{CheckedSql, ToSql};
3use sqlx::{Database, Error, Executor, FromRow};
4use std::future::Future;
5use std::pin::Pin;
6
7pub trait Fetch<'c, 'out, E>: ToSql + CheckedSql
8where
9    E: Executor<'c> + 'out,
10{
11    type Output: for<'r> FromRow<'r, <E::Database as Database>::Row>;
12
13    fn fetch_one(
14        &self,
15        exec: E,
16    ) -> Pin<Box<dyn Future<Output = Result<Self::Output, Error>> + Send + 'out>> {
17        let sql = self.to_sql();
18        Box::pin(async move {
19            exec.fetch_one(sql.as_ref())
20                .await
21                .and_then(|row| FromRow::from_row(&row))
22        })
23    }
24
25    fn fetch_optional(
26        &self,
27        exec: E,
28    ) -> Pin<Box<dyn Future<Output = Result<Option<Self::Output>, Error>> + Send + 'out>> {
29        let sql = self.to_sql();
30        Box::pin(async move {
31            exec.fetch_optional(sql.as_ref())
32                .await
33                .and_then(|row| row.as_ref().map(FromRow::from_row).transpose())
34        })
35    }
36}
37
38impl<'c, 'out, E, S> Fetch<'c, 'out, E> for SelectStatement<S, WildCard>
39where
40    E: Executor<'c> + 'out,
41    S: Selectable,
42    S::Table: for<'r> FromRow<'r, <E::Database as Database>::Row>,
43{
44    type Output = S::Table;
45}