mirror of
https://github.com/launchbadge/sqlx.git
synced 2025-10-02 15:25:32 +00:00
Integrate FromRow while maintaining type fallback for query!
This commit is contained in:
parent
ab32d0a5c4
commit
73ca673bf2
@ -1,4 +1,3 @@
|
|||||||
use futures::TryStreamExt;
|
|
||||||
use sqlx::{FromRow, Pool, Postgres};
|
use sqlx::{FromRow, Pool, Postgres};
|
||||||
use std::env;
|
use std::env;
|
||||||
use tide::error::ResultExt;
|
use tide::error::ResultExt;
|
||||||
@ -22,6 +21,8 @@ async fn main() -> anyhow::Result<()> {
|
|||||||
|
|
||||||
app.at("/v1/user/first").get(get_first_user);
|
app.at("/v1/user/first").get(get_first_user);
|
||||||
|
|
||||||
|
app.at("/v1/user/last").get(get_last_user);
|
||||||
|
|
||||||
app.serve(("localhost", 8080))?;
|
app.serve(("localhost", 8080))?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -47,19 +48,28 @@ async fn get_all_users(cx: Context<Pool<Postgres>>) -> EndpointResult {
|
|||||||
let mut pool = cx.state();
|
let mut pool = cx.state();
|
||||||
|
|
||||||
let users: Vec<(i32, String)> = sqlx::query(r#"SELECT id, name FROM users"#)
|
let users: Vec<(i32, String)> = sqlx::query(r#"SELECT id, name FROM users"#)
|
||||||
.fetch(&mut pool) // -> Stream<Row>
|
.fetch_all(&mut pool)
|
||||||
.map_ok(FromRow::from_row)
|
|
||||||
.try_collect()
|
|
||||||
.await
|
.await
|
||||||
.server_err()?;
|
.server_err()?;
|
||||||
|
|
||||||
Ok(response::json(users))
|
Ok(response::json(users))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: #[derive(FromRow)]
|
||||||
|
struct UserRow {
|
||||||
|
id: i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FromRow<Postgres, (i32,)> for UserRow {
|
||||||
|
fn from_row(row: sqlx::Row<Postgres>) -> Self {
|
||||||
|
Self { id: row.get(0) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async fn get_first_user(cx: Context<Pool<Postgres>>) -> EndpointResult {
|
async fn get_first_user(cx: Context<Pool<Postgres>>) -> EndpointResult {
|
||||||
let mut pool = cx.state();
|
let mut pool = cx.state();
|
||||||
|
|
||||||
let (user_id,) /* : (i32,) */ = sqlx::query!(
|
let row: UserRow = sqlx::query!(
|
||||||
r#"
|
r#"
|
||||||
SELECT id
|
SELECT id
|
||||||
FROM users
|
FROM users
|
||||||
@ -71,6 +81,24 @@ LIMIT 1
|
|||||||
.await
|
.await
|
||||||
.server_err()?;
|
.server_err()?;
|
||||||
|
|
||||||
|
Ok(response::json(vec![row.id]))
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn get_last_user(cx: Context<Pool<Postgres>>) -> EndpointResult {
|
||||||
|
let mut pool = cx.state();
|
||||||
|
|
||||||
|
let (user_id,) = sqlx::query!(
|
||||||
|
r#"
|
||||||
|
SELECT id
|
||||||
|
FROM users
|
||||||
|
ORDER BY created_at ASC
|
||||||
|
LIMIT 1
|
||||||
|
"#,
|
||||||
|
)
|
||||||
|
.fetch_one(&mut pool)
|
||||||
|
.await
|
||||||
|
.server_err()?;
|
||||||
|
|
||||||
Ok(response::json(vec![user_id]))
|
Ok(response::json(vec![user_id]))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,25 +53,25 @@ where
|
|||||||
{
|
{
|
||||||
type Backend = DB;
|
type Backend = DB;
|
||||||
|
|
||||||
fn execute<'c, 'q: 'c, A: 'c>(
|
fn execute<'c, 'q: 'c, I: 'c>(
|
||||||
&'c mut self,
|
&'c mut self,
|
||||||
query: &'q str,
|
query: &'q str,
|
||||||
params: A,
|
params: I,
|
||||||
) -> BoxFuture<'c, Result<u64, Error>>
|
) -> BoxFuture<'c, Result<u64, Error>>
|
||||||
where
|
where
|
||||||
A: IntoQueryParameters<Self::Backend> + Send,
|
I: IntoQueryParameters<Self::Backend> + Send,
|
||||||
{
|
{
|
||||||
Box::pin(async move { self.live.execute(query, params.into_params()).await })
|
Box::pin(async move { self.live.execute(query, params.into_params()).await })
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fetch<'c, 'q: 'c, T: 'c, A: 'c>(
|
fn fetch<'c, 'q: 'c, I: 'c, O: 'c, T: 'c>(
|
||||||
&'c mut self,
|
&'c mut self,
|
||||||
query: &'q str,
|
query: &'q str,
|
||||||
params: A,
|
params: I,
|
||||||
) -> BoxStream<'c, Result<T, Error>>
|
) -> BoxStream<'c, Result<T, Error>>
|
||||||
where
|
where
|
||||||
A: IntoQueryParameters<Self::Backend> + Send,
|
I: IntoQueryParameters<Self::Backend> + Send,
|
||||||
T: FromRow<Self::Backend> + Send + Unpin,
|
T: FromRow<Self::Backend, O> + Send + Unpin,
|
||||||
{
|
{
|
||||||
Box::pin(async_stream::try_stream! {
|
Box::pin(async_stream::try_stream! {
|
||||||
let mut s = self.live.fetch(query, params.into_params());
|
let mut s = self.live.fetch(query, params.into_params());
|
||||||
@ -82,14 +82,14 @@ where
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fetch_optional<'c, 'q: 'c, T: 'c, A: 'c>(
|
fn fetch_optional<'c, 'q: 'c, I: 'c, O: 'c, T: 'c>(
|
||||||
&'c mut self,
|
&'c mut self,
|
||||||
query: &'q str,
|
query: &'q str,
|
||||||
params: A,
|
params: I,
|
||||||
) -> BoxFuture<'c, Result<Option<T>, Error>>
|
) -> BoxFuture<'c, Result<Option<T>, Error>>
|
||||||
where
|
where
|
||||||
A: IntoQueryParameters<Self::Backend> + Send,
|
I: IntoQueryParameters<Self::Backend> + Send,
|
||||||
T: FromRow<Self::Backend>,
|
T: FromRow<Self::Backend, O>,
|
||||||
{
|
{
|
||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
let row = self
|
let row = self
|
||||||
|
@ -5,52 +5,52 @@ use futures_util::TryStreamExt;
|
|||||||
pub trait Executor: Send {
|
pub trait Executor: Send {
|
||||||
type Backend: Backend;
|
type Backend: Backend;
|
||||||
|
|
||||||
fn execute<'c, 'q: 'c, A: 'c>(
|
fn execute<'c, 'q: 'c, I: 'c>(
|
||||||
&'c mut self,
|
&'c mut self,
|
||||||
query: &'q str,
|
query: &'q str,
|
||||||
params: A,
|
params: I,
|
||||||
) -> BoxFuture<'c, Result<u64, Error>>
|
) -> BoxFuture<'c, Result<u64, Error>>
|
||||||
where
|
where
|
||||||
A: IntoQueryParameters<Self::Backend> + Send;
|
I: IntoQueryParameters<Self::Backend> + Send;
|
||||||
|
|
||||||
fn fetch<'c, 'q: 'c, T: 'c, A: 'c>(
|
fn fetch<'c, 'q: 'c, I: 'c, O: 'c, T: 'c>(
|
||||||
&'c mut self,
|
&'c mut self,
|
||||||
query: &'q str,
|
query: &'q str,
|
||||||
params: A,
|
params: I,
|
||||||
) -> BoxStream<'c, Result<T, Error>>
|
) -> BoxStream<'c, Result<T, Error>>
|
||||||
where
|
where
|
||||||
A: IntoQueryParameters<Self::Backend> + Send,
|
I: IntoQueryParameters<Self::Backend> + Send,
|
||||||
T: FromRow<Self::Backend> + Send + Unpin;
|
T: FromRow<Self::Backend, O> + Send + Unpin;
|
||||||
|
|
||||||
fn fetch_all<'c, 'q: 'c, T: 'c, A: 'c>(
|
fn fetch_all<'c, 'q: 'c, I: 'c, O: 'c, T: 'c>(
|
||||||
&'c mut self,
|
&'c mut self,
|
||||||
query: &'q str,
|
query: &'q str,
|
||||||
params: A,
|
params: I,
|
||||||
) -> BoxFuture<'c, Result<Vec<T>, Error>>
|
) -> BoxFuture<'c, Result<Vec<T>, Error>>
|
||||||
where
|
where
|
||||||
A: IntoQueryParameters<Self::Backend> + Send,
|
I: IntoQueryParameters<Self::Backend> + Send,
|
||||||
T: FromRow<Self::Backend> + Send + Unpin,
|
T: FromRow<Self::Backend, O> + Send + Unpin,
|
||||||
{
|
{
|
||||||
Box::pin(self.fetch(query, params).try_collect())
|
Box::pin(self.fetch(query, params).try_collect())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fetch_optional<'c, 'q: 'c, T: 'c, A: 'c>(
|
fn fetch_optional<'c, 'q: 'c, I: 'c, O: 'c, T: 'c>(
|
||||||
&'c mut self,
|
&'c mut self,
|
||||||
query: &'q str,
|
query: &'q str,
|
||||||
params: A,
|
params: I,
|
||||||
) -> BoxFuture<'c, Result<Option<T>, Error>>
|
) -> BoxFuture<'c, Result<Option<T>, Error>>
|
||||||
where
|
where
|
||||||
A: IntoQueryParameters<Self::Backend> + Send,
|
I: IntoQueryParameters<Self::Backend> + Send,
|
||||||
T: FromRow<Self::Backend> + Send;
|
T: FromRow<Self::Backend, O> + Send;
|
||||||
|
|
||||||
fn fetch_one<'c, 'q: 'c, T: 'c, A: 'c>(
|
fn fetch_one<'c, 'q: 'c, I: 'c, O: 'c, T: 'c>(
|
||||||
&'c mut self,
|
&'c mut self,
|
||||||
query: &'q str,
|
query: &'q str,
|
||||||
params: A,
|
params: I,
|
||||||
) -> BoxFuture<'c, Result<T, Error>>
|
) -> BoxFuture<'c, Result<T, Error>>
|
||||||
where
|
where
|
||||||
A: IntoQueryParameters<Self::Backend> + Send,
|
I: IntoQueryParameters<Self::Backend> + Send,
|
||||||
T: FromRow<Self::Backend> + Send,
|
T: FromRow<Self::Backend, O> + Send,
|
||||||
{
|
{
|
||||||
let fut = self.fetch_optional(query, params);
|
let fut = self.fetch_optional(query, params);
|
||||||
Box::pin(async move { fut.await?.ok_or(Error::NotFound) })
|
Box::pin(async move { fut.await?.ok_or(Error::NotFound) })
|
||||||
|
@ -244,25 +244,25 @@ where
|
|||||||
{
|
{
|
||||||
type Backend = DB;
|
type Backend = DB;
|
||||||
|
|
||||||
fn execute<'c, 'q: 'c, A: 'c>(
|
fn execute<'c, 'q: 'c, I: 'c>(
|
||||||
&'c mut self,
|
&'c mut self,
|
||||||
query: &'q str,
|
query: &'q str,
|
||||||
params: A,
|
params: I,
|
||||||
) -> BoxFuture<'c, Result<u64, Error>>
|
) -> BoxFuture<'c, Result<u64, Error>>
|
||||||
where
|
where
|
||||||
A: IntoQueryParameters<Self::Backend> + Send,
|
I: IntoQueryParameters<Self::Backend> + Send,
|
||||||
{
|
{
|
||||||
Box::pin(async move { <&Pool<DB> as Executor>::execute(&mut &*self, query, params).await })
|
Box::pin(async move { <&Pool<DB> as Executor>::execute(&mut &*self, query, params).await })
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fetch<'c, 'q: 'c, T: 'c, A: 'c>(
|
fn fetch<'c, 'q: 'c, I: 'c, O: 'c, T: 'c>(
|
||||||
&'c mut self,
|
&'c mut self,
|
||||||
query: &'q str,
|
query: &'q str,
|
||||||
params: A,
|
params: I,
|
||||||
) -> BoxStream<'c, Result<T, Error>>
|
) -> BoxStream<'c, Result<T, Error>>
|
||||||
where
|
where
|
||||||
A: IntoQueryParameters<Self::Backend> + Send,
|
I: IntoQueryParameters<Self::Backend> + Send,
|
||||||
T: FromRow<Self::Backend> + Send + Unpin,
|
T: FromRow<Self::Backend, O> + Send + Unpin,
|
||||||
{
|
{
|
||||||
Box::pin(async_stream::try_stream! {
|
Box::pin(async_stream::try_stream! {
|
||||||
let mut self_ = &*self;
|
let mut self_ = &*self;
|
||||||
@ -276,14 +276,14 @@ where
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fetch_optional<'c, 'q: 'c, T: 'c, A: 'c>(
|
fn fetch_optional<'c, 'q: 'c, I: 'c, O: 'c, T: 'c>(
|
||||||
&'c mut self,
|
&'c mut self,
|
||||||
query: &'q str,
|
query: &'q str,
|
||||||
params: A,
|
params: I,
|
||||||
) -> BoxFuture<'c, Result<Option<T>, Error>>
|
) -> BoxFuture<'c, Result<Option<T>, Error>>
|
||||||
where
|
where
|
||||||
A: IntoQueryParameters<Self::Backend> + Send,
|
I: IntoQueryParameters<Self::Backend> + Send,
|
||||||
T: FromRow<Self::Backend> + Send,
|
T: FromRow<Self::Backend, O> + Send,
|
||||||
{
|
{
|
||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
<&Pool<DB> as Executor>::fetch_optional(&mut &*self, query, params).await
|
<&Pool<DB> as Executor>::fetch_optional(&mut &*self, query, params).await
|
||||||
@ -297,13 +297,13 @@ where
|
|||||||
{
|
{
|
||||||
type Backend = DB;
|
type Backend = DB;
|
||||||
|
|
||||||
fn execute<'c, 'q: 'c, A: 'c>(
|
fn execute<'c, 'q: 'c, I: 'c>(
|
||||||
&'c mut self,
|
&'c mut self,
|
||||||
query: &'q str,
|
query: &'q str,
|
||||||
params: A,
|
params: I,
|
||||||
) -> BoxFuture<'c, Result<u64, Error>>
|
) -> BoxFuture<'c, Result<u64, Error>>
|
||||||
where
|
where
|
||||||
A: IntoQueryParameters<Self::Backend> + Send,
|
I: IntoQueryParameters<Self::Backend> + Send,
|
||||||
{
|
{
|
||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
let mut live = self.0.acquire().await?;
|
let mut live = self.0.acquire().await?;
|
||||||
@ -312,14 +312,14 @@ where
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fetch<'c, 'q: 'c, T: 'c, A: 'c>(
|
fn fetch<'c, 'q: 'c, I: 'c, O: 'c, T: 'c>(
|
||||||
&'c mut self,
|
&'c mut self,
|
||||||
query: &'q str,
|
query: &'q str,
|
||||||
params: A,
|
params: I,
|
||||||
) -> BoxStream<'c, Result<T, Error>>
|
) -> BoxStream<'c, Result<T, Error>>
|
||||||
where
|
where
|
||||||
A: IntoQueryParameters<Self::Backend> + Send,
|
I: IntoQueryParameters<Self::Backend> + Send,
|
||||||
T: FromRow<Self::Backend> + Send + Unpin,
|
T: FromRow<Self::Backend, O> + Send + Unpin,
|
||||||
{
|
{
|
||||||
Box::pin(async_stream::try_stream! {
|
Box::pin(async_stream::try_stream! {
|
||||||
let mut live = self.0.acquire().await?;
|
let mut live = self.0.acquire().await?;
|
||||||
@ -331,14 +331,14 @@ where
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fetch_optional<'c, 'q: 'c, T: 'c, A: 'c>(
|
fn fetch_optional<'c, 'q: 'c, I: 'c, O: 'c, T: 'c>(
|
||||||
&'c mut self,
|
&'c mut self,
|
||||||
query: &'q str,
|
query: &'q str,
|
||||||
params: A,
|
params: I,
|
||||||
) -> BoxFuture<'c, Result<Option<T>, Error>>
|
) -> BoxFuture<'c, Result<Option<T>, Error>>
|
||||||
where
|
where
|
||||||
A: IntoQueryParameters<Self::Backend> + Send,
|
I: IntoQueryParameters<Self::Backend> + Send,
|
||||||
T: FromRow<Self::Backend> + Send,
|
T: FromRow<Self::Backend, O> + Send,
|
||||||
{
|
{
|
||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
Ok(self
|
Ok(self
|
||||||
|
@ -6,7 +6,7 @@ use crate::{
|
|||||||
use bitflags::_core::marker::PhantomData;
|
use bitflags::_core::marker::PhantomData;
|
||||||
use futures_core::{future::BoxFuture, stream::BoxStream};
|
use futures_core::{future::BoxFuture, stream::BoxStream};
|
||||||
|
|
||||||
pub struct Query<'q, DB, I = <DB as Backend>::QueryParameters, O = Row<DB>>
|
pub struct Query<'q, DB, I = <DB as Backend>::QueryParameters, O = Row<DB>, T = O>
|
||||||
where
|
where
|
||||||
DB: Backend,
|
DB: Backend,
|
||||||
{
|
{
|
||||||
@ -19,6 +19,9 @@ where
|
|||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub output: PhantomData<O>,
|
pub output: PhantomData<O>,
|
||||||
|
|
||||||
|
#[doc(hidden)]
|
||||||
|
pub target: PhantomData<T>,
|
||||||
|
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub backend: PhantomData<DB>,
|
pub backend: PhantomData<DB>,
|
||||||
}
|
}
|
||||||
@ -28,20 +31,7 @@ where
|
|||||||
DB: Backend,
|
DB: Backend,
|
||||||
DB::QueryParameters: 'q,
|
DB::QueryParameters: 'q,
|
||||||
I: IntoQueryParameters<DB> + Send,
|
I: IntoQueryParameters<DB> + Send,
|
||||||
O: FromRow<DB> + Send + Unpin,
|
|
||||||
{
|
{
|
||||||
pub fn cast<U>(self) -> Query<'q, DB, I, U>
|
|
||||||
where
|
|
||||||
U: FromRow<DB> + Send + Unpin,
|
|
||||||
{
|
|
||||||
Query {
|
|
||||||
query: self.query,
|
|
||||||
input: self.input,
|
|
||||||
output: PhantomData,
|
|
||||||
backend: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn execute<E>(self, executor: &'q mut E) -> BoxFuture<'q, crate::Result<u64>>
|
pub fn execute<E>(self, executor: &'q mut E) -> BoxFuture<'q, crate::Result<u64>>
|
||||||
where
|
where
|
||||||
@ -49,29 +39,37 @@ where
|
|||||||
{
|
{
|
||||||
executor.execute(self.query, self.input)
|
executor.execute(self.query, self.input)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn fetch<E>(self, executor: &'q mut E) -> BoxStream<'q, crate::Result<O>>
|
impl<'q, DB, I: 'q, O: 'q, T: 'q> Query<'q, DB, I, O, T>
|
||||||
|
where
|
||||||
|
DB: Backend,
|
||||||
|
DB::QueryParameters: 'q,
|
||||||
|
I: IntoQueryParameters<DB> + Send,
|
||||||
|
T: FromRow<DB, O> + Send + Unpin,
|
||||||
|
{
|
||||||
|
pub fn fetch<E>(self, executor: &'q mut E) -> BoxStream<'q, crate::Result<T>>
|
||||||
where
|
where
|
||||||
E: Executor<Backend = DB>,
|
E: Executor<Backend = DB>,
|
||||||
{
|
{
|
||||||
executor.fetch(self.query, self.input)
|
executor.fetch(self.query, self.input)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn fetch_all<E>(self, executor: &'q mut E) -> BoxFuture<'q, crate::Result<Vec<O>>>
|
pub fn fetch_all<E>(self, executor: &'q mut E) -> BoxFuture<'q, crate::Result<Vec<T>>>
|
||||||
where
|
where
|
||||||
E: Executor<Backend = DB>,
|
E: Executor<Backend = DB>,
|
||||||
{
|
{
|
||||||
executor.fetch_all(self.query, self.input)
|
executor.fetch_all(self.query, self.input)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn fetch_optional<E>(self, executor: &'q mut E) -> BoxFuture<'q, Result<Option<O>, Error>>
|
pub fn fetch_optional<E>(self, executor: &'q mut E) -> BoxFuture<'q, Result<Option<T>, Error>>
|
||||||
where
|
where
|
||||||
E: Executor<Backend = DB>,
|
E: Executor<Backend = DB>,
|
||||||
{
|
{
|
||||||
executor.fetch_optional(self.query, self.input)
|
executor.fetch_optional(self.query, self.input)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn fetch_one<E>(self, executor: &'q mut E) -> BoxFuture<'q, crate::Result<O>>
|
pub fn fetch_one<E>(self, executor: &'q mut E) -> BoxFuture<'q, crate::Result<T>>
|
||||||
where
|
where
|
||||||
E: Executor<Backend = DB>,
|
E: Executor<Backend = DB>,
|
||||||
{
|
{
|
||||||
@ -102,7 +100,7 @@ where
|
|||||||
|
|
||||||
/// Construct a full SQL query using raw SQL.
|
/// Construct a full SQL query using raw SQL.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn query<DB>(query: &str) -> Query<'_, DB, DB::QueryParameters, Row<DB>>
|
pub fn query<DB, T>(query: &str) -> Query<'_, DB, DB::QueryParameters, Row<DB>, T>
|
||||||
where
|
where
|
||||||
DB: Backend,
|
DB: Backend,
|
||||||
{
|
{
|
||||||
@ -111,5 +109,6 @@ where
|
|||||||
input: DB::QueryParameters::new(),
|
input: DB::QueryParameters::new(),
|
||||||
output: PhantomData,
|
output: PhantomData,
|
||||||
backend: PhantomData,
|
backend: PhantomData,
|
||||||
|
target: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -33,13 +33,14 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait FromRow<DB: Backend> {
|
pub trait FromRow<DB: Backend, O = Row<DB>> {
|
||||||
fn from_row(row: Row<DB>) -> Self;
|
fn from_row(row: Row<DB>) -> Self;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
macro_rules! impl_from_row {
|
macro_rules! impl_from_row {
|
||||||
($B:ident: $( ($idx:tt) -> $T:ident );+;) => {
|
($B:ident: $( ($idx:tt) -> $T:ident );+;) => {
|
||||||
|
// Row -> (T1, T2, ...)
|
||||||
impl<$($T,)+> crate::row::FromRow<$B> for ($($T,)+)
|
impl<$($T,)+> crate::row::FromRow<$B> for ($($T,)+)
|
||||||
where
|
where
|
||||||
$($B: crate::types::HasSqlType<$T>,)+
|
$($B: crate::types::HasSqlType<$T>,)+
|
||||||
@ -50,6 +51,18 @@ macro_rules! impl_from_row {
|
|||||||
($(row.get($idx),)+)
|
($(row.get($idx),)+)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// (T1, T2, ...) -> (T1, T2, ...)
|
||||||
|
impl<$($T,)+> crate::row::FromRow<$B, ($($T,)+)> for ($($T,)+)
|
||||||
|
where
|
||||||
|
$($B: crate::types::HasSqlType<$T>,)+
|
||||||
|
$($T: crate::decode::Decode<$B>,)+
|
||||||
|
{
|
||||||
|
#[inline]
|
||||||
|
fn from_row(row: crate::row::Row<$B>) -> Self {
|
||||||
|
($(row.get($idx),)+)
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -188,10 +188,11 @@ where
|
|||||||
Ok(quote! {{
|
Ok(quote! {{
|
||||||
#params
|
#params
|
||||||
|
|
||||||
sqlx::Query::<#backend_path, _, (#(#output_types),*,)> {
|
sqlx::Query::<#backend_path, _, (#(#output_types),*,), _> {
|
||||||
query: #query,
|
query: #query,
|
||||||
input: params,
|
input: params,
|
||||||
output: ::core::marker::PhantomData,
|
output: ::core::marker::PhantomData,
|
||||||
|
target: ::core::marker::PhantomData,
|
||||||
backend: ::core::marker::PhantomData,
|
backend: ::core::marker::PhantomData,
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user