repo: Add `auto_transaction` and `TransactionGuard`
This gives auto-cancelling semantics on `Drop`, plus a nicer `.commit()` method on the transaction. Matches the currently private `_OstreeRepoAutoTransaction` in the C library.
This commit is contained in:
parent
69950574f7
commit
f8852ca945
|
|
@ -1,6 +1,6 @@
|
||||||
#[cfg(any(feature = "v2016_4", feature = "dox"))]
|
#[cfg(any(feature = "v2016_4", feature = "dox"))]
|
||||||
use crate::RepoListRefsExtFlags;
|
use crate::RepoListRefsExtFlags;
|
||||||
use crate::{Checksum, ObjectName, ObjectType, Repo};
|
use crate::{Checksum, ObjectName, ObjectType, Repo, RepoTransactionStats};
|
||||||
use ffi;
|
use ffi;
|
||||||
use glib::ffi as glib_sys;
|
use glib::ffi as glib_sys;
|
||||||
use glib::{self, translate::*, Error, IsA};
|
use glib::{self, translate::*, Error, IsA};
|
||||||
|
|
@ -34,12 +34,51 @@ unsafe fn from_glib_container_variant_set(ptr: *mut glib_sys::GHashTable) -> Has
|
||||||
set
|
set
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// An open transaction in the repository.
|
||||||
|
///
|
||||||
|
/// This will automatically invoke [`ostree::Repo::abort_transaction`] when the value is dropped.
|
||||||
|
pub struct TransactionGuard<'a> {
|
||||||
|
/// Reference to the repository for this transaction.
|
||||||
|
repo: Option<&'a Repo>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> TransactionGuard<'a> {
|
||||||
|
/// Commit this transaction.
|
||||||
|
pub fn commit<P: IsA<gio::Cancellable>>(
|
||||||
|
mut self,
|
||||||
|
cancellable: Option<&P>,
|
||||||
|
) -> Result<RepoTransactionStats, glib::Error> {
|
||||||
|
// Safety: This is the only function which mutates this option
|
||||||
|
let repo = self.repo.take().unwrap();
|
||||||
|
repo.commit_transaction(cancellable)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Drop for TransactionGuard<'a> {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
if let Some(repo) = self.repo {
|
||||||
|
// TODO: better logging in ostree?
|
||||||
|
// See also https://github.com/ostreedev/ostree/issues/2413
|
||||||
|
let _ = repo.abort_transaction(gio::NONE_CANCELLABLE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Repo {
|
impl Repo {
|
||||||
/// Create a new `Repo` object for working with an OSTree repo at the given path.
|
/// Create a new `Repo` object for working with an OSTree repo at the given path.
|
||||||
pub fn new_for_path<P: AsRef<Path>>(path: P) -> Repo {
|
pub fn new_for_path<P: AsRef<Path>>(path: P) -> Repo {
|
||||||
Repo::new(&gio::File::for_path(path.as_ref()))
|
Repo::new(&gio::File::for_path(path.as_ref()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A wrapper for [`prepare_transaction`] which ensures the transaction will be aborted when the guard goes out of scope.
|
||||||
|
pub fn auto_transaction<P: IsA<gio::Cancellable>>(
|
||||||
|
&self,
|
||||||
|
cancellable: Option<&P>,
|
||||||
|
) -> Result<TransactionGuard, glib::Error> {
|
||||||
|
let _ = self.prepare_transaction(cancellable)?;
|
||||||
|
Ok(TransactionGuard { repo: Some(self) })
|
||||||
|
}
|
||||||
|
|
||||||
/// Return a copy of the directory file descriptor for this repository.
|
/// Return a copy of the directory file descriptor for this repository.
|
||||||
#[cfg(any(feature = "v2016_4", feature = "dox"))]
|
#[cfg(any(feature = "v2016_4", feature = "dox"))]
|
||||||
#[cfg_attr(feature = "dox", doc(cfg(feature = "v2016_4")))]
|
#[cfg_attr(feature = "dox", doc(cfg(feature = "v2016_4")))]
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,8 @@ pub fn create_mtree(repo: &ostree::Repo) -> ostree::MutableTree {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn commit(repo: &ostree::Repo, mtree: &ostree::MutableTree, ref_: &str) -> GString {
|
pub fn commit(repo: &ostree::Repo, mtree: &ostree::MutableTree, ref_: &str) -> GString {
|
||||||
repo.prepare_transaction(NONE_CANCELLABLE)
|
let txn = repo
|
||||||
|
.auto_transaction(NONE_CANCELLABLE)
|
||||||
.expect("prepare transaction");
|
.expect("prepare transaction");
|
||||||
let repo_file = repo
|
let repo_file = repo
|
||||||
.write_mtree(mtree, NONE_CANCELLABLE)
|
.write_mtree(mtree, NONE_CANCELLABLE)
|
||||||
|
|
@ -60,8 +61,7 @@ pub fn commit(repo: &ostree::Repo, mtree: &ostree::MutableTree, ref_: &str) -> G
|
||||||
)
|
)
|
||||||
.expect("write commit");
|
.expect("write commit");
|
||||||
repo.transaction_set_ref(None, ref_, checksum.as_str().into());
|
repo.transaction_set_ref(None, ref_, checksum.as_str().into());
|
||||||
repo.commit_transaction(NONE_CANCELLABLE)
|
txn.commit(NONE_CANCELLABLE).expect("commit transaction");
|
||||||
.expect("commit transaction");
|
|
||||||
checksum
|
checksum
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue