indexeddb: Use a MigrationDb object to ensure DB is closed

Signed-off-by: Andy Balaam <andy.balaam@matrix.org>
This commit is contained in:
Andy Balaam
2024-02-05 15:55:39 +00:00
parent 88d10210ad
commit a92140f3ac
4 changed files with 40 additions and 23 deletions

View File

@@ -12,6 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
use std::ops::Deref;
use indexed_db_futures::{prelude::*, web_sys::DomException};
use tracing::info;
use wasm_bindgen::JsValue;
@@ -28,6 +30,37 @@ mod v7;
mod v7_to_v8;
mod v8_to_v10;
struct MigrationDb {
db: IdbDatabase,
next_version: u32,
}
impl MigrationDb {
/// Create an Indexed DB wrapper that manages a database migration,
/// logging messages before and after the migration, and automatically
/// closing the DB when this object is dropped.
async fn new(name: &str, next_version: u32) -> Result<Self> {
info!("IndexeddbCryptoStore migrate data before v{next_version} starting");
Ok(Self { db: IdbDatabase::open(name)?.await?, next_version })
}
}
impl Deref for MigrationDb {
type Target = IdbDatabase;
fn deref(&self) -> &Self::Target {
&self.db
}
}
impl Drop for MigrationDb {
fn drop(&mut self) {
let version = self.next_version;
info!("IndexeddbCryptoStore migrate data before v{version} finished");
self.db.close();
}
}
/// Open the indexeddb with the given name, upgrading it to the latest version
/// of the schema if necessary.
pub async fn open_and_upgrade_db(

View File

@@ -19,7 +19,7 @@
//! Then we move the data into the new store.
//! The migration 6->7 deletes the old store inbound_group_sessions.
use indexed_db_futures::{IdbDatabase, IdbQuerySource};
use indexed_db_futures::IdbQuerySource;
use matrix_sdk_crypto::olm::InboundGroupSession;
use tracing::{debug, info};
use web_sys::{DomException, IdbTransactionMode};
@@ -28,7 +28,7 @@ use crate::{
crypto_store::{
indexeddb_serializer::IndexeddbSerializer,
keys,
migrations::{add_nonunique_index, do_schema_upgrade, old_keys, v7},
migrations::{add_nonunique_index, do_schema_upgrade, old_keys, v7, MigrationDb},
Result,
},
IndexeddbCryptoStoreError,
@@ -52,16 +52,8 @@ pub(crate) async fn schema_add(name: &str) -> Result<(), DomException> {
/// Migrate data from `inbound_group_sessions` into `inbound_group_sessions2`.
pub(crate) async fn data_migrate(name: &str, serializer: &IndexeddbSerializer) -> Result<()> {
info!("IndexeddbCryptoStore migrate data before v7 starting");
let db = IdbDatabase::open(name)?.await?;
let res = do_prepare_data_for_v7(serializer, &db).await;
db.close();
res?;
info!("IndexeddbCryptoStore migrate data before v7 finished");
Ok(())
}
let db = MigrationDb::new(name, 7).await?;
async fn do_prepare_data_for_v7(serializer: &IndexeddbSerializer, db: &IdbDatabase) -> Result<()> {
// The new store has been made for inbound group sessions; time to populate it.
let txn = db.transaction_on_multi_with_mode(
&[old_keys::INBOUND_GROUP_SESSIONS_V1, old_keys::INBOUND_GROUP_SESSIONS_V2],

View File

@@ -23,7 +23,7 @@ use web_sys::{DomException, IdbTransactionMode};
use crate::{
crypto_store::{
indexeddb_serializer::IndexeddbSerializer,
migrations::{do_schema_upgrade, old_keys, v7},
migrations::{do_schema_upgrade, old_keys, v7, MigrationDb},
Result,
},
IndexeddbCryptoStoreError,
@@ -34,9 +34,8 @@ use crate::{
/// should have done is re-hash them using the new table name, so we fix them up
/// here.
pub(crate) async fn data_migrate(name: &str, serializer: &IndexeddbSerializer) -> Result<()> {
info!("IndexeddbCryptoStore upgrade data -> v8 starting");
let db = MigrationDb::new(name, 8).await?;
let db = IdbDatabase::open(name)?.await?;
let txn = db.transaction_on_one_with_mode(
old_keys::INBOUND_GROUP_SESSIONS_V2,
IdbTransactionMode::Readwrite,
@@ -109,9 +108,6 @@ pub(crate) async fn data_migrate(name: &str, serializer: &IndexeddbSerializer) -
}
txn.await.into_result()?;
db.close();
info!("IndexeddbCryptoStore upgrade data -> v8 finished");
Ok(())
}

View File

@@ -26,7 +26,7 @@ use crate::{
keys,
migrations::{
add_nonunique_index, do_schema_upgrade, old_keys,
v7::InboundGroupSessionIndexedDbObject2,
v7::InboundGroupSessionIndexedDbObject2, MigrationDb,
},
InboundGroupSessionIndexedDbObject, Result,
},
@@ -60,9 +60,8 @@ pub(crate) async fn schema_add(name: &str) -> Result<(), DomException> {
/// Migrate data from `inbound_group_sessions2` into `inbound_group_sessions3`.
pub(crate) async fn data_migrate(name: &str, serializer: &IndexeddbSerializer) -> Result<()> {
info!("IndexeddbCryptoStore migrate data before v10 starting");
let db = MigrationDb::new(name, 10).await?;
let db = IdbDatabase::open(name)?.await?;
let txn = db.transaction_on_multi_with_mode(
&[old_keys::INBOUND_GROUP_SESSIONS_V2, keys::INBOUND_GROUP_SESSIONS_V3],
IdbTransactionMode::Readwrite,
@@ -127,9 +126,6 @@ pub(crate) async fn data_migrate(name: &str, serializer: &IndexeddbSerializer) -
inbound_group_sessions2.clear()?.await?;
txn.await.into_result()?;
db.close();
info!("IndexeddbCryptoStore upgrade data before v10 finished");
Ok(())
}