|
@@ -1,6 +1,7 @@
|
|
|
//! Simple SQLite
|
|
|
use cdk_common::database::Error;
|
|
|
use cdk_sql_common::database::{DatabaseConnector, DatabaseExecutor, DatabaseTransaction};
|
|
|
+use cdk_sql_common::run_db_operation_sync;
|
|
|
use cdk_sql_common::stmt::{query, Column, SqlPart, Statement};
|
|
|
use rusqlite::{ffi, CachedStatement, Connection, Error as SqliteError, ErrorCode};
|
|
|
use tokio::sync::Mutex;
|
|
@@ -25,7 +26,7 @@ impl AsyncSqlite {
|
|
|
&self,
|
|
|
conn: &'a Connection,
|
|
|
statement: Statement,
|
|
|
- ) -> Result<CachedStatement<'a>, Error> {
|
|
|
+ ) -> Result<(String, CachedStatement<'a>), Error> {
|
|
|
let (sql, placeholder_values) = statement.to_sql()?;
|
|
|
|
|
|
let new_sql = sql.trim().trim_end_matches("FOR UPDATE");
|
|
@@ -39,7 +40,7 @@ impl AsyncSqlite {
|
|
|
.map_err(|e| Error::Database(Box::new(e)))?;
|
|
|
}
|
|
|
|
|
|
- Ok(stmt)
|
|
|
+ Ok((sql, stmt))
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -104,68 +105,81 @@ impl DatabaseExecutor for AsyncSqlite {
|
|
|
async fn execute(&self, statement: Statement) -> Result<usize, Error> {
|
|
|
let conn = self.inner.lock().await;
|
|
|
|
|
|
- let mut stmt = self
|
|
|
+ let (sql, mut stmt) = self
|
|
|
.get_stmt(&conn, statement)
|
|
|
.map_err(|e| Error::Database(Box::new(e)))?;
|
|
|
|
|
|
- Ok(stmt.raw_execute().map_err(to_sqlite_error)?)
|
|
|
+ run_db_operation_sync(&sql, || stmt.raw_execute(), to_sqlite_error)
|
|
|
}
|
|
|
|
|
|
async fn fetch_one(&self, statement: Statement) -> Result<Option<Vec<Column>>, Error> {
|
|
|
let conn = self.inner.lock().await;
|
|
|
- let mut stmt = self
|
|
|
+ let (sql, mut stmt) = self
|
|
|
.get_stmt(&conn, statement)
|
|
|
.map_err(|e| Error::Database(Box::new(e)))?;
|
|
|
|
|
|
- let columns = stmt.column_count();
|
|
|
-
|
|
|
- let mut rows = stmt.raw_query();
|
|
|
- rows.next()
|
|
|
- .map_err(to_sqlite_error)?
|
|
|
- .map(|row| {
|
|
|
- (0..columns)
|
|
|
- .map(|i| row.get(i).map(from_sqlite))
|
|
|
- .collect::<Result<Vec<_>, _>>()
|
|
|
- })
|
|
|
- .transpose()
|
|
|
- .map_err(to_sqlite_error)
|
|
|
+ run_db_operation_sync(
|
|
|
+ &sql,
|
|
|
+ || {
|
|
|
+ let columns = stmt.column_count();
|
|
|
+
|
|
|
+ let mut rows = stmt.raw_query();
|
|
|
+ rows.next()?
|
|
|
+ .map(|row| {
|
|
|
+ (0..columns)
|
|
|
+ .map(|i| row.get(i).map(from_sqlite))
|
|
|
+ .collect::<Result<Vec<_>, _>>()
|
|
|
+ })
|
|
|
+ .transpose()
|
|
|
+ },
|
|
|
+ to_sqlite_error,
|
|
|
+ )
|
|
|
}
|
|
|
|
|
|
async fn fetch_all(&self, statement: Statement) -> Result<Vec<Vec<Column>>, Error> {
|
|
|
let conn = self.inner.lock().await;
|
|
|
- let mut stmt = self
|
|
|
+ let (sql, mut stmt) = self
|
|
|
.get_stmt(&conn, statement)
|
|
|
.map_err(|e| Error::Database(Box::new(e)))?;
|
|
|
|
|
|
let columns = stmt.column_count();
|
|
|
|
|
|
- let mut rows = stmt.raw_query();
|
|
|
- let mut results = vec![];
|
|
|
-
|
|
|
- while let Some(row) = rows.next().map_err(to_sqlite_error)? {
|
|
|
- results.push(
|
|
|
- (0..columns)
|
|
|
- .map(|i| row.get(i).map(from_sqlite))
|
|
|
- .collect::<Result<Vec<_>, _>>()
|
|
|
- .map_err(to_sqlite_error)?,
|
|
|
- )
|
|
|
- }
|
|
|
-
|
|
|
- Ok(results)
|
|
|
+ run_db_operation_sync(
|
|
|
+ &sql,
|
|
|
+ || {
|
|
|
+ let mut rows = stmt.raw_query();
|
|
|
+ let mut results = vec![];
|
|
|
+
|
|
|
+ while let Some(row) = rows.next()? {
|
|
|
+ results.push(
|
|
|
+ (0..columns)
|
|
|
+ .map(|i| row.get(i).map(from_sqlite))
|
|
|
+ .collect::<Result<Vec<_>, _>>()?,
|
|
|
+ )
|
|
|
+ }
|
|
|
+
|
|
|
+ Ok(results)
|
|
|
+ },
|
|
|
+ to_sqlite_error,
|
|
|
+ )
|
|
|
}
|
|
|
|
|
|
async fn pluck(&self, statement: Statement) -> Result<Option<Column>, Error> {
|
|
|
let conn = self.inner.lock().await;
|
|
|
- let mut stmt = self
|
|
|
+ let (sql, mut stmt) = self
|
|
|
.get_stmt(&conn, statement)
|
|
|
.map_err(|e| Error::Database(Box::new(e)))?;
|
|
|
|
|
|
- let mut rows = stmt.raw_query();
|
|
|
- rows.next()
|
|
|
- .map_err(to_sqlite_error)?
|
|
|
- .map(|row| row.get(0usize).map(from_sqlite))
|
|
|
- .transpose()
|
|
|
- .map_err(to_sqlite_error)
|
|
|
+ run_db_operation_sync(
|
|
|
+ &sql,
|
|
|
+ || {
|
|
|
+ let mut rows = stmt.raw_query();
|
|
|
+ rows.next()?
|
|
|
+ .map(|row| row.get(0usize).map(from_sqlite))
|
|
|
+ .transpose()
|
|
|
+ },
|
|
|
+ to_sqlite_error,
|
|
|
+ )
|
|
|
}
|
|
|
|
|
|
async fn batch(&self, mut statement: Statement) -> Result<(), Error> {
|
|
@@ -187,11 +201,8 @@ impl DatabaseExecutor for AsyncSqlite {
|
|
|
unreachable!()
|
|
|
}
|
|
|
};
|
|
|
+ let conn = self.inner.lock().await;
|
|
|
|
|
|
- self.inner
|
|
|
- .lock()
|
|
|
- .await
|
|
|
- .execute_batch(&sql)
|
|
|
- .map_err(to_sqlite_error)
|
|
|
+ run_db_operation_sync(&sql, || conn.execute_batch(&sql), to_sqlite_error)
|
|
|
}
|
|
|
}
|