use mempill_core::ports::persistence::Txn;
use mempill_types::identity::AgentId;
use rusqlite::Connection;
use crate::SqliteStoreError;
pub struct SqliteTxn {
agent_id: AgentId,
conn: Option<Box<Connection>>,
}
unsafe impl Send for SqliteTxn {}
impl SqliteTxn {
pub(crate) fn begin(
agent_id: AgentId,
conn: Box<Connection>,
) -> Result<Self, SqliteStoreError> {
conn.execute_batch("BEGIN DEFERRED")?;
Ok(Self { agent_id, conn: Some(conn) })
}
pub(crate) fn conn(&self) -> &Connection {
self.conn.as_ref().expect("SqliteTxn: connection must be present (not yet consumed)")
}
pub(crate) fn commit_and_return(mut self) -> Result<Box<Connection>, SqliteStoreError> {
let conn = self.conn.take().expect("SqliteTxn: connection must be present");
conn.execute_batch("COMMIT")?;
Ok(conn)
}
pub(crate) fn rollback_and_return(mut self) -> Result<Box<Connection>, SqliteStoreError> {
let conn = self.conn.take().expect("SqliteTxn: connection must be present");
conn.execute_batch("ROLLBACK")?;
Ok(conn)
}
}
impl Drop for SqliteTxn {
fn drop(&mut self) {
if let Some(ref conn) = self.conn {
let _ = conn.execute_batch("ROLLBACK");
}
}
}
impl Txn for SqliteTxn {
fn agent_id(&self) -> &AgentId {
&self.agent_id
}
}