derive_sql/proxy/
mysql.rs1use super::*;
2
3#[cfg(feature="compatibility_v0_10")]
4mod conn;
5#[cfg(feature="compatibility_v0_10")]
6pub use conn::Conn;
7#[cfg(feature="compatibility_v0_10")]
8mod log;
9#[cfg(feature="compatibility_v0_10")]
10pub use log::Log;
11
12#[cfg(feature="compatibility_v0_10")]
13pub trait MysqlTrait {
16 fn query_drop<Q>(&mut self, query: Q) -> Result<()>
17 where Q: AsRef<str>;
18
19 fn query_first<T, Q>(&mut self, query: Q) -> Result<Option<T>>
20 where Q: AsRef<str>,
21 T: ::mysql::prelude::FromRow;
22
23 fn query_map<T, F, Q, U>(&mut self, query: Q, f: F) -> Result<Vec<U>>
24 where Q: AsRef<str>,
25 T: ::mysql::prelude::FromRow,
26 F: FnMut(T) -> U;
27
28 fn exec_drop<Q, P>(&mut self, query: Q, params: P) -> Result<()>
29 where Q: AsRef<str>,
30 P: Into<::mysql::Params>;
31}
32
33#[cfg(feature="compatibility_v0_10")]
34pub struct MysqlProxy<T>
35where T: ::mysql::prelude::Queryable,
36{
37 conn: T
38}
39
40#[cfg(feature="compatibility_v0_10")]
41impl<T> From<T> for MysqlProxy<T>
42where T: ::mysql::prelude::Queryable,
43{
44 fn from(conn: T) -> Self {
45 MysqlProxy { conn }
46 }
47}
48
49#[cfg(feature="compatibility_v0_10")]
50impl<T> traits::ExecuteTrait for MysqlProxy<T>
51where T: ::mysql::prelude::Queryable,
52{
53 fn execute_with_params<P>(&mut self, query: &str, params: P) -> Result<()>
54 where P: traits::Params
55 {
56 let params = params.as_vec_params()?
57 .into_iter()
58 .map(|p| std::convert::TryInto::<::mysql::Value>::try_into(p))
59 .collect::<Result<Vec<::mysql::Value>>>()?;
60 self.conn.exec_drop(query, params)?;
61 Ok(())
62 }
63}
64
65pub struct Row {
66 row: ::mysql::Row,
67}
68
69impl ::mysql::prelude::FromRow for Row {
70 fn from_row_opt(row: ::mysql::Row) -> std::result::Result<Row, ::mysql::FromRowError> {
71 Ok(Row { row } )
72 }
73}
74
75impl traits::Row for Row {
76 fn get_value(&self, i: usize) -> Option<Result<traits::Value>> {
77 let v: Option<core::result::Result<::mysql::Value, _>> = self.row.get_opt(i);
78 if let Some(Ok(v)) = v {
79 let v: Result<traits::Value> = v.try_into();
80 Some(v)
81
82 } else if let Some(Err(e)) = v {
83 Some(Err(e.into()))
84
85 } else {
86 None
87 }
88 }
89}
90
91#[cfg(feature="compatibility_v0_10")]
137impl<T> traits::QueryTrait<Row> for MysqlProxy<T>
138where T: ::mysql::prelude::Queryable,
139{
140 fn query_row(&mut self, query: &str) -> Result<Vec<Row>> {
141 Ok( self.conn.query_map(query, |r: Row| r )? )
142 }
143}
144
145trait Transaction {
149 fn start_transaction(&mut self, tx_opts: ::mysql::TxOpts) -> Result<::mysql::Transaction>;
150}
151
152impl Transaction for ::mysql::Conn {
153 fn start_transaction(&mut self, tx_opts: ::mysql::TxOpts) -> Result<::mysql::Transaction> {
154 Ok(self.start_transaction(tx_opts)?)
155 }
156}
157
158impl Transaction for ::mysql::PooledConn {
159 fn start_transaction(&mut self, tx_opts: ::mysql::TxOpts) -> Result<::mysql::Transaction> {
160 Ok(self.start_transaction(tx_opts)?)
161 }
162}
163
164impl<T> traits::Connection<Row> for T
165where T: ::mysql::prelude::Queryable + Transaction,
166{
167 fn flavor(&self) -> traits::Flavor { traits::Flavor::MySQL }
168
169 fn execute_with_params<S, P>(&mut self, query: S, params: &P) -> Result<()>
170 where S: std::convert::AsRef<str>,
171 P: traits::Params,
172 {
173 let params = params.as_vec_params()?
174 .into_iter()
175 .map(|p| std::convert::TryInto::<::mysql::Value>::try_into(p))
176 .collect::<Result<Vec<::mysql::Value>>>()?;
177 self.exec_drop(query, params)?;
178 Ok(())
179 }
180
181 fn execute_with_params_iterator<'a, S, I, P>(&mut self, query: S, params_iter: I) -> Result<()>
182 where S: std::convert::AsRef<str>,
183 P: traits::Params + 'a,
184 I: core::iter::IntoIterator<Item = &'a P>
185 {
186 use ::mysql::prelude::Queryable;
187 let params_arr = params_iter
188 .into_iter()
189 .map(|params|
190 params.as_vec_params()?.into_iter()
191 .map(|p| std::convert::TryInto::<::mysql::Value>::try_into(p))
192 .collect::<Result<Vec<::mysql::Value>>>()
193 )
194 .collect::<Result<Vec<Vec<::mysql::Value>>>>()?;
195
196 let mut conn = self.start_transaction(::mysql::TxOpts::default())?;
197 let statement = conn.prep(query)?;
198 conn.exec_batch(statement, params_arr.into_iter())?;
199 conn.commit()?;
200 Ok(())
201 }
202
203fn query<S>(&mut self, query: S) -> Result<Vec<Row>>
217 where S: std::convert::AsRef<str>
218 {
219 Ok( self.query_map(query, |r: Row| r)? )
220 }
221}
222
223#[cfg(test)]
224mod tests {
225 use super::*;
226
227 #[test]
228 fn test_connection() -> Result<()> {
229 let mut conn = ::mysql::Conn::new(
230 ::mysql::Opts::from_url("mysql://test@localhost/simpledb").unwrap()
231 )?;
232
233 proxy_test::run_connection(&mut conn)?;
234
235 use ::mysql::prelude::Queryable;
236 let r: Vec<String> = conn.query_map("SELECT name FROM mytable_proxy_conn", |r: String| r)?;
237 assert!(r[0].eq("my name"));
238
239 Ok(())
240 }
241
242 #[test]
243 fn test_run_with_date() -> Result<()> {
244 let mut conn = ::mysql::Conn::new(
245 ::mysql::Opts::from_url("mysql://test@localhost/simpledb").unwrap()
246 )?;
247 proxy_test::run_with_date(&mut conn)?;
248 Ok(())
249 }
250}
251