diff --git a/iroh-sync/src/store/fs/migrations.rs b/iroh-sync/src/store/fs/migrations.rs index 7e6901a792..8c1e9c43d4 100644 --- a/iroh-sync/src/store/fs/migrations.rs +++ b/iroh-sync/src/store/fs/migrations.rs @@ -14,8 +14,9 @@ use super::{ /// Run all database migrations, if needed. pub fn run_migrations(db: &Database) -> Result<()> { run_migration(db, migration_001_populate_latest_table)?; - run_migration(db, migration_002_namespaces_v2)?; - run_migration(db, migration_003_populate_by_key_index)?; + run_migration(db, migration_002_namespaces_populate_v2)?; + run_migration(db, migration_003_namespaces_delete_v1)?; + run_migration(db, migration_004_populate_by_key_index)?; Ok(()) } @@ -74,12 +75,11 @@ fn migration_001_populate_latest_table(tx: &WriteTransaction) -> Result Result { +/// Copy the namespaces data from V1 to V2. +fn migration_002_namespaces_populate_v2(tx: &WriteTransaction) -> Result { let namespaces_v1_exists = tx .list_tables()? .any(|handle| handle.name() == NAMESPACES_TABLE_V1.name()); - // migration 002: update namespaces from V1 to V2 if !namespaces_v1_exists { return Ok(MigrateOutcome::Skip); } @@ -95,12 +95,31 @@ fn migration_002_namespaces_v2(tx: &WriteTransaction) -> Result namespaces_v2.insert(&id, (raw_kind, &raw_bytes))?; entries += 1; } - tx.delete_table(NAMESPACES_TABLE_V1)?; Ok(MigrateOutcome::Execute(entries)) } +/// Delete the v1 namespaces table. +/// +/// This should be part of [`migration_002_namespaces_populate_v2`] but due to a limitation in +/// [`redb`] up to v1.3.0 a table cannot be deleted in a transaction that also opens this table. +/// Therefore the table deletion has to be in a separate transaction. +/// +/// This limitation was removed in so this can be merged +/// back into [`migration_002_namespaces_populate_v2`] once we upgrade to the next redb version +/// after 1.3. +fn migration_003_namespaces_delete_v1(tx: &WriteTransaction) -> Result { + let namespaces_v1_exists = tx + .list_tables()? + .any(|handle| handle.name() == NAMESPACES_TABLE_V1.name()); + if !namespaces_v1_exists { + return Ok(MigrateOutcome::Skip); + } + tx.delete_table(NAMESPACES_TABLE_V1)?; + Ok(MigrateOutcome::Execute(1)) +} + /// migration 003: populate the by_key index table(which did not exist before) -fn migration_003_populate_by_key_index(tx: &WriteTransaction) -> Result { +fn migration_004_populate_by_key_index(tx: &WriteTransaction) -> Result { let mut by_key_table = tx.open_table(RECORDS_BY_KEY_TABLE)?; let records_table = tx.open_table(RECORDS_TABLE)?; if !by_key_table.is_empty()? || records_table.is_empty()? {