From 0b756e1d285c470a620e7e322481b108815092a1 Mon Sep 17 00:00:00 2001 From: Justus Winter Date: Thu, 7 Mar 2019 15:56:41 +0100 Subject: [PATCH] New method Database::update_tpk(). --- database/src/lib.rs | 33 +++++++++++++++++++++++++-------- 1 file changed, 25 insertions(+), 8 deletions(-) diff --git a/database/src/lib.rs b/database/src/lib.rs index 43ae1da..51de81c 100644 --- a/database/src/lib.rs +++ b/database/src/lib.rs @@ -163,6 +163,30 @@ pub trait Database: Sync + Send { &self, fpr: &Fingerprint, new: Option, ) -> Result<()>; + /// Update the TPK associated with `fpr` with the TPK in new. + /// + /// If new is None, this removes any associated TPK. + /// + /// This function updates the TPK atomically. That is, readers + /// can continue to read from the associated file and they will + /// either have the old version or the new version, but never an + /// inconsistent mix or a partial version. + /// + /// Note: it is up to the caller to serialize writes. + fn update_tpk(&self, fp: &Fingerprint, new: Option) -> Result<()> { + self.update(fp, if let Some(tpk) = new { + let mut buf = Vec::new(); + { + let mut armor_writer = Writer::new(&mut buf, Kind::PublicKey, + &[][..])?; + tpk.serialize(&mut armor_writer)?; + }; + Some(String::from_utf8_lossy(&buf).to_string()) + } else { + None + }) + } + /// Queries the database using Fingerprint, KeyID, or /// email-address. fn lookup(&self, term: &Query) -> Result> { @@ -281,17 +305,10 @@ pub trait Database: Sync + Send { new_tpk }; - let mut buf = Vec::new(); - { - let mut armor_writer = Writer::new(&mut buf, Kind::PublicKey, - &[][..])?; - tpk.serialize(&mut armor_writer)?; - }; - let armored = String::from_utf8_lossy(&buf); - self.update(&fpr, Some(armored.into_owned()))?; self.link_subkeys(&fpr, tpk.subkeys().map(|s| s.subkey().fingerprint()) .collect())?; + self.update_tpk(&fpr, Some(tpk))?; Ok(()) }