executor_sqlx_sqlite.rs (3245B)
1 use std::path::Path; 2 use std::sync::{Arc, Mutex}; 3 4 use sqlx::Connection; 5 use sqlx::sqlite::{SqliteConnectOptions, SqliteConnection}; 6 7 use crate::sqlx_sqlite_util; 8 use crate::{ExecOutcome, SqlExecutor, error::SqlError}; 9 10 pub struct SqlxSqliteExecutor { 11 conn: Arc<Mutex<SqliteConnection>>, 12 } 13 14 impl SqlxSqliteExecutor { 15 pub fn open<P: AsRef<Path>>(path: P) -> Result<Self, SqlError> { 16 let options = SqliteConnectOptions::new() 17 .filename(path) 18 .create_if_missing(true); 19 Self::connect(options) 20 } 21 22 pub fn open_memory() -> Result<Self, SqlError> { 23 Self::connect(SqliteConnectOptions::new().in_memory(true)) 24 } 25 26 fn connect(options: SqliteConnectOptions) -> Result<Self, SqlError> { 27 let conn = futures_executor::block_on(SqliteConnection::connect_with(&options))?; 28 Ok(Self { 29 conn: Arc::new(Mutex::new(conn)), 30 }) 31 } 32 } 33 34 impl SqlExecutor for SqlxSqliteExecutor { 35 fn exec(&self, sql: &str, params_json: &str) -> Result<ExecOutcome, SqlError> { 36 let binds = sqlx_sqlite_util::parse_params(params_json)?; 37 let mut conn = self.conn.lock().map_err(|_| SqlError::Internal)?; 38 if binds.is_empty() { 39 let result = futures_executor::block_on( 40 sqlx::raw_sql(sqlx::AssertSqlSafe(sql)).execute(&mut *conn), 41 )?; 42 return Ok(ExecOutcome { 43 changes: i64::try_from(result.rows_affected()).map_err(|_| SqlError::Internal)?, 44 last_insert_id: result.last_insert_rowid(), 45 }); 46 } 47 let query = sqlx_sqlite_util::bind_params(sqlx::query(sqlx::AssertSqlSafe(sql)), binds)?; 48 let result = futures_executor::block_on(query.execute(&mut *conn))?; 49 Ok(ExecOutcome { 50 changes: i64::try_from(result.rows_affected()).map_err(|_| SqlError::Internal)?, 51 last_insert_id: result.last_insert_rowid(), 52 }) 53 } 54 55 fn query_raw(&self, sql: &str, params_json: &str) -> Result<String, SqlError> { 56 let binds = sqlx_sqlite_util::parse_params(params_json)?; 57 let query = sqlx_sqlite_util::bind_params(sqlx::query(sqlx::AssertSqlSafe(sql)), binds)?; 58 let rows = { 59 let mut conn = self.conn.lock().map_err(|_| SqlError::Internal)?; 60 futures_executor::block_on(query.fetch_all(&mut *conn))? 61 }; 62 let rows = rows 63 .iter() 64 .map(sqlx_sqlite_util::row_to_json) 65 .collect::<Result<Vec<_>, _>>()?; 66 Ok(serde_json::Value::from(rows).to_string()) 67 } 68 69 fn begin(&self) -> Result<(), SqlError> { 70 let mut conn = self.conn.lock().map_err(|_| SqlError::Internal)?; 71 futures_executor::block_on(sqlx::query("BEGIN").execute(&mut *conn))?; 72 Ok(()) 73 } 74 75 fn commit(&self) -> Result<(), SqlError> { 76 let mut conn = self.conn.lock().map_err(|_| SqlError::Internal)?; 77 futures_executor::block_on(sqlx::query("COMMIT").execute(&mut *conn))?; 78 Ok(()) 79 } 80 81 fn rollback(&self) -> Result<(), SqlError> { 82 let mut conn = self.conn.lock().map_err(|_| SqlError::Internal)?; 83 futures_executor::block_on(sqlx::query("ROLLBACK").execute(&mut *conn))?; 84 Ok(()) 85 } 86 }