use crate::ast::ast::CommitStatement;
use crate::exec::write_stmt::{ExecutionContext, StatementExecutor, TransactionStatementExecutor};
use crate::exec::{ExecutionError, QueryResult, Row};
use crate::storage::value::Value;
use crate::txn::{log::TransactionLog, state::OperationType};
use std::collections::HashMap;
use std::sync::RwLock;
pub struct CommitExecutor {
}
impl CommitExecutor {
pub fn new(_statement: CommitStatement) -> Self {
Self {}
}
}
impl StatementExecutor for CommitExecutor {
fn operation_type(&self) -> OperationType {
OperationType::Commit
}
fn operation_description(&self, _context: &ExecutionContext) -> String {
"COMMIT".to_string()
}
fn requires_write_permission(&self) -> bool {
false }
}
impl TransactionStatementExecutor for CommitExecutor {
fn execute_transaction_operation(
&self,
context: &ExecutionContext,
) -> Result<QueryResult, ExecutionError> {
let transaction_state = context.transaction_state().ok_or_else(|| {
ExecutionError::RuntimeError("No transaction state available".to_string())
})?;
transaction_state.commit_transaction()?;
let message = "Transaction committed successfully";
Ok(QueryResult {
rows: vec![Row::from_values(HashMap::from([(
"status".to_string(),
Value::String(message.to_string()),
)]))],
variables: vec!["status".to_string()],
execution_time_ms: 0,
rows_affected: 0,
session_result: None,
warnings: Vec::new(),
})
}
}
impl CommitExecutor {
#[allow(dead_code)] pub fn execute_commit(
_statement: &CommitStatement,
transaction_manager: &crate::txn::TransactionManager,
current_transaction: &RwLock<Option<crate::txn::TransactionId>>,
transaction_logs: &RwLock<HashMap<crate::txn::TransactionId, TransactionLog>>,
) -> Result<QueryResult, ExecutionError> {
let current_txn = current_transaction.read().map_err(|_| {
ExecutionError::RuntimeError("Failed to acquire transaction lock".to_string())
})?;
let txn_id = match *current_txn {
Some(id) => id,
None => {
drop(current_txn);
return Err(ExecutionError::RuntimeError(
"No transaction in progress".to_string(),
));
}
};
drop(current_txn);
transaction_manager.commit_transaction(txn_id)?;
{
let mut logs = transaction_logs.write().map_err(|_| {
ExecutionError::RuntimeError("Failed to acquire transaction logs lock".to_string())
})?;
logs.remove(&txn_id);
}
{
let mut current_txn = current_transaction.write().map_err(|_| {
ExecutionError::RuntimeError("Failed to acquire transaction lock".to_string())
})?;
*current_txn = None;
}
let message = "Transaction committed successfully";
Ok(QueryResult {
rows: vec![Row::from_values(HashMap::from([(
"status".to_string(),
Value::String(message.to_string()),
)]))],
variables: vec!["status".to_string()],
execution_time_ms: 0,
rows_affected: 0,
session_result: None,
warnings: Vec::new(),
})
}
}