derive_sql/proxy/
sqlite.rs

1//! SQLite connection - a trait is defined to be implemented by SQLite connection.
2//! This allow functionalities to be added to the connection directly. Two implementations
3//! of the trait are provided: `sqlite::Conn` provide a wrapper around the raw `rusqlite::Conn`;
4//! `sqlite::Log` augments a connection by log the requests.
5use super::*;
6
7#[cfg(feature = "compatibility_v0_10")]
8mod conn; 
9#[cfg(feature = "compatibility_v0_10")]
10pub use conn::Conn;
11#[cfg(feature = "compatibility_v0_10")]
12mod log; 
13#[cfg(feature = "compatibility_v0_10")]
14pub use log::Log;
15
16#[cfg(feature = "compatibility_v0_10")]
17/// Generic trait exposing methods used for interaction with SQLite
18/// in `DeriveSqlite` macro implementation.
19pub trait SqliteTrait {
20  fn execute<P>(&self, sql: &str, params: P) -> Result<usize>
21  where P: rusqlite::Params;
22
23  fn query_first<T, P, F>(&self, sql: &str, params: P, f: F) -> Result<T>
24  where P: rusqlite::Params,
25        F: FnOnce(&rusqlite::Row<'_>) -> rusqlite::Result<T>;
26
27  fn query_map<T, P, F>(&self, sql: &str, params: P, f: F) -> Result<Vec<T>>
28  where P: rusqlite::Params,
29        F: FnMut(&rusqlite::Row<'_>) -> rusqlite::Result<T>;
30
31}
32
33#[cfg(feature = "compatibility_v0_10")]
34/// Auto-implement `Selectable` trait for struct implementing `SqliteTrait`
35impl<T, S, I> traits::Select<T, I> for S
36where S: SqliteTrait,
37      T: traits::AsStatement<I> + traits::IsSelect,
38      I: for<'a> std::convert::TryFrom<&'a rusqlite::Row<'a>, Error = rusqlite::Error>,
39{
40  fn select(&self, s: &T) -> Result<Vec<I>> {
41    self.query_map(s.as_statement()?.as_str(), [], |r| r.try_into())
42  }
43}
44
45#[cfg(feature = "compatibility_v0_10")]
46/// Auto-implement `CreateTable` trait for struct implementing `SqliteTrait`
47impl<T, S> traits::CreateTable<T> for S
48where S: SqliteTrait,
49      T: traits::AsStatement<()>
50{
51  fn create_table(&mut self, s: &T) -> Result<()> {
52    self.execute(s.as_statement()?.as_str(), ())?;
53    Ok(())
54  }
55}
56
57pub struct Row {
58  values: Vec<traits::Value>,
59}
60
61impl std::convert::TryFrom<(usize, &rusqlite::Row<'_>)> for Row {
62  type Error = rusqlite::Error;
63  fn try_from((column_count, row): (usize, &rusqlite::Row<'_>)) -> std::result::Result<Self, Self::Error> {
64    let mut values = Vec::new();
65    for i in 0..column_count {
66      let v = match row.get_ref(i)? {
67        ::rusqlite::types::ValueRef::Null       => traits::Value::Null,
68        ::rusqlite::types::ValueRef::Integer(v) => traits::Value::Integer(v),
69        ::rusqlite::types::ValueRef::Real(v)    => traits::Value::Real(v),
70        ::rusqlite::types::ValueRef::Text(v)    => traits::Value::Text(std::str::from_utf8(v)?.to_string()),
71        ::rusqlite::types::ValueRef::Blob(v)    => traits::Value::Blob(v.to_vec()),
72      };
73      values.push(v);
74    }
75    Ok(Row { values })
76  }
77}
78
79impl traits::Row for Row {
80  fn get_value(&self, i: usize) -> Option<Result<traits::Value>> { 
81    self.values.get(i).map(|v| Ok(v.clone()))
82  }
83}
84
85fn execute<'a, P>(statement: &mut rusqlite::Statement<'a>, params: &P) -> Result<()>
86where P: traits::Params,
87{
88    let params: Vec<traits::Param> = params.as_vec_params()?;
89    let _ = match params.len() {
90      0 => statement.execute(())?,
91      1 => statement.execute([ &params[0] ] )?,
92      2 => statement.execute([ &params[0], &params[1] ] )?,
93      3 => statement.execute([ &params[0], &params[1], &params[2], ] )?,
94      4 => statement.execute([ &params[0], &params[1], &params[2], &params[3], ] )?,
95      5 => statement.execute([ &params[0], &params[1], &params[2], &params[3], &params[4], ] )?,
96      6 => statement.execute([ &params[0], &params[1], &params[2], &params[3], &params[4], &params[5], ] )?,
97      7 => statement.execute([ &params[0], &params[1], &params[2], &params[3], &params[4], &params[5], &params[6], ] )?,
98      8 => statement.execute([ &params[0], &params[1], &params[2], &params[3], &params[4], &params[5], &params[6], &params[7], ] )?,
99      9 => statement.execute([ &params[0], &params[1], &params[2], &params[3], &params[4], &params[5], &params[6], &params[7], &params[8], ] )?,
100     10 => statement.execute([ &params[0], &params[1], &params[2], &params[3], &params[4], &params[5], &params[6], &params[7], &params[8], &params[9], ] )?,
101     11 => statement.execute([ &params[0], &params[1], &params[2], &params[3], &params[4], &params[5], &params[6], &params[7], &params[8], &params[9], &params[10], ] )?,
102     12 => statement.execute([ &params[0], &params[1], &params[2], &params[3], &params[4], &params[5], &params[6], &params[7], &params[8], &params[9], &params[10], &params[11], ] )?,
103     13 => statement.execute([ &params[0], &params[1], &params[2], &params[3], &params[4], &params[5], &params[6], &params[7], &params[8], &params[9], &params[10], &params[11], &params[12], ] )?,
104     14 => statement.execute([ &params[0], &params[1], &params[2], &params[3], &params[4], &params[5], &params[6], &params[7], &params[8], &params[9], &params[10], &params[11], &params[12], &params[13], ] )?,
105     15 => statement.execute([ &params[0], &params[1], &params[2], &params[3], &params[4], &params[5], &params[6], &params[7], &params[8], &params[9], &params[10], &params[11], &params[12], &params[13], &params[14], ] )?,
106     16 => statement.execute([ &params[0], &params[1], &params[2], &params[3], &params[4], &params[5], &params[6], &params[7], &params[8], &params[9], &params[10], &params[11], &params[12], &params[13], &params[14], &params[15], ] )?,
107     17 => statement.execute([ &params[0], &params[1], &params[2], &params[3], &params[4], &params[5], &params[6], &params[7], &params[8], &params[9], &params[10], &params[11], &params[12], &params[13], &params[14], &params[15], &params[16], ] )?,
108      // _ => { self.conn.execute(query, params.iter().collect::<Vec<&traits::Param>>().as_slice())?; },
109      _ => { return Err(Error::MaximumNumberOfParametersExceeded(17, params.len())); },
110    };
111    Ok(())
112}
113
114impl traits::Connection<Row> for rusqlite::Connection
115{
116  fn flavor(&self) -> traits::Flavor { traits::Flavor::SQLite }
117
118  fn execute_with_params<S, P>(&mut self, query: S, params: &P) -> Result<()>
119  where S: std::convert::AsRef<str>,
120        P: traits::Params,
121  {
122    let mut statement = self.prepare(query.as_ref())?;
123    execute(&mut statement, params)
124  }
125
126  fn execute_with_params_iterator<'a, S, I, P>(&mut self, query: S, params_iter: I) -> Result<()>
127  where S: std::convert::AsRef<str>,
128        P: traits::Params + 'a,
129        I: core::iter::IntoIterator<Item = &'a P>
130  {
131    let tx = self.transaction()?;
132    {
133      let mut statement = tx.prepare(query.as_ref())?;
134      for params in params_iter { execute(&mut statement, params)?; }
135    }
136    tx.commit()?;
137    Ok(())
138  }
139
140/*
141  fn execute_with_params_rows<S, P>(&mut self, query: S, params: &P) -> Result<Vec<Row>>
142  where S: std::convert::AsRef<str>,
143        P: traits::Params,
144  {
145    let mut statement = self.prepare(query.as_ref())?;
146    let column_count = statement.column_count();
147
148    let f = |row: &rusqlite::Row<'_>| { Ok((column_count, row).try_into()?) };
149    let params: Vec<traits::Param> = params.as_vec_params()?;
150    let r = match params.len() {
151      0 => statement.query_map((), f)?,
152      1 => statement.query_map([ &params[0] ], f )?,
153      2 => statement.query_map([ &params[0], &params[1] ], f )?,
154      // _ => { self.conn.execute(query, params.iter().collect::<Vec<&traits::Param>>().as_slice())?; },
155      _ => { return Err(Error::NotImplemented); },
156    }
157    .collect::<rusqlite::Result<Vec<Row>>>()?;
158
159    Ok(r)
160  }
161  */
162
163
164  fn query<S>(&mut self, query: S) -> Result<Vec<Row>>
165  where S: std::convert::AsRef<str>
166  {
167    use fallible_iterator::FallibleIterator;
168
169    let mut statement = self.prepare(query.as_ref())?;
170    let column_count = statement.column_count();
171
172    let r = statement.query(())?
173    .map(|row| Ok((column_count, row).try_into()?) )
174    .collect::<Vec<Row>>()?;
175
176    Ok(r)
177  }
178}
179
180#[cfg(test)]
181mod tests {
182  use super::*;
183
184  #[test]
185  fn test_connection() -> Result<()> {
186    let mut conn = rusqlite::Connection::open_in_memory()?;
187
188    proxy_test::run_connection(&mut conn)?;
189
190    let r: Vec<String> = conn.prepare("SELECT name FROM mytable_proxy_conn")?
191    .query_map(
192      (),
193      |r| Ok(r.get(0)?)
194    )?.collect::<rusqlite::Result<Vec<String>>>()?;
195    assert!(r[0].eq("my name"));
196    
197    Ok(())
198  }
199
200  #[test]
201  fn test_run_with_date() -> Result<()> {
202    let mut conn = rusqlite::Connection::open_in_memory()?;
203    proxy_test::run_with_date(&mut conn)?;
204    Ok(())
205  }
206}