lib

Core libraries for Radroots
git clone https://radroots.dev/git/lib.git
Log | Files | Refs | README | LICENSE

executor_sqlite.rs (2800B)


      1 use crate::sqlite_util;
      2 use crate::{ExecOutcome, SqlExecutor, error::SqlError};
      3 use rusqlite::{Connection, params_from_iter};
      4 use serde_json::Value;
      5 use std::path::Path;
      6 use std::sync::{Arc, Mutex};
      7 
      8 pub struct SqliteExecutor {
      9     conn: Arc<Mutex<Connection>>,
     10 }
     11 
     12 impl SqliteExecutor {
     13     pub fn open<P: AsRef<Path>>(path: P) -> Result<Self, SqlError> {
     14         let conn = Connection::open(path).map_err(SqlError::from)?;
     15         Ok(Self {
     16             conn: Arc::new(Mutex::new(conn)),
     17         })
     18     }
     19 
     20     pub fn open_memory() -> Result<Self, SqlError> {
     21         let conn = Connection::open_in_memory().map_err(SqlError::from)?;
     22         Ok(Self {
     23             conn: Arc::new(Mutex::new(conn)),
     24         })
     25     }
     26 }
     27 
     28 impl SqlExecutor for SqliteExecutor {
     29     fn exec(&self, sql: &str, params_json: &str) -> Result<ExecOutcome, SqlError> {
     30         let binds = sqlite_util::parse_params(params_json)?;
     31         let conn = self.conn.lock().map_err(|_| SqlError::Internal)?;
     32         if binds.is_empty() {
     33             let total_changes_before = conn.total_changes();
     34             conn.execute_batch(sql).map_err(SqlError::from)?;
     35             let total_changes_after = conn.total_changes();
     36             let last_insert_id = conn.last_insert_rowid();
     37             return Ok(ExecOutcome {
     38                 changes: (total_changes_after - total_changes_before) as i64,
     39                 last_insert_id,
     40             });
     41         }
     42         let n = conn
     43             .execute(sql, params_from_iter(binds))
     44             .map_err(SqlError::from)?;
     45         let last_insert_id = conn.last_insert_rowid();
     46         Ok(ExecOutcome {
     47             changes: n as i64,
     48             last_insert_id,
     49         })
     50     }
     51 
     52     fn query_raw(&self, sql: &str, params_json: &str) -> Result<String, SqlError> {
     53         let binds = sqlite_util::parse_params(params_json)?;
     54         let rows = {
     55             let conn = self.conn.lock().map_err(|_| SqlError::Internal)?;
     56             let mut stmt = conn.prepare(sql).map_err(SqlError::from)?;
     57             let mapped = stmt.query_map(params_from_iter(binds), sqlite_util::row_to_json)?;
     58             mapped.collect::<Result<Vec<_>, _>>()?
     59         };
     60         Ok(Value::from(rows).to_string())
     61     }
     62 
     63     fn begin(&self) -> Result<(), SqlError> {
     64         let conn = self.conn.lock().map_err(|_| SqlError::Internal)?;
     65         conn.execute("BEGIN", []).map_err(SqlError::from)?;
     66         Ok(())
     67     }
     68 
     69     fn commit(&self) -> Result<(), SqlError> {
     70         let conn = self.conn.lock().map_err(|_| SqlError::Internal)?;
     71         conn.execute("COMMIT", []).map_err(SqlError::from)?;
     72         Ok(())
     73     }
     74 
     75     fn rollback(&self) -> Result<(), SqlError> {
     76         let conn = self.conn.lock().map_err(|_| SqlError::Internal)?;
     77         conn.execute("ROLLBACK", []).map_err(SqlError::from)?;
     78         Ok(())
     79     }
     80 }