mirror of
https://github.com/launchbadge/sqlx.git
synced 2025-12-29 21:00:54 +00:00
feat(core): add query_as, FromRow
This commit is contained in:
parent
0708b3a873
commit
1107241170
204
sqlx-core/src/from_row.rs
Normal file
204
sqlx-core/src/from_row.rs
Normal file
@ -0,0 +1,204 @@
|
||||
use crate::{Row, TypeDecodeOwned};
|
||||
|
||||
/// A type that can be built from a row returned by the database.
|
||||
pub trait FromRow<R: Row>: Sized {
|
||||
/// Build a value of `Self` from the given [`Row`].
|
||||
fn from_row(row: &R) -> crate::Result<Self>;
|
||||
}
|
||||
|
||||
macro_rules! impl_from_row_for_tuple {
|
||||
($( ($idx:tt) -> $T:ident );+;) => {
|
||||
impl<R: Row, $($T,)+> FromRow<R> for ($($T,)+)
|
||||
where
|
||||
$($T: TypeDecodeOwned<R::Database>,)+
|
||||
{
|
||||
fn from_row(row: &R) -> crate::Result<Self> {
|
||||
Ok(($(row.try_get($idx)?,)+))
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
impl_from_row_for_tuple!(
|
||||
(0) -> T1;
|
||||
);
|
||||
|
||||
impl_from_row_for_tuple!(
|
||||
(0) -> T1;
|
||||
(1) -> T2;
|
||||
);
|
||||
|
||||
impl_from_row_for_tuple!(
|
||||
(0) -> T1;
|
||||
(1) -> T2;
|
||||
(2) -> T3;
|
||||
);
|
||||
|
||||
impl_from_row_for_tuple!(
|
||||
(0) -> T1;
|
||||
(1) -> T2;
|
||||
(2) -> T3;
|
||||
(3) -> T4;
|
||||
);
|
||||
|
||||
impl_from_row_for_tuple!(
|
||||
(0) -> T1;
|
||||
(1) -> T2;
|
||||
(2) -> T3;
|
||||
(3) -> T4;
|
||||
(4) -> T5;
|
||||
);
|
||||
|
||||
impl_from_row_for_tuple!(
|
||||
(0) -> T1;
|
||||
(1) -> T2;
|
||||
(2) -> T3;
|
||||
(3) -> T4;
|
||||
(4) -> T5;
|
||||
(5) -> T6;
|
||||
);
|
||||
|
||||
impl_from_row_for_tuple!(
|
||||
(0) -> T1;
|
||||
(1) -> T2;
|
||||
(2) -> T3;
|
||||
(3) -> T4;
|
||||
(4) -> T5;
|
||||
(5) -> T6;
|
||||
(6) -> T7;
|
||||
);
|
||||
|
||||
impl_from_row_for_tuple!(
|
||||
(0) -> T1;
|
||||
(1) -> T2;
|
||||
(2) -> T3;
|
||||
(3) -> T4;
|
||||
(4) -> T5;
|
||||
(5) -> T6;
|
||||
(6) -> T7;
|
||||
(7) -> T8;
|
||||
);
|
||||
|
||||
impl_from_row_for_tuple!(
|
||||
(0) -> T1;
|
||||
(1) -> T2;
|
||||
(2) -> T3;
|
||||
(3) -> T4;
|
||||
(4) -> T5;
|
||||
(5) -> T6;
|
||||
(6) -> T7;
|
||||
(7) -> T8;
|
||||
(8) -> T9;
|
||||
);
|
||||
|
||||
impl_from_row_for_tuple!(
|
||||
(0) -> T1;
|
||||
(1) -> T2;
|
||||
(2) -> T3;
|
||||
(3) -> T4;
|
||||
(4) -> T5;
|
||||
(5) -> T6;
|
||||
(6) -> T7;
|
||||
(7) -> T8;
|
||||
(8) -> T9;
|
||||
(9) -> T10;
|
||||
);
|
||||
|
||||
impl_from_row_for_tuple!(
|
||||
(0) -> T1;
|
||||
(1) -> T2;
|
||||
(2) -> T3;
|
||||
(3) -> T4;
|
||||
(4) -> T5;
|
||||
(5) -> T6;
|
||||
(6) -> T7;
|
||||
(7) -> T8;
|
||||
(8) -> T9;
|
||||
(9) -> T10;
|
||||
(10) -> T11;
|
||||
);
|
||||
|
||||
impl_from_row_for_tuple!(
|
||||
(0) -> T1;
|
||||
(1) -> T2;
|
||||
(2) -> T3;
|
||||
(3) -> T4;
|
||||
(4) -> T5;
|
||||
(5) -> T6;
|
||||
(6) -> T7;
|
||||
(7) -> T8;
|
||||
(8) -> T9;
|
||||
(9) -> T10;
|
||||
(10) -> T11;
|
||||
(11) -> T12;
|
||||
);
|
||||
|
||||
impl_from_row_for_tuple!(
|
||||
(0) -> T1;
|
||||
(1) -> T2;
|
||||
(2) -> T3;
|
||||
(3) -> T4;
|
||||
(4) -> T5;
|
||||
(5) -> T6;
|
||||
(6) -> T7;
|
||||
(7) -> T8;
|
||||
(8) -> T9;
|
||||
(9) -> T10;
|
||||
(10) -> T11;
|
||||
(11) -> T12;
|
||||
(12) -> T13;
|
||||
);
|
||||
|
||||
impl_from_row_for_tuple!(
|
||||
(0) -> T1;
|
||||
(1) -> T2;
|
||||
(2) -> T3;
|
||||
(3) -> T4;
|
||||
(4) -> T5;
|
||||
(5) -> T6;
|
||||
(6) -> T7;
|
||||
(7) -> T8;
|
||||
(8) -> T9;
|
||||
(9) -> T10;
|
||||
(10) -> T11;
|
||||
(11) -> T12;
|
||||
(12) -> T13;
|
||||
(13) -> T14;
|
||||
);
|
||||
|
||||
impl_from_row_for_tuple!(
|
||||
(0) -> T1;
|
||||
(1) -> T2;
|
||||
(2) -> T3;
|
||||
(3) -> T4;
|
||||
(4) -> T5;
|
||||
(5) -> T6;
|
||||
(6) -> T7;
|
||||
(7) -> T8;
|
||||
(8) -> T9;
|
||||
(9) -> T10;
|
||||
(10) -> T11;
|
||||
(11) -> T12;
|
||||
(12) -> T13;
|
||||
(13) -> T14;
|
||||
(14) -> T15;
|
||||
);
|
||||
|
||||
impl_from_row_for_tuple!(
|
||||
(0) -> T1;
|
||||
(1) -> T2;
|
||||
(2) -> T3;
|
||||
(3) -> T4;
|
||||
(4) -> T5;
|
||||
(5) -> T6;
|
||||
(6) -> T7;
|
||||
(7) -> T8;
|
||||
(8) -> T9;
|
||||
(9) -> T10;
|
||||
(10) -> T11;
|
||||
(11) -> T12;
|
||||
(12) -> T13;
|
||||
(13) -> T14;
|
||||
(14) -> T15;
|
||||
(15) -> T16;
|
||||
);
|
||||
@ -32,6 +32,7 @@ mod error;
|
||||
mod execute;
|
||||
mod executor;
|
||||
mod isolation_level;
|
||||
mod from_row;
|
||||
mod options;
|
||||
mod query_result;
|
||||
pub mod row;
|
||||
@ -63,13 +64,14 @@ pub use connection::Connection;
|
||||
pub use database::Database;
|
||||
pub use decode::Decode;
|
||||
pub use encode::Encode;
|
||||
pub use from_row::FromRow;
|
||||
pub use error::{DatabaseError, Error, Result};
|
||||
pub use execute::Execute;
|
||||
pub use executor::Executor;
|
||||
pub use isolation_level::IsolationLevel;
|
||||
pub use options::ConnectOptions;
|
||||
pub use query_result::QueryResult;
|
||||
pub use r#type::{Type, TypeDecode, TypeEncode};
|
||||
pub use r#type::{Type, TypeDecode, TypeEncode, TypeDecodeOwned};
|
||||
pub use row::{ColumnIndex, Row};
|
||||
#[cfg(feature = "actix")]
|
||||
pub use runtime::Actix;
|
||||
|
||||
@ -74,3 +74,8 @@ impl<Db: Database, T: Type<Db> + Encode<Db>> TypeEncode<Db> for T {
|
||||
pub trait TypeDecode<'r, Db: Database>: Type<Db> + Decode<'r, Db> {}
|
||||
|
||||
impl<'r, T: Type<Db> + Decode<'r, Db>, Db: Database> TypeDecode<'r, Db> for T {}
|
||||
|
||||
#[allow(clippy::module_name_repetitions)]
|
||||
pub trait TypeDecodeOwned<Db: Database>: for<'r> TypeDecode<'r, Db> {}
|
||||
|
||||
impl<T, Db: Database> TypeDecodeOwned<Db> for T where T: for<'r> TypeDecode<'r, Db> {}
|
||||
|
||||
@ -47,6 +47,7 @@
|
||||
pub mod blocking;
|
||||
|
||||
mod query;
|
||||
mod query_as;
|
||||
mod runtime;
|
||||
|
||||
#[cfg(feature = "mysql")]
|
||||
@ -58,6 +59,7 @@ pub mod mysql;
|
||||
#[cfg(feature = "blocking")]
|
||||
pub use blocking::Blocking;
|
||||
pub use query::{query, Query};
|
||||
pub use query_as::{query_as, QueryAs};
|
||||
pub use runtime::DefaultRuntime;
|
||||
#[cfg(feature = "actix")]
|
||||
pub use sqlx_core::Actix;
|
||||
|
||||
65
sqlx/src/query_as.rs
Normal file
65
sqlx/src/query_as.rs
Normal file
@ -0,0 +1,65 @@
|
||||
use std::borrow::Cow;
|
||||
use std::marker::PhantomData;
|
||||
|
||||
use sqlx_core::{Execute, Executor, FromRow, TypeEncode};
|
||||
|
||||
use crate::{query, Arguments, Database, DefaultRuntime, Query, Runtime};
|
||||
|
||||
pub struct QueryAs<'q, 'a, O, Db: Database, Rt: Runtime = DefaultRuntime> {
|
||||
inner: Query<'q, 'a, Db, Rt>,
|
||||
output: PhantomData<O>,
|
||||
}
|
||||
|
||||
impl<'q, 'a, Db: Database, Rt: Runtime, O: Send + Sync> Execute<'q, 'a, Db>
|
||||
for QueryAs<'q, 'a, O, Db, Rt>
|
||||
{
|
||||
fn sql(&self) -> &str {
|
||||
self.inner.sql()
|
||||
}
|
||||
|
||||
fn arguments(&self) -> Option<&Arguments<'a, Db>> {
|
||||
self.inner.arguments()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'q, 'a, Db: Database, Rt: Runtime, O> QueryAs<'q, 'a, O, Db, Rt> {
|
||||
pub fn bind<T: 'a + TypeEncode<Db>>(&mut self, value: &'a T) -> &mut Self {
|
||||
self.inner.bind(value);
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "async")]
|
||||
impl<'q, 'a, O, Db, Rt> QueryAs<'q, 'a, O, Db, Rt>
|
||||
where
|
||||
Db: Database,
|
||||
Rt: crate::Async,
|
||||
O: Send + Sync + FromRow<Db::Row>,
|
||||
{
|
||||
pub async fn fetch_optional<X>(&self, mut executor: X) -> crate::Result<Option<O>>
|
||||
where
|
||||
X: Send + Executor<Rt, Database = Db>,
|
||||
{
|
||||
executor.fetch_optional(&self.inner).await?.as_ref().map(O::from_row).transpose()
|
||||
}
|
||||
|
||||
pub async fn fetch_one<X>(&self, mut executor: X) -> crate::Result<O>
|
||||
where
|
||||
X: Send + Executor<Rt, Database = Db>,
|
||||
{
|
||||
O::from_row(&executor.fetch_one(&self.inner).await?)
|
||||
}
|
||||
|
||||
pub async fn fetch_all<X>(&self, mut executor: X) -> crate::Result<Vec<O>>
|
||||
where
|
||||
X: Send + Executor<Rt, Database = Db>,
|
||||
{
|
||||
executor.fetch_all(self).await?.iter().map(O::from_row).collect()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn query_as<'q, 'a, O, Db: Database, Rt: Runtime>(
|
||||
sql: impl Into<Cow<'q, str>>,
|
||||
) -> QueryAs<'q, 'a, O, Db, Rt> {
|
||||
QueryAs::<'q, 'a, O, Db, Rt> { inner: query(sql), output: PhantomData }
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user