1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86
use crate::{
error::{GenericError, PE},
journal::recover_impl::RecoverImpl,
persy::PersyImpl,
Persy, TransactionId,
};
use std::sync::Arc;
/// Possible state of a transaction in the log
#[derive(PartialEq, Eq, Debug, Clone)]
pub enum RecoverStatus {
/// Started but not completed
Started,
/// Successfully prepared
PrepareCommit,
/// rollback-ed
Rollback,
/// Successfully committed after prepared
Commit,
/// Successfully cleaned up resources after commit
Cleanup,
}
/// Intermediate recover status to select witch transactions to commit or rollback and list witch
/// transactions are in a intermediate state
///
/// # Example
///
///
/// ```rust
/// # use persy::{Persy,Config};
/// # fn main() -> Result<(), Box<dyn std::error::Error>> {
/// # Persy::create("./target/recover_example.persy")?;
/// let mut recover = Persy::recover("./target/recover_example.persy", Config::new())?;
/// for (tx_id,status) in recover.list_transactions() {
/// // Check the transaction if can be committed using the tx_id
/// if true {
/// // if so commit the tx
/// recover.commit(tx_id);
/// } else {
/// // otherwise roll back it
/// recover.rollback(tx_id);
/// }
/// // finalize all the transaction marked to finalize and get a persy instance.
/// }
/// let persy = recover.finalize()?;
/// # std::fs::remove_file("./target/recover_example.persy")?;
/// # Ok(())
/// # }
/// ```
pub struct Recover {
recover_impl: RecoverImpl,
persy_impl: Arc<PersyImpl>,
}
impl Recover {
pub(crate) fn new(recover_impl: RecoverImpl, persy_impl: Arc<PersyImpl>) -> Recover {
Recover {
recover_impl,
persy_impl,
}
}
/// List all the transactions found in the log with the current status
pub fn list_transactions(&self) -> Vec<(TransactionId, RecoverStatus)> {
self.recover_impl.list_transactions()
}
/// Mark to commit a transaction in the log with state prepared commit
pub fn commit(&mut self, tx_id: TransactionId) {
self.recover_impl.commit(tx_id)
}
/// Mark to rollback a transaction that is not yet committed
pub fn rollback(&mut self, tx_id: TransactionId) {
self.recover_impl.rollback(tx_id)
}
/// Read the status of a transaction in the log
pub fn status(&self, tx_id: TransactionId) -> Option<RecoverStatus> {
self.recover_impl.status(tx_id)
}
/// Recover all the prepared committed transactions that are not marked to rollback
pub fn finalize(self) -> Result<Persy, PE<GenericError>> {
self.persy_impl.final_recover(self.recover_impl)?;
Ok(Persy {
persy_impl: self.persy_impl,
})
}
}