1
0

only reinsert all sessions if necessary

The purpose of this is data safety. If there ever was a broken model
that corrupted data previously it would have ruined everything if it
coincided with a schema migration. Now this is much less likely.
This commit is contained in:
Adrian Wannenmacher 2026-02-28 18:23:48 +01:00
parent 53e3b2539a
commit b5ead20f0b
Signed by: tfld
GPG Key ID: 19D986ECB1E492D5
2 changed files with 49 additions and 37 deletions

View File

@ -142,13 +142,18 @@ export default class WbDb extends EventTarget {
target: { result: db, transaction: trans },
} = event;
let reinsertAll = false;
if (old < 1 && now >= 1)
this.#version1(db, trans);
if (old < 2 && now >= 2)
if (old < 2 && now >= 2) {
this.#version2(db, trans);
reinsertAll = true;
}
// update existing data to be visible in indexes
SessionRepo.reinsertAll(trans);
if (reinsertAll)
SessionRepo.reinsertAll(trans);
}
/** Handle the `error` event from opening the DB.

View File

@ -133,44 +133,51 @@ export default function() {
assert.true(second.failed, "second instance failed");
});
QUnit.test("sessions are reinserted after upgrade", async function(assert) {
let first = WbDb.get(true, 1);
await waitForChange(first);
first
.db
.transaction([WbDb.OS_SESSIONS], "readwrite")
.objectStore(WbDb.OS_SESSIONS)
.put({
goal: 3,
ourTeam: "",
theirTeam: "",
games: [],
currentGame: null,
});
first.db.close();
inst = WbDb.get(true, 2);
await waitForChange();
let sessions = (await new Promise(function (resolve) {
inst
QUnit.test.each(
"sessions are reinserted after upgrade",
[{ before: 1, after: 2, reinsert: true }],
async function(assert, input) {
let first = WbDb.get(true, input.before);
await waitForChange(first);
first
.db
.transaction([WbDb.OS_SESSIONS], "readonly")
.transaction([WbDb.OS_SESSIONS], "readwrite")
.objectStore(WbDb.OS_SESSIONS)
.index(WbDb.IDX_SESSIONS_UPDATED)
.getAll()
.onsuccess = resolve;
})).target.result;
assert.strictEqual(sessions.length, 1, "session found by update index");
.put({
goal: 3,
ourTeam: "",
theirTeam: "",
games: [],
currentGame: null,
});
first.db.close();
// Note that the inserted session data is older than the `updated` field
// in the model class. Thus it being present in the index proves that
// the session has indeed been parsed and reinserted.
//
// Also note that the exact parsing and default value adding is already
// checked in the model tests, thus it would be a duplicate to test that
// here too.
});
inst = WbDb.get(true, input.after);
await waitForChange();
let sessions = (await new Promise(function (resolve) {
inst
.db
.transaction([WbDb.OS_SESSIONS], "readonly")
.objectStore(WbDb.OS_SESSIONS)
.index(WbDb.IDX_SESSIONS_UPDATED)
.getAll()
.onsuccess = resolve;
})).target.result;
if (input.reinsert)
assert.strictEqual(sessions.length, 1, "session found via index");
else
assert.strictEqual(sessions.length, 0, "session not in index");
// Note that the inserted session data is older than the `updated` field
// in the model class. Thus it being present in the index proves that
// the session has indeed been parsed and reinserted.
//
// Also note that the exact parsing and default value adding is already
// checked in the model tests, thus it would be a duplicate to test that
// here too.
}
);
QUnit.test("schema version 1", async function(assert) {
inst = WbDb.get(true, 1);