easy_sqlite/impls/
executor.rs1use rusqlite::{Connection, ToSql};
2use std::cell::RefCell;
3use std::rc::Rc;
4
5use crate::errors::{DbError, DbResult};
6use crate::traits::repo::{IConnection, IExecutor};
7
8pub struct Executor<Cnn: IConnection> {
9 cnn: Cnn,
10}
11
12impl<Cnn: IConnection> Executor<Cnn> {
13 #[inline]
14 pub fn new(cnn: Cnn) -> Self {
15 Self { cnn }
16 }
17}
18
19fn signal_error() -> rusqlite::Error {
20 rusqlite::Error::ExecuteReturnedResults
21}
22
23fn unwrap_err<T>(
24 handler: &RefCell<Option<DbError>>,
25 res: Result<T, rusqlite::Error>,
26) -> Result<T, DbError> {
27 if let Some(ref val) = *handler.borrow() {
28 Err(val.clone())
29 } else {
30 Ok(res?)
31 }
32}
33
34impl<Cnn: IConnection> IExecutor for Executor<Cnn> {
35 type Locked = Executor<Cnn::Locked>;
36
37 fn lock(&self) -> DbResult<Self::Locked> {
38 Ok(Executor::new(self.cnn.lock_sync()?))
39 }
40
41 fn get_one<T, F: FnMut(&rusqlite::Row<'_>) -> DbResult<T>>(
42 &self,
43 query: &str,
44 params: &[&dyn ToSql],
45 mut serializer: F,
46 ) -> DbResult<T> {
47 let real_error = Rc::new(RefCell::new(None));
48 let err_handler_copy = real_error.clone();
49 let m_serializer = move |row: &rusqlite::Row| -> rusqlite::Result<T> {
50 let other_copy = err_handler_copy.clone();
51 serializer(row).map_err(move |err| {
52 *other_copy.borrow_mut() = Some(err);
53 signal_error()
54 })
55 };
56 let fun = move |cnn: &Connection| -> DbResult<T> {
57 let mut statement = cnn.prepare(query)?;
58 let qmap = statement.query_map(params, m_serializer);
59 let val = unwrap_err(&real_error, qmap)?.next();
60 match val {
61 Some(val) => unwrap_err(&real_error, val),
62 None => Err(DbError::NotFound(None)),
63 }
64 };
65 self.cnn.with(fun)
66 }
67
68 fn get_many<T, F: FnMut(&rusqlite::Row<'_>) -> DbResult<T>>(
69 &self,
70 query: &str,
71 params: &[&dyn ToSql],
72 mut serializer: F,
73 ) -> DbResult<Vec<T>> {
74 let real_error = Rc::new(RefCell::new(None));
75 let err_handler_copy = real_error.clone();
76 let m_serializer = move |row: &rusqlite::Row| -> rusqlite::Result<T> {
77 serializer(row).map_err(|err| {
78 *err_handler_copy.borrow_mut() = Some(err);
79 signal_error()
80 })
81 };
82 let fun = move |cnn: &Connection| -> DbResult<Vec<T>> {
83 let mut statement = cnn.prepare(query)?;
84 let qmap = statement.query_map(params, m_serializer);
85 let val = unwrap_err(&real_error, qmap)?
86 .map(|res| unwrap_err(&real_error, res))
87 .collect::<Result<Vec<T>, _>>()?;
88 Ok(val)
89 };
90 self.cnn.with(fun)
91 }
92
93 fn execute(&self, query: &str, params: &[&dyn ToSql]) -> DbResult<()> {
94 self.cnn.with(move |cnn| {
95 cnn.execute(query, params)?;
96 Ok(())
97 })
98 }
99
100 fn execute_return_id(&self, query: &str, params: &[&dyn ToSql]) -> DbResult<i64> {
101 self.cnn.with(move |cnn| {
102 cnn.execute(query, params)?;
103 Ok(cnn.last_insert_rowid())
104 })
105 }
106}