1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87
//! This module defines a wrapper for sqlx's Executor
//!
//! Unlike sqlx's Executor which provides several separate methods for different querying strategies,
//! our [Executor] has a single method which is generic using the [QueryStrategy] trait.
use rorm_sql::value::Value;
use crate::internal;
/// [QueryStrategy] returning nothing
///
/// `type Result<'result> = impl Future<Output = Result<(), Error>>`
pub struct Nothing;
impl QueryStrategy for Nothing {}
/// [QueryStrategy] returning how many rows have been affected by the query
///
/// `type Result<'result> = impl Future<Output = Result<u64, Error>>`
pub struct AffectedRows;
impl QueryStrategy for AffectedRows {}
/// [QueryStrategy] returning a single row
///
/// `type Result<'result> = impl Future<Output = Result<Row, Error>>`
pub struct One;
impl QueryStrategy for One {}
/// [QueryStrategy] returning an optional row
///
/// `type Result<'result> = impl Future<Output = Result<Option<Row>, Error>>`
pub struct Optional;
impl QueryStrategy for Optional {}
/// [QueryStrategy] returning a vector of rows
///
/// `type Result<'result> = impl Future<Output = Result<Vec<Row>, Error>>`
pub struct All;
impl QueryStrategy for All {}
/// [QueryStrategy] returning a stream of rows
///
/// `type Result<'result> = impl Stream<Item = Result<Row, Error>>`
pub struct Stream;
impl QueryStrategy for Stream {}
/// Define how a query is send to and results retrieved from the database.
///
/// This trait is implemented on the following unit structs:
/// - [Nothing] retrieves nothing
/// - [Optional] retrieves an optional row
/// - [One] retrieves a single row
/// - [Stream] retrieves many rows in a stream
/// - [All] retrieves many rows in a vector
/// - [AffectedRows] returns the number of rows affected by the query
///
/// This trait has an associated `Result<'result>` type which is returned by [Executor::execute].
/// To avoid boxing, these types are quite big.
///
/// Each of those unit structs' docs (follow links above) contains an easy to read `impl Trait` version of the actual types.
pub trait QueryStrategy: QueryStrategyResult + internal::executor::QueryStrategyImpl {}
/// Helper trait to make the `Result<'result> public,
/// while keeping [QueryStrategyImpl](internal::executor::QueryStrategyImpl) itself private
#[doc(hidden)]
pub trait QueryStrategyResult {
type Result<'result>;
}
/// Some kind of database connection which can execute queries
///
/// This trait is implemented by the database connection itself as well as transactions.
pub trait Executor<'executor> {
/// Execute a query
///
/// ```skipped
/// db.execute::<All>("SELECT * FROM foo;".to_string(), vec![]);
/// ```
fn execute<'data, 'result, Q>(
self,
query: String,
values: Vec<Value<'data>>,
) -> Q::Result<'result>
where
'executor: 'result,
'data: 'result,
Q: QueryStrategy;
}