diff --git a/CHANGELOG.md b/CHANGELOG.md index 7fd49a206..4b5f2eac8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,7 +19,7 @@ - place common headers like `From:` before the large `Autocrypt:` header #3079 - keep track of securejoin joiner status in database to survive restarts #2920 - remove never used `SentboxMove` option #3111 -- improve speed by caching config values +- improve speed by caching config values #3131 #3145 - optimize `markseen_msgs` #3141 - automatically accept chats with outgoing messages #3143 diff --git a/src/imex.rs b/src/imex.rs index 9784e34c0..b24ef97bc 100644 --- a/src/imex.rs +++ b/src/imex.rs @@ -460,6 +460,8 @@ async fn import_backup( context.get_dbfile().display() ); + context.sql.config_cache.write().await.clear(); + let archive = Archive::new(backup_file); let mut entries = archive.entries()?; @@ -901,6 +903,54 @@ mod tests { } } + #[async_std::test] + async fn test_export_and_import_backup() -> Result<()> { + let backup_dir = tempfile::tempdir().unwrap(); + + let context1 = TestContext::new_alice().await; + assert!(context1.is_configured().await?); + + let context2 = TestContext::new().await; + assert!(!context2.is_configured().await?); + assert!(has_backup(&context2, backup_dir.path().as_ref()) + .await + .is_err()); + + // export from context1 + assert!(imex( + &context1, + ImexMode::ExportBackup, + backup_dir.path().as_ref(), + None, + ) + .await + .is_ok()); + let _event = context1 + .evtracker + .get_matching(|evt| matches!(evt, EventType::ImexProgress(1000))) + .await; + + // import to context2 + let backup = has_backup(&context2, backup_dir.path().as_ref()).await?; + assert!( + imex(&context2, ImexMode::ImportBackup, backup.as_ref(), None) + .await + .is_ok() + ); + let _event = context2 + .evtracker + .get_matching(|evt| matches!(evt, EventType::ImexProgress(1000))) + .await; + + assert!(context2.is_configured().await?); + assert_eq!( + context2.get_config(Config::Addr).await?, + Some("alice@example.org".to_string()) + ); + + Ok(()) + } + #[test] fn test_normalize_setup_code() { let norm = normalize_setup_code("123422343234423452346234723482349234"); diff --git a/src/sql.rs b/src/sql.rs index 59c449010..f4da4333b 100644 --- a/src/sql.rs +++ b/src/sql.rs @@ -48,7 +48,7 @@ pub struct Sql { /// open without a passphrase. is_encrypted: RwLock>, - config_cache: RwLock>>, + pub(crate) config_cache: RwLock>>, } impl Sql { @@ -501,6 +501,7 @@ impl Sql { pub async fn set_raw_config(&self, key: impl AsRef, value: Option<&str>) -> Result<()> { let key = key.as_ref(); + let mut lock = self.config_cache.write().await; if let Some(value) = value { let exists = self .exists( @@ -526,8 +527,6 @@ impl Sql { self.execute("DELETE FROM config WHERE keyname=?;", paramsv![key]) .await?; } - - let mut lock = self.config_cache.write().await; lock.insert(key.to_string(), value.map(|s| s.to_string())); drop(lock); @@ -544,6 +543,7 @@ impl Sql { return Ok(c); } + let mut lock = self.config_cache.write().await; let value = self .query_get_value( "SELECT value FROM config WHERE keyname=?;", @@ -551,8 +551,6 @@ impl Sql { ) .await .context(format!("failed to fetch raw config: {}", key.as_ref()))?; - - let mut lock = self.config_cache.write().await; lock.insert(key.as_ref().to_string(), value.clone()); drop(lock); diff --git a/src/sql/migrations.rs b/src/sql/migrations.rs index c060bbbae..9874c1d82 100644 --- a/src/sql/migrations.rs +++ b/src/sql/migrations.rs @@ -36,6 +36,13 @@ pub async fn run(context: &Context, sql: &Sql) -> Result<(bool, bool, bool, bool Ok(()) }) .await?; + + let mut lock = context.sql.config_cache.write().await; + lock.insert( + VERSION_CFG.to_string(), + Some(format!("{}", dbversion_before_update)), + ); + drop(lock); } else { exists_before_update = true; dbversion_before_update = sql