matrix_sdk_indexeddb/crypto_store/migrations/
v8_to_v10.rs1use indexed_db_futures::{
19 error::OpenDbError, query_source::QuerySource, transaction::TransactionMode, Build,
20};
21use matrix_sdk_crypto::olm::InboundGroupSession;
22use tracing::{debug, info};
23use wasm_bindgen::JsValue;
24
25use crate::{
26 crypto_store::{
27 keys,
28 migrations::{
29 add_nonunique_index, do_schema_upgrade, old_keys,
30 v7::InboundGroupSessionIndexedDbObject2, MigrationDb,
31 },
32 InboundGroupSessionIndexedDbObject, Result,
33 },
34 serializer::SafeEncodeSerializer,
35 IndexeddbCryptoStoreError,
36};
37
38pub(crate) async fn schema_add(name: &str) -> Result<(), OpenDbError> {
40 do_schema_upgrade(name, 9, |tx, _| {
41 let db = tx.db();
42 let object_store = db.create_object_store(keys::INBOUND_GROUP_SESSIONS_V3).build()?;
43
44 add_nonunique_index(
45 &object_store,
46 keys::INBOUND_GROUP_SESSIONS_BACKUP_INDEX,
47 "needs_backup",
48 )?;
49
50 add_nonunique_index(
54 &object_store,
55 keys::INBOUND_GROUP_SESSIONS_BACKED_UP_TO_INDEX,
56 "backed_up_to",
57 )?;
58
59 Ok(())
60 })
61 .await
62}
63
64pub(crate) async fn data_migrate(name: &str, serializer: &SafeEncodeSerializer) -> Result<()> {
66 let db = MigrationDb::new(name, 10).await?;
67
68 let txn = db
69 .transaction([old_keys::INBOUND_GROUP_SESSIONS_V2, keys::INBOUND_GROUP_SESSIONS_V3])
70 .with_mode(TransactionMode::Readwrite)
71 .build()?;
72
73 let inbound_group_sessions2 = txn.object_store(old_keys::INBOUND_GROUP_SESSIONS_V2)?;
74 let inbound_group_sessions3 = txn.object_store(keys::INBOUND_GROUP_SESSIONS_V3)?;
75
76 let row_count = inbound_group_sessions2.count().await?;
77 info!(row_count, "Shrinking inbound_group_session records");
78
79 if let Some(mut cursor) = inbound_group_sessions2.open_cursor().await? {
81 let mut idx = 0;
82 while let Some(value) = cursor.next_record::<JsValue>().await? {
83 idx += 1;
84
85 if idx % 100 == 0 {
86 debug!("Migrating session {idx} of {row_count}");
87 }
88
89 let old_value: InboundGroupSessionIndexedDbObject2 =
91 serde_wasm_bindgen::from_value(value)?;
92
93 let session = InboundGroupSession::from_pickle(
94 serializer.deserialize_value_from_bytes(&old_value.pickled_session)?,
95 )
96 .map_err(|e| IndexeddbCryptoStoreError::CryptoStoreError(e.into()))?;
97
98 let new_key = serializer.encode_key(
100 keys::INBOUND_GROUP_SESSIONS_V3,
101 (&session.room_id, session.session_id()),
102 );
103
104 let new_value =
106 InboundGroupSessionIndexedDbObject::from_session(&session, serializer).await?;
107
108 inbound_group_sessions3
110 .add(&serde_wasm_bindgen::to_value(&new_value)?)
111 .with_key(new_key)
112 .build()?;
113
114 cursor.delete()?;
116 }
117
118 debug!("Migrated {idx} sessions.");
120 }
121
122 inbound_group_sessions2.clear()?.await?;
126
127 txn.commit().await?;
128 Ok(())
129}
130
131pub(crate) async fn schema_delete(name: &str) -> Result<(), OpenDbError> {
133 do_schema_upgrade(name, 10, |tx, _| {
134 tx.db().delete_object_store(old_keys::INBOUND_GROUP_SESSIONS_V2)?;
135 Ok(())
136 })
137 .await
138}