derive_sql/
traits.rs

1//! traits underlying the implementation of SQL functionalities. What some other crates call `prelude`
2use super::*;
3
4mod params; pub use params::{Params, Param, ToParam};
5mod row; pub use row::{Value, Row, TryFromRefRow, }; // Row2, RefTryInto, };
6mod flavor; pub use flavor::{Flavor};
7
8/// Generic trait to be implemented by SQL drivers (or proxy to SQL drivers). This trait is used
9/// to provide the basis of the functionalities on which the crate rely
10pub trait Connection<R>
11where R: Row,
12{
13  /// Returns flavor of SQL
14  fn flavor(&self) -> Flavor;
15
16  /// Implements an `execute` statement
17  fn execute_with_params<S, P>(&mut self, query: S, params: &P) -> Result<()>
18  where S: std::convert::AsRef<str>,
19        P: Params;
20
21  /// Implements an `execute` statement over an iterator of parameters
22  fn execute_with_params_iterator<'a, S, I, P>(&mut self, query: S, params_iter: I) -> Result<()>
23  where S: std::convert::AsRef<str>,
24        P: Params + 'a,
25        I: core::iter::IntoIterator<Item = &'a P>;
26
27  /*
28  /// Implements an `execute` statement returning the modified elements
29  fn execute_with_params_rows<S, P>(&mut self, query: S, params: &P) -> Result<Vec<R>>
30  where S: std::convert::AsRef<str>,
31        P: Params;
32        */
33
34  /// Implements a `query` statement returning a list of results stored as `Row`
35  fn query<S>(&mut self, query: S) -> Result<Vec<R>>
36  where S: std::convert::AsRef<str>;
37
38  // Implemented methods:
39  /*
40  /// `execute` statement retuning the list of results as object of the given type `T`
41  fn execute_with_params_try_as_object<S, P, T>(&mut self, query: S, params: &P) -> Result<Vec<T>>
42  where S: std::convert::AsRef<str>,
43        P: Params,
44        T: TryFromRefRow<R>,
45  {
46    Ok(
47    self.execute_with_params_rows(query, params)?
48    .iter()
49    .map(|r: &R| Ok(T::try_from(r)?))
50    .collect::<Result<Vec<T>>>()?
51    )
52  }
53  */
54
55/*
56  /// `execute` statement retuning the list of results as object of the given type `T`
57  fn execute_with_params_as_object<S, P, T>(&mut self, query: S, params: P) -> Result<Vec<T>>
58  where S: std::convert::AsRef<str>,
59        P: Params,
60        T: for<'a> std::convert::From<&'a R>,
61  {
62    Ok(
63    self.execute_with_params(query, params)?
64    .iter()
65    .map(|r: &R| r.into())
66    .collect::<Vec<T>>()
67    )
68  }
69  */
70
71/*
72  /// `execute` statement returning only the first item in the list
73  fn execute_with_params_first<S, P>(&mut self, query: S, params: P) -> Result<Option<R>>
74  where S: std::convert::AsRef<str>,
75        P: Params,
76  {
77    let r = self.execute_with_params(query, params)?;
78    Ok(r.into_iter().nth(0))
79  }
80
81  /// `execute` statement returning the first item in the list as an object of the given type `T`
82  fn execute_with_params_first_try_as_object<S, P, T, E>(&mut self, query: S, params: P) -> Result<Option<T>>
83  where S: std::convert::AsRef<str>,
84        P: Params,
85        T: for<'a> std::convert::TryFrom<&'a R, Error=E>,
86        error::Error: std::convert::From<E>,
87  {
88    if let Some(r) = self.execute_with_params_first::<_, _>(query, params)? {
89      Ok(Some((&r).try_into()?))
90    } else {
91      Ok(None)
92    }
93  }
94  */
95
96/*
97  /// `execute` statement returning the first item in the list as an object of the given type `T`
98  fn execute_with_params_first_as_object<S, P, T>(&mut self, query: S, params: P) -> Result<Option<T>>
99  where S: std::convert::AsRef<str>,
100        P: Params,
101        T: for<'a> std::convert::From<&'a R>,
102  {
103    if let Some(r) = self.execute_with_params_first::<_, _>(query, params)? {
104      Ok(Some((&r).into()))
105    } else {
106      Ok(None)
107    }
108  }
109  */
110
111/*
112  /// `execute` statement dropping returned results
113  fn execute_with_params_drop<S, P>(&mut self, query: S, params: P) -> Result<()>
114  where S: std::convert::AsRef<str>,
115        P: Params,
116  {
117    self.execute_with_params_first::<_, _>(query, params)?;
118    Ok(())
119  }
120  */
121
122  /// `query` statement returning list of objects of type `T`
123  fn query_try_as_object<S, T>(&mut self, query: S) -> Result<Vec<T>>
124  where S: std::convert::AsRef<str>,
125        T: TryFromRefRow<R>,
126  {
127    self.query(query)?
128    .iter()
129    .map(|r: &R| Ok(T::try_from(r)?) )
130    .collect::<Result<Vec<T>>>()
131  }
132
133/*
134  /// `query` statement returning list of objects of type `T`
135  fn query_as_object<S, T>(&mut self, query: S) -> Result<Vec<T>>
136  where S: std::convert::AsRef<str>,
137        T: for<'a> std::convert::From<&'a R>,
138  {
139    Ok(
140    self.query(query)?
141    .iter()
142    .map(|r: &R| r.into() )
143    .collect::<Vec<T>>()
144    )
145  }
146  */
147
148  /// `query` statement returning only the first item in the list
149  fn query_first<S>(&mut self, query: S) -> Result<Option<R>>
150  where S: std::convert::AsRef<str>,
151  {
152    Ok(self.query(query)?.into_iter().nth(0))
153  }
154
155  /// `query` statement returning only the first item as an object of type `T`
156  fn query_first_try_as_object<S, T>(&mut self, query: S) -> Result<Option<T>>
157  where S: std::convert::AsRef<str>,
158        T: TryFromRefRow<R>,
159  {
160    if let Some(r) = self.query_first::<_>(query)? {
161      Ok(Some(T::try_from(&r)?))
162    } else {
163      Ok(None)
164    }
165  }
166
167/*
168  /// `query` statement returning only the first item as an object of type `T`
169  fn query_first_as_object<S, T>(&mut self, query: S) -> Result<Option<T>>
170  where S: std::convert::AsRef<str>,
171        T: for<'a> std::convert::From<&'a R>,
172  {
173    if let Some(r) = self.query_first::<_>(query)? {
174      Ok(Some((&r).into()))
175    } else {
176      Ok(None)
177    }
178  }
179  */
180
181  /// `query` statement dropping returned results
182  fn query_drop<S>(&mut self, query: S) -> Result<()>
183  where S: std::convert::AsRef<str>
184  {
185    self.query_first::<_>(query)?;
186    Ok(())
187  }
188}
189
190mod sql;    // pub use sql::Sql;
191mod table;  pub use table::{Table, TableStatement, TableFlavoredStatement};
192mod insert; pub use insert::{Insert, InsertMultiple, InsertStatement, InsertFlavoredStatement};
193mod select; pub use select::{Select as SelectV2, SelectStatement, SelectFlavoredStatement};
194mod update; pub use update::{Update, UpdateStatement, UpdateFlavoredStatement};
195mod delete; pub use delete::{Delete, DeleteStatement, DeleteFlavoredStatement};
196mod filter; pub use filter::{Filter, FlavoredFilter};
197mod order;  pub use order::{Order, FlavoredOrder};
198
199/// Combine a flavored statement with optional filter, order, limit and offset to return full statement
200fn 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>
201where C: Connection<R>, R: Row, F: FlavoredFilter, O: FlavoredOrder,
202{
203  let statement = if let Some(filter) = filter { 
204    let filter = filter.filter(conn)?;
205    if ! filter.is_empty() { format!("{statement} WHERE {filter}") } 
206    else { statement }
207  } else { statement };
208  let statement = if let Some(order) = order {
209    let order = order.as_order_clause(conn)?;
210    if ! order.is_empty() { format!("{statement} ORDER BY {order}") }
211    else { statement }
212  } else { statement };
213  let statement = if let Some(limit) = limit { format!("{statement} LIMIT {limit}") } else { statement };
214  let statement = if let Some(offset) = offset { 
215    if offset > 0 { format!("{statement} OFFSET {offset}") }
216    else { statement }
217  } else { statement };
218  Ok(statement)
219}
220/// Combine a statement with optional filter, order, limit and offset to return full statement
221fn 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>
222where F: Filter, O: Order,
223{
224  let statement = if let Some(filter) = filter { 
225    let filter = filter.filter();
226    if ! filter.is_empty() { format!("{statement} WHERE {filter}") } 
227    else { statement }
228  } else { statement };
229  let statement = if let Some(order) = order {
230    let order = order.as_order_clause();
231    if ! order.is_empty() { format!("{statement} ORDER BY {order}") }
232    else { statement }
233  } else { statement };
234  let statement = if let Some(limit) = limit { format!("{statement} LIMIT {limit}") } else { statement };
235  let statement = if let Some(offset) = offset { 
236    if offset > 0 { format!("{statement} OFFSET {offset}") }
237    else { statement }
238  } else { statement };
239  Ok(statement)
240}
241
242#[cfg(test)]
243pub mod tests {
244  use super::*;
245
246  pub struct SQLiteFlavoredConnection {}
247  impl<R> Connection<R> for SQLiteFlavoredConnection 
248  where R: traits::Row
249  {
250    fn flavor(&self) -> Flavor { Flavor::SQLite }
251    fn execute_with_params<S, P>(&mut self, _query: S, _params: &P) -> Result<()>
252    where S: std::convert::AsRef<str>, P: Params,
253    { Err("command not available for SQLiteFlavoredConnection".into()) }
254    fn execute_with_params_iterator<'a, S, I, P>(&mut self, _query: S, _params_iter: I) -> Result<()>
255    where S: std::convert::AsRef<str>, P: Params + 'a, 
256          I: core::iter::IntoIterator<Item = &'a P>,
257    { Err("command not available for SQLiteFlavoredConnection".into()) }
258    fn query<S>(&mut self, _query: S) -> Result<Vec<R>>
259    where S: std::convert::AsRef<str>,
260    { Err("command not available for SQLiteFlavoredConnection".into()) }
261  }
262
263  pub struct Row {}
264  impl row::Row for Row {
265    fn get_value(&self, _i: usize) -> Option<Result<Value>> { None }
266    fn get<T>(&self, _i: usize) -> Option<Result<T>>
267    where T: row::TryFromValue,
268    { None }
269  }
270}
271
272#[cfg(feature="compatibility_v0_10")]
273mod execute; 
274#[cfg(feature="compatibility_v0_10")]
275pub use execute::{ExecuteTrait};
276#[cfg(feature="compatibility_v0_10")]
277mod query; 
278#[cfg(feature="compatibility_v0_10")]
279pub use query::{QueryTrait};
280
281// mod derive_sql; pub use derive_sql::{DeriveSqlTrait, Params, Param, ToParam, Row, FromValue, };
282// mod select; pub use select::Select;
283// mod connection; pub use connection::Connection;
284
285#[cfg(feature="compatibility_v0_10")]
286pub trait AsStatement<I> {
287  fn as_statement(&self) -> Result<String>;
288}
289
290#[cfg(feature="compatibility_v0_10")]
291pub trait IsSelect {}
292
293#[cfg(feature="compatibility_v0_10")]
294pub trait Select<T, I>
295where T: AsStatement<I> + IsSelect
296{
297  fn select(&self, as_statement: &T) -> Result<Vec<I>>;
298}
299
300#[cfg(feature="compatibility_v0_10")]
301pub trait CreateTable<T>
302where T: AsStatement<()>
303{
304  fn create_table(&mut self, as_statement: &T) -> Result<()>;
305}