sqlx/sqlx-core/src/executor.rs
Ryan Leckey 6b22fb7489 Refactor HasSqlType to provide an array of compatible types.
* Intending to use in a new Row type to check types at runtime for
   dynamic queries and to guard against schema changes

 * Hoping the query! macro can utilize this to allow accepting N
   rust types for 1 sql type and returning N rust types for 1 sql
   type.
2020-01-14 23:27:42 -08:00

73 lines
2.5 KiB
Rust

use crate::database::Database;
use crate::describe::Describe;
use futures_core::future::BoxFuture;
use futures_core::stream::BoxStream;
use futures_util::TryStreamExt;
/// Encapsulates query execution on the database.
///
/// Implemented primarily by [crate::Pool].
pub trait Executor {
type Database: Database + ?Sized;
/// Send a raw SQL command to the database.
///
/// This is intended for queries that cannot or should not be prepared (ex. `BEGIN`).
///
/// Does not support fetching results.
fn send<'e, 'q: 'e>(&'e mut self, command: &'q str) -> BoxFuture<'e, crate::Result<()>>;
/// Execute the query, returning the number of rows affected.
fn execute<'e, 'q: 'e>(
&'e mut self,
query: &'q str,
args: <Self::Database as Database>::Arguments,
) -> BoxFuture<'e, crate::Result<u64>>;
/// Executes the query and returns a [Stream] of [Row].
fn fetch<'e, 'q: 'e>(
&'e mut self,
query: &'q str,
args: <Self::Database as Database>::Arguments,
) -> BoxStream<'e, crate::Result<<Self::Database as Database>::Row>>;
/// Executes the query and returns up to resulting record.
///
/// * [crate::Error::FoundMoreThanOne] will be returned if the query produced more than 1 row.
fn fetch_optional<'e, 'q: 'e>(
&'e mut self,
query: &'q str,
args: <Self::Database as Database>::Arguments,
) -> BoxFuture<'e, crate::Result<Option<<Self::Database as Database>::Row>>> {
let mut s = self.fetch(query, args);
Box::pin(async move {
match s.try_next().await? {
Some(val) => {
if s.try_next().await?.is_some() {
Err(crate::Error::FoundMoreThanOne)
} else {
Ok(Some(val))
}
}
None => Ok(None),
}
})
}
/// Execute the query and return at most one resulting record.
fn fetch_one<'e, 'q: 'e>(
&'e mut self,
query: &'q str,
args: <Self::Database as Database>::Arguments,
) -> BoxFuture<'e, crate::Result<<Self::Database as Database>::Row>> {
let mut s = self.fetch(query, args);
Box::pin(async move { s.try_next().await?.ok_or(crate::Error::NotFound) })
}
#[doc(hidden)]
fn describe<'e, 'q: 'e>(
&'e mut self,
query: &'q str,
) -> BoxFuture<'e, crate::Result<Describe<Self::Database>>>;
}