hydrogen-web/src/matrix/storage/idb/schema.js

97 lines
3.4 KiB
JavaScript
Raw Normal View History

import {iterateCursor, reqAsPromise} from "./utils.js";
2020-08-19 19:58:09 +05:30
import {RoomMember, EVENT_TYPE as MEMBER_EVENT_TYPE} from "../../room/members/RoomMember.js";
import {RoomMemberStore} from "./stores/RoomMemberStore.js";
import {SessionStore} from "./stores/SessionStore.js";
2020-06-27 02:56:24 +05:30
// FUNCTIONS SHOULD ONLY BE APPENDED!!
// the index in the array is the database version
export const schema = [
createInitialStores,
createMemberStore,
migrateSession,
2020-08-31 18:08:03 +05:30
createIdentityStores,
2020-09-01 21:29:59 +05:30
createOlmSessionStore,
2020-09-02 17:54:38 +05:30
createInboundGroupSessionsStore,
2020-09-03 21:19:20 +05:30
createOutboundGroupSessionsStore,
createGroupSessionDecryptions,
2020-06-27 02:56:24 +05:30
];
// TODO: how to deal with git merge conflicts of this array?
// how do we deal with schema updates vs existing data migration in a way that
//v1
function createInitialStores(db) {
db.createObjectStore("session", {keyPath: "key"});
// any way to make keys unique here? (just use put?)
db.createObjectStore("roomSummary", {keyPath: "roomId"});
// need index to find live fragment? prooobably ok without for now
//key = room_id | fragment_id
db.createObjectStore("timelineFragments", {keyPath: "key"});
//key = room_id | fragment_id | event_index
const timelineEvents = db.createObjectStore("timelineEvents", {keyPath: "key"});
//eventIdKey = room_id | event_id
timelineEvents.createIndex("byEventId", "eventIdKey", {unique: true});
//key = room_id | event.type | event.state_key,
db.createObjectStore("roomState", {keyPath: "key"});
db.createObjectStore("pendingEvents", {keyPath: "key"});
}
//v2
async function createMemberStore(db, txn) {
const roomMembers = new RoomMemberStore(db.createObjectStore("roomMembers", {keyPath: "key"}));
2020-06-27 02:56:24 +05:30
// migrate existing member state events over
const roomState = txn.objectStore("roomState");
await iterateCursor(roomState.openCursor(), entry => {
if (entry.event.type === MEMBER_EVENT_TYPE) {
roomState.delete(entry.key);
const member = RoomMember.fromMemberEvent(entry.roomId, entry.event);
if (member) {
roomMembers.set(member.serialize());
2020-06-27 02:56:24 +05:30
}
}
});
}
2020-08-31 18:08:03 +05:30
//v3
async function migrateSession(db, txn) {
const session = txn.objectStore("session");
try {
const PRE_MIGRATION_KEY = 1;
const entry = await reqAsPromise(session.get(PRE_MIGRATION_KEY));
if (entry) {
session.delete(PRE_MIGRATION_KEY);
const {syncToken, syncFilterId, serverVersions} = entry.value;
const store = new SessionStore(session);
store.set("sync", {token: syncToken, filterId: syncFilterId});
store.set("serverVersions", serverVersions);
}
} catch (err) {
txn.abort();
console.error("could not migrate session", err.stack);
}
}
2020-08-31 18:08:03 +05:30
//v4
function createIdentityStores(db) {
db.createObjectStore("userIdentities", {keyPath: "userId"});
db.createObjectStore("deviceIdentities", {keyPath: "key"});
}
2020-09-01 21:29:59 +05:30
//v5
function createOlmSessionStore(db) {
db.createObjectStore("olmSessions", {keyPath: "key"});
}
2020-09-02 17:54:38 +05:30
//v6
function createInboundGroupSessionsStore(db) {
db.createObjectStore("inboundGroupSessions", {keyPath: "key"});
}
2020-09-03 21:19:20 +05:30
//v7
function createOutboundGroupSessionsStore(db) {
db.createObjectStore("outboundGroupSessions", {keyPath: "roomId"});
}
//v8
function createGroupSessionDecryptions(db) {
db.createObjectStore("groupSessionDecryptions", {keyPath: "key"});
}