use indexed_db_futures::{
Build,
database::Database,
error::{Error, OpenDbError},
};
use crate::crypto_store::{
Result, keys,
migrations::{add_nonunique_index, add_unique_index, do_schema_upgrade, old_keys},
};
pub(crate) async fn schema_add(name: &str) -> Result<(), OpenDbError> {
do_schema_upgrade(name, 5, |tx, old_version| {
let db = tx.db();
if db.object_store_names().next().is_none() {
schema_add_v1(db)?;
}
if old_version < 2 {
schema_add_v2(db)?;
}
if old_version < 3 {
schema_add_v3(db)?;
}
if old_version < 4 {
schema_add_v4(db)?;
}
if old_version < 5 {
schema_add_v5(db)?;
}
Ok(())
})
.await
}
fn schema_add_v1(db: &Database) -> Result<(), Error> {
db.create_object_store(keys::CORE).build()?;
db.create_object_store(keys::SESSION).build()?;
db.create_object_store(old_keys::INBOUND_GROUP_SESSIONS_V1).build()?;
db.create_object_store(keys::OUTBOUND_GROUP_SESSIONS).build()?;
db.create_object_store(keys::TRACKED_USERS).build()?;
db.create_object_store(keys::OLM_HASHES).build()?;
db.create_object_store(keys::DEVICES).build()?;
db.create_object_store(keys::IDENTITIES).build()?;
db.create_object_store(keys::BACKUP_KEYS).build()?;
Ok(())
}
fn schema_add_v2(db: &Database) -> Result<(), Error> {
db.delete_object_store(old_keys::INBOUND_GROUP_SESSIONS_V1)?;
db.create_object_store(old_keys::INBOUND_GROUP_SESSIONS_V1).build()?;
db.create_object_store(keys::ROOM_SETTINGS).build()?;
Ok(())
}
fn schema_add_v3(db: &Database) -> Result<(), Error> {
db.delete_object_store(keys::OUTBOUND_GROUP_SESSIONS)?;
db.create_object_store(keys::OUTBOUND_GROUP_SESSIONS).build()?;
db.create_object_store(old_keys::DIRECT_WITHHELD_INFO).build()?;
Ok(())
}
fn schema_add_v4(db: &Database) -> Result<(), Error> {
db.create_object_store(old_keys::SECRETS_INBOX_V1).build()?;
Ok(())
}
fn schema_add_v5(db: &Database) -> Result<(), Error> {
let object_store = db.create_object_store(keys::GOSSIP_REQUESTS).build()?;
add_nonunique_index(&object_store, keys::GOSSIP_REQUESTS_UNSENT_INDEX, "unsent")?;
add_unique_index(&object_store, keys::GOSSIP_REQUESTS_BY_INFO_INDEX, "info")?;
if db.object_store_names().any(|n| n == "outgoing_secret_requests") {
db.delete_object_store("outgoing_secret_requests")?;
db.delete_object_store("unsent_secret_requests")?;
db.delete_object_store("secret_requests_by_info")?;
}
Ok(())
}