matrix_sdk_indexeddb/crypto_store/migrations/
v5_to_v7.rs1use indexed_db_futures::{
23 error::OpenDbError, query_source::QuerySource, transaction::TransactionMode, Build,
24};
25use matrix_sdk_crypto::olm::InboundGroupSession;
26use tracing::{debug, info};
27use wasm_bindgen::JsValue;
28
29use crate::{
30 crypto_store::{
31 keys,
32 migrations::{add_nonunique_index, do_schema_upgrade, old_keys, v7, MigrationDb},
33 Result,
34 },
35 serializer::SafeEncodeSerializer,
36 IndexeddbCryptoStoreError,
37};
38
39pub(crate) async fn schema_add(name: &str) -> Result<(), OpenDbError> {
41 do_schema_upgrade(name, 6, |tx, _| {
42 let db = tx.db();
43 let object_store = db.create_object_store(old_keys::INBOUND_GROUP_SESSIONS_V2).build()?;
44
45 add_nonunique_index(
46 &object_store,
47 keys::INBOUND_GROUP_SESSIONS_BACKUP_INDEX,
48 "needs_backup",
49 )?;
50
51 Ok(())
52 })
53 .await
54}
55
56pub(crate) async fn data_migrate(name: &str, serializer: &SafeEncodeSerializer) -> Result<()> {
58 let db = MigrationDb::new(name, 7).await?;
59
60 let txn = db
62 .transaction([old_keys::INBOUND_GROUP_SESSIONS_V1, old_keys::INBOUND_GROUP_SESSIONS_V2])
63 .with_mode(TransactionMode::Readwrite)
64 .build()?;
65
66 let old_store = txn.object_store(old_keys::INBOUND_GROUP_SESSIONS_V1)?;
67 let new_store = txn.object_store(old_keys::INBOUND_GROUP_SESSIONS_V2)?;
68
69 let row_count = old_store.count().await?;
70 info!(row_count, "Migrating inbound group session data from v1 to v2");
71
72 if let Some(mut cursor) = old_store.open_cursor().await? {
73 let mut idx = 0;
74 while let Some(value) = cursor.next_record::<JsValue>().await? {
75 idx += 1;
76 let key =
77 cursor.key::<JsValue>()?.ok_or(matrix_sdk_crypto::CryptoStoreError::Backend(
78 "inbound_group_sessions v1 cursor has no key".into(),
79 ))?;
80
81 if idx % 100 == 0 {
82 debug!("Migrating session {idx} of {row_count}");
83 }
84
85 let igs = InboundGroupSession::from_pickle(serializer.deserialize_value(value)?)
86 .map_err(|e| IndexeddbCryptoStoreError::CryptoStoreError(e.into()))?;
87
88 let new_data =
89 serde_wasm_bindgen::to_value(&v7::InboundGroupSessionIndexedDbObject2 {
90 pickled_session: serializer.serialize_value_as_bytes(&igs.pickle().await)?,
91 needs_backup: !igs.backed_up(),
92 })?;
93
94 new_store.add(&new_data).with_key(key).build()?;
95
96 cursor.delete()?;
98 }
99 }
100
101 old_store.clear()?.await?;
105
106 Ok(txn.commit().await?)
107}
108
109pub(crate) async fn schema_delete(name: &str) -> Result<(), OpenDbError> {
111 do_schema_upgrade(name, 7, |tx, _| {
112 tx.db().delete_object_store(old_keys::INBOUND_GROUP_SESSIONS_V1)?;
113 Ok(())
114 })
115 .await
116}