use crate::{ backend::Backend, describe::Describe, error::Error, params::{IntoQueryParameters, QueryParameters}, row::FromRow, }; use futures_core::{future::BoxFuture, stream::BoxStream}; use futures_util::{TryFutureExt, TryStreamExt}; pub trait Executor: Send { type Backend: Backend; /// Verifies a connection to the database is still alive. fn ping<'e>(&'e mut self) -> BoxFuture<'e, crate::Result<()>> { Box::pin( self.execute( "SELECT 1", Default::default(), ) .map_ok(|_| ()), ) } fn execute<'e, 'q: 'e>( &'e mut self, query: &'q str, params: ::QueryParameters, ) -> BoxFuture<'e, crate::Result>; fn fetch<'e, 'q: 'e, T: 'e>( &'e mut self, query: &'q str, params: ::QueryParameters, ) -> BoxStream<'e, crate::Result> where T: FromRow + Send + Unpin; fn fetch_all<'e, 'q: 'e, T: 'e>( &'e mut self, query: &'q str, params: ::QueryParameters, ) -> BoxFuture<'e, crate::Result>> where T: FromRow + Send + Unpin, { Box::pin(self.fetch(query, params).try_collect()) } fn fetch_optional<'e, 'q: 'e, T: 'e>( &'e mut self, query: &'q str, params: ::QueryParameters, ) -> BoxFuture<'e, crate::Result>> where T: FromRow + Send; fn fetch_one<'e, 'q: 'e, T: 'e>( &'e mut self, query: &'q str, params: ::QueryParameters, ) -> BoxFuture<'e, crate::Result> where T: FromRow + Send, { let fut = self.fetch_optional(query, params); Box::pin(async move { fut.await?.ok_or(Error::NotFound) }) } /// Analyze the SQL statement and report the inferred bind parameter types and returned /// columns. fn describe<'e, 'q: 'e>( &'e mut self, query: &'q str, ) -> BoxFuture<'e, crate::Result>>; }