diff --git a/src/database.rs b/src/database.rs index 6156c7e0..5e145acd 100644 --- a/src/database.rs +++ b/src/database.rs @@ -570,7 +570,7 @@ impl KeyValueDatabase { if services().users.count()? > 0 { // MIGRATIONS - if services().globals.database_version()? < 1 { + migration(1, || { for (roomserverid, _) in db.roomserverids.iter() { let mut parts = roomserverid.split(|&b| b == 0xFF); let room_id = @@ -585,13 +585,10 @@ impl KeyValueDatabase { db.serverroomids.insert(&serverroomid, &[])?; } + Ok(()) + })?; - services().globals.bump_database_version(1)?; - - warn!("Migration: 0 -> 1 finished"); - } - - if services().globals.database_version()? < 2 { + migration(2, || { // We accidentally inserted hashed versions of "" into the db // instead of just "" for (userid, password) in db.userid_password.iter() { @@ -606,13 +603,10 @@ impl KeyValueDatabase { db.userid_password.insert(&userid, b"")?; } } + Ok(()) + })?; - services().globals.bump_database_version(2)?; - - warn!("Migration: 1 -> 2 finished"); - } - - if services().globals.database_version()? < 3 { + migration(3, || { // Move media to filesystem for (key, content) in db.mediaid_file.iter() { let key = MediaFileKey::new(key); @@ -625,13 +619,10 @@ impl KeyValueDatabase { file.write_all(&content)?; db.mediaid_file.insert(key.as_bytes(), &[])?; } + Ok(()) + })?; - services().globals.bump_database_version(3)?; - - warn!("Migration: 2 -> 3 finished"); - } - - if services().globals.database_version()? < 4 { + migration(4, || { // Add federated users to services() as deactivated for our_user in services().users.iter() { let our_user = our_user?; @@ -654,13 +645,10 @@ impl KeyValueDatabase { } } } + Ok(()) + })?; - services().globals.bump_database_version(4)?; - - warn!("Migration: 3 -> 4 finished"); - } - - if services().globals.database_version()? < 5 { + migration(5, || { // Upgrade user data store for (roomuserdataid, _) in db.roomuserdataid_accountdata.iter() { @@ -679,13 +667,10 @@ impl KeyValueDatabase { db.roomusertype_roomuserdataid .insert(&key, &roomuserdataid)?; } + Ok(()) + })?; - services().globals.bump_database_version(5)?; - - warn!("Migration: 4 -> 5 finished"); - } - - if services().globals.database_version()? < 6 { + migration(6, || { // Set room member count for (roomid, _) in db.roomid_shortstatehash.iter() { let string = utils::string_from_bytes(&roomid).unwrap(); @@ -695,13 +680,10 @@ impl KeyValueDatabase { .state_cache .update_joined_count(room_id)?; } + Ok(()) + })?; - services().globals.bump_database_version(6)?; - - warn!("Migration: 5 -> 6 finished"); - } - - if services().globals.database_version()? < 7 { + migration(7, || { // Upgrade state store let mut last_roomstates: HashMap = HashMap::new(); @@ -833,13 +815,10 @@ impl KeyValueDatabase { &mut last_roomstates, )?; } + Ok(()) + })?; - services().globals.bump_database_version(7)?; - - warn!("Migration: 6 -> 7 finished"); - } - - if services().globals.database_version()? < 8 { + migration(8, || { // Generate short room ids for all rooms for (room_id, _) in db.roomid_shortstatehash.iter() { let shortroomid = @@ -892,13 +871,10 @@ impl KeyValueDatabase { }); db.eventid_pduid.insert_batch(&mut batch2)?; + Ok(()) + })?; - services().globals.bump_database_version(8)?; - - warn!("Migration: 7 -> 8 finished"); - } - - if services().globals.database_version()? < 9 { + migration(9, || { // Update tokenids db layout let mut iter = db .tokenids @@ -942,13 +918,10 @@ impl KeyValueDatabase { for key in batch2 { db.tokenids.remove(&key)?; } + Ok(()) + })?; - services().globals.bump_database_version(9)?; - - warn!("Migration: 8 -> 9 finished"); - } - - if services().globals.database_version()? < 10 { + migration(10, || { // Add other direction for shortstatekeys for (statekey, shortstatekey) in db.statekey_shortstatekey.iter() @@ -962,20 +935,15 @@ impl KeyValueDatabase { for user_id in services().users.iter().filter_map(Result::ok) { services().users.mark_device_key_update(&user_id)?; } + Ok(()) + })?; - services().globals.bump_database_version(10)?; - - warn!("Migration: 9 -> 10 finished"); - } - - if services().globals.database_version()? < 11 { + migration(11, || { db.db.open_tree("userdevicesessionid_uiaarequest")?.clear()?; - services().globals.bump_database_version(11)?; + Ok(()) + })?; - warn!("Migration: 10 -> 11 finished"); - } - - if services().globals.database_version()? < 12 { + migration(12, || { for username in services().users.list_local_users()? { let user = match UserId::parse_with_server_name( username.clone(), @@ -1072,15 +1040,12 @@ impl KeyValueDatabase { .expect("to json value always works"), )?; } - - services().globals.bump_database_version(12)?; - - warn!("Migration: 11 -> 12 finished"); - } + Ok(()) + })?; // This migration can be reused as-is anytime the server-default // rules are updated. - if services().globals.database_version()? < 13 { + migration(13, || { for username in services().users.list_local_users()? { let user = match UserId::parse_with_server_name( username.clone(), @@ -1131,11 +1096,8 @@ impl KeyValueDatabase { .expect("to json value always works"), )?; } - - services().globals.bump_database_version(13)?; - - warn!("Migration: 12 -> 13 finished"); - } + Ok(()) + })?; assert_eq!( services().globals.database_version().unwrap(), @@ -1277,3 +1239,18 @@ fn set_emergency_access() -> Result { res } + +/// If the current version is older than `new_version`, execute a migration +/// function. +fn migration(new_version: u64, migration: F) -> Result<(), Error> +where + F: FnOnce() -> Result<(), Error>, +{ + let current_version = services().globals.database_version()?; + if current_version < new_version { + migration()?; + services().globals.bump_database_version(new_version)?; + warn!("Migration: {current_version} -> {new_version} finished"); + } + Ok(()) +}