use super::connection::Connection;
use super::error::DbResult;
use super::statement::{Row, Statement};
use super::value::Value;
pub struct Transaction<'conn> {
conn: &'conn Connection,
committed: bool,
}
impl<'conn> Transaction<'conn> {
pub(super) fn begin(conn: &'conn Connection, immediate: bool) -> DbResult<Self> {
let sql = if immediate {
"BEGIN IMMEDIATE"
} else {
"BEGIN DEFERRED"
};
conn.execute_batch(sql)?;
Ok(Self {
conn,
committed: false,
})
}
pub fn commit(mut self) -> DbResult<()> {
self.conn.execute_batch("COMMIT")?;
self.committed = true;
Ok(())
}
#[allow(dead_code)]
pub fn execute_batch(&self, sql: &str) -> DbResult<()> {
self.conn.execute_batch(sql)
}
pub fn execute(&self, sql: &str, params: &[Value]) -> DbResult<usize> {
self.conn.execute(sql, params)
}
pub fn query_row<T>(
&self,
sql: &str,
params: &[Value],
mapper: impl FnOnce(&Row<'_, '_>) -> DbResult<T>,
) -> DbResult<T> {
self.conn.query_row(sql, params, mapper)
}
pub fn prepare(&self, sql: &str) -> DbResult<Statement<'_>> {
self.conn.prepare(sql)
}
}
impl Drop for Transaction<'_> {
fn drop(&mut self) {
if !self.committed {
let _ = self.conn.execute_batch("ROLLBACK");
}
}
}