matrix_sdk_indexeddb/crypto_store/migrations/
v8_to_v10.rs1use indexed_db_futures::IdbQuerySource;
19use matrix_sdk_crypto::olm::InboundGroupSession;
20use tracing::{debug, info};
21use web_sys::{DomException, IdbTransactionMode};
22
23use crate::{
24 crypto_store::{
25 indexeddb_serializer::IndexeddbSerializer,
26 keys,
27 migrations::{
28 add_nonunique_index, do_schema_upgrade, old_keys,
29 v7::InboundGroupSessionIndexedDbObject2, MigrationDb,
30 },
31 InboundGroupSessionIndexedDbObject, Result,
32 },
33 IndexeddbCryptoStoreError,
34};
35
36pub(crate) async fn schema_add(name: &str) -> Result<(), DomException> {
38 do_schema_upgrade(name, 9, |db, _, _| {
39 let object_store = db.create_object_store(keys::INBOUND_GROUP_SESSIONS_V3)?;
40
41 add_nonunique_index(
42 &object_store,
43 keys::INBOUND_GROUP_SESSIONS_BACKUP_INDEX,
44 "needs_backup",
45 )?;
46
47 add_nonunique_index(
51 &object_store,
52 keys::INBOUND_GROUP_SESSIONS_BACKED_UP_TO_INDEX,
53 "backed_up_to",
54 )?;
55
56 Ok(())
57 })
58 .await
59}
60
61pub(crate) async fn data_migrate(name: &str, serializer: &IndexeddbSerializer) -> Result<()> {
63 let db = MigrationDb::new(name, 10).await?;
64
65 let txn = db.transaction_on_multi_with_mode(
66 &[old_keys::INBOUND_GROUP_SESSIONS_V2, keys::INBOUND_GROUP_SESSIONS_V3],
67 IdbTransactionMode::Readwrite,
68 )?;
69
70 let inbound_group_sessions2 = txn.object_store(old_keys::INBOUND_GROUP_SESSIONS_V2)?;
71 let inbound_group_sessions3 = txn.object_store(keys::INBOUND_GROUP_SESSIONS_V3)?;
72
73 let row_count = inbound_group_sessions2.count()?.await?;
74 info!(row_count, "Shrinking inbound_group_session records");
75
76 if let Some(cursor) = inbound_group_sessions2.open_cursor()?.await? {
78 let mut idx = 0;
79 loop {
80 idx += 1;
81
82 if idx % 100 == 0 {
83 debug!("Migrating session {idx} of {row_count}");
84 }
85
86 let old_value: InboundGroupSessionIndexedDbObject2 =
88 serde_wasm_bindgen::from_value(cursor.value())?;
89
90 let session = InboundGroupSession::from_pickle(
91 serializer.deserialize_value_from_bytes(&old_value.pickled_session)?,
92 )
93 .map_err(|e| IndexeddbCryptoStoreError::CryptoStoreError(e.into()))?;
94
95 let new_key = serializer.encode_key(
97 keys::INBOUND_GROUP_SESSIONS_V3,
98 (&session.room_id, session.session_id()),
99 );
100
101 let new_value =
103 InboundGroupSessionIndexedDbObject::from_session(&session, serializer).await?;
104
105 inbound_group_sessions3
107 .add_key_val(&new_key, &serde_wasm_bindgen::to_value(&new_value)?)?;
108
109 cursor.delete()?;
111
112 if !cursor.continue_cursor()?.await? {
114 debug!("Migrated {idx} sessions.");
115 break;
116 }
117 }
118 }
119
120 inbound_group_sessions2.clear()?.await?;
124
125 txn.await.into_result()?;
126 Ok(())
127}
128
129pub(crate) async fn schema_delete(name: &str) -> Result<(), DomException> {
131 do_schema_upgrade(name, 10, |db, _, _| {
132 db.delete_object_store(old_keys::INBOUND_GROUP_SESSIONS_V2)?;
133 Ok(())
134 })
135 .await
136}