use super::*;
mod params; pub use params::{Params, Param, ToParam};
mod row; pub use row::{Value, Row, TryFromRefRow, }; mod flavor; pub use flavor::{Flavor};
pub trait Connection<R>
where R: Row,
{
fn flavor(&self) -> Flavor;
fn execute_with_params<S, P>(&mut self, query: S, params: &P) -> Result<()>
where S: std::convert::AsRef<str>,
P: Params;
fn execute_with_params_iterator<'a, S, I, P>(&mut self, query: S, params_iter: I) -> Result<()>
where S: std::convert::AsRef<str>,
P: Params + 'a,
I: core::iter::IntoIterator<Item = &'a P>;
fn query<S>(&mut self, query: S) -> Result<Vec<R>>
where S: std::convert::AsRef<str>;
fn query_try_as_object<S, T>(&mut self, query: S) -> Result<Vec<T>>
where S: std::convert::AsRef<str>,
T: TryFromRefRow<R>,
{
self.query(query)?
.iter()
.map(|r: &R| Ok(T::try_from(r)?) )
.collect::<Result<Vec<T>>>()
}
fn query_first<S>(&mut self, query: S) -> Result<Option<R>>
where S: std::convert::AsRef<str>,
{
Ok(self.query(query)?.into_iter().nth(0))
}
fn query_first_try_as_object<S, T>(&mut self, query: S) -> Result<Option<T>>
where S: std::convert::AsRef<str>,
T: TryFromRefRow<R>,
{
if let Some(r) = self.query_first::<_>(query)? {
Ok(Some(T::try_from(&r)?))
} else {
Ok(None)
}
}
fn query_drop<S>(&mut self, query: S) -> Result<()>
where S: std::convert::AsRef<str>
{
self.query_first::<_>(query)?;
Ok(())
}
}
mod sql; mod table; pub use table::{Table, TableStatement, TableFlavoredStatement};
mod insert; pub use insert::{Insert, InsertMultiple, InsertStatement, InsertFlavoredStatement};
mod select; pub use select::{Select as SelectV2, SelectStatement, SelectFlavoredStatement};
mod update; pub use update::{Update, UpdateStatement, UpdateFlavoredStatement};
mod delete; pub use delete::{Delete, DeleteStatement, DeleteFlavoredStatement};
mod filter; pub use filter::{Filter, FlavoredFilter};
mod order; pub use order::{Order, FlavoredOrder};
fn statement_with_conn_filter_order_limit_offset_options<C, R, F, O>(statement: String, conn: &C, filter: Option<&F>, order: Option<&O>, limit: Option<usize>, offset: Option<usize>) -> Result<String>
where C: Connection<R>, R: Row, F: FlavoredFilter, O: FlavoredOrder,
{
let statement = if let Some(filter) = filter {
let filter = filter.filter(conn)?;
if ! filter.is_empty() { format!("{statement} WHERE {filter}") }
else { statement }
} else { statement };
let statement = if let Some(order) = order {
let order = order.as_order_clause(conn)?;
if ! order.is_empty() { format!("{statement} ORDER BY {order}") }
else { statement }
} else { statement };
let statement = if let Some(limit) = limit { format!("{statement} LIMIT {limit}") } else { statement };
let statement = if let Some(offset) = offset {
if offset > 0 { format!("{statement} OFFSET {offset}") }
else { statement }
} else { statement };
Ok(statement)
}
fn statement_with_filter_order_limit_offset_options<F, O>(statement: String, filter: Option<&F>, order: Option<&O>, limit: Option<usize>, offset: Option<usize>) -> Result<String>
where F: Filter, O: Order,
{
let statement = if let Some(filter) = filter {
let filter = filter.filter();
if ! filter.is_empty() { format!("{statement} WHERE {filter}") }
else { statement }
} else { statement };
let statement = if let Some(order) = order {
let order = order.as_order_clause();
if ! order.is_empty() { format!("{statement} ORDER BY {order}") }
else { statement }
} else { statement };
let statement = if let Some(limit) = limit { format!("{statement} LIMIT {limit}") } else { statement };
let statement = if let Some(offset) = offset {
if offset > 0 { format!("{statement} OFFSET {offset}") }
else { statement }
} else { statement };
Ok(statement)
}
#[cfg(test)]
pub mod tests {
use super::*;
pub struct SQLiteFlavoredConnection {}
impl<R> Connection<R> for SQLiteFlavoredConnection
where R: traits::Row
{
fn flavor(&self) -> Flavor { Flavor::SQLite }
fn execute_with_params<S, P>(&mut self, _query: S, _params: &P) -> Result<()>
where S: std::convert::AsRef<str>, P: Params,
{ Err("command not available for SQLiteFlavoredConnection".into()) }
fn execute_with_params_iterator<'a, S, I, P>(&mut self, _query: S, _params_iter: I) -> Result<()>
where S: std::convert::AsRef<str>, P: Params + 'a,
I: core::iter::IntoIterator<Item = &'a P>,
{ Err("command not available for SQLiteFlavoredConnection".into()) }
fn query<S>(&mut self, _query: S) -> Result<Vec<R>>
where S: std::convert::AsRef<str>,
{ Err("command not available for SQLiteFlavoredConnection".into()) }
}
pub struct Row {}
impl row::Row for Row {
fn get_value(&self, _i: usize) -> Option<Result<Value>> { None }
fn get<T>(&self, _i: usize) -> Option<Result<T>>
where T: row::TryFromValue,
{ None }
}
}
#[cfg(feature="compatibility_v0_10")]
mod execute;
#[cfg(feature="compatibility_v0_10")]
pub use execute::{ExecuteTrait};
#[cfg(feature="compatibility_v0_10")]
mod query;
#[cfg(feature="compatibility_v0_10")]
pub use query::{QueryTrait};
#[cfg(feature="compatibility_v0_10")]
pub trait AsStatement<I> {
fn as_statement(&self) -> Result<String>;
}
#[cfg(feature="compatibility_v0_10")]
pub trait IsSelect {}
#[cfg(feature="compatibility_v0_10")]
pub trait Select<T, I>
where T: AsStatement<I> + IsSelect
{
fn select(&self, as_statement: &T) -> Result<Vec<I>>;
}
#[cfg(feature="compatibility_v0_10")]
pub trait CreateTable<T>
where T: AsStatement<()>
{
fn create_table(&mut self, as_statement: &T) -> Result<()>;
}