1
0

add db index for update timestamp

This commit is contained in:
Adrian Wannenmacher 2026-02-27 23:05:51 +01:00
parent 4f5f4fbb28
commit 570588f885
Signed by: tfld
GPG Key ID: 19D986ECB1E492D5
2 changed files with 86 additions and 1 deletions

View File

@ -1,5 +1,7 @@
"use strict";
import SessionRepo from "/data/session_repo.js";
/** A wrapper around an IndexedDB.
*
* This wrapper handles the following tasks:
@ -19,10 +21,12 @@ export default class WbDb extends EventTarget {
/** The name of the test `IDBDatabase`. */
static get DB_NAME_TEST() { return "test-watterblock"; }
/** The currently correct DB version. */
static get DB_VERSION() { return 1; }
static get DB_VERSION() { return 2; }
/** The name of the `IDBObjectStore` for `Session`s. */
static get OS_SESSIONS() { return "sessions"; }
/** The name of the `IDBIndex` for the `Session` update time. */
static get IDX_SESSIONS_UPDATED() { return "sessions-updated"; }
/** Whether the WbDb constructor may be called. */
static #mayConstruct = false;
@ -140,6 +144,11 @@ export default class WbDb extends EventTarget {
if (old < 1 && now >= 1)
this.#version1(db, trans);
if (old < 2 && now >= 2)
this.#version2(db, trans);
// update existing data to be visible in indexes
SessionRepo.reinsertAll(trans);
}
/** Handle the `error` event from opening the DB.
@ -172,4 +181,14 @@ export default class WbDb extends EventTarget {
autoIncrement: true,
});
}
/** Do the migration for db version 2.
* @param {IDBDatabase} db The db to upgrade.
* @param {IDBTransaction} trans The db transaction.
*/
#version2(db, trans) {
trans
.objectStore(WbDb.OS_SESSIONS)
.createIndex(WbDb.IDX_SESSIONS_UPDATED, "updated");
}
}

View File

@ -133,6 +133,45 @@ 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
.db
.transaction([WbDb.OS_SESSIONS], "readonly")
.objectStore(WbDb.OS_SESSIONS)
.index(WbDb.IDX_SESSIONS_UPDATED)
.getAll()
.onsuccess = resolve;
})).target.result;
assert.strictEqual(sessions.length, 1, "session found by update 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);
await waitForChange();
@ -149,5 +188,32 @@ export default function() {
assert.true(sessions.autoIncrement, "sessions autoIncrement");
assert.strictEqual(sessions.indexNames.length, 0, "sessions no indexes");
});
QUnit.test("schema version 2", async function(assert) {
inst = WbDb.get(true, 2);
await waitForChange();
assert.true(inst.open, "db is opened");
assert.strictEqual(inst.db.version, 2, "db is version 2");
let osn = inst.db.objectStoreNames;
assert.strictEqual(osn.length, 1, "correct number of object stores");
assert.true(osn.contains(WbDb.OS_SESSIONS), "contains sessions");
let trans = inst.db.transaction(osn);
let sessions = trans.objectStore(WbDb.OS_SESSIONS);
assert.strictEqual(sessions.keyPath, "id", "sessions keyPath");
assert.true(sessions.autoIncrement, "sessions autoIncrement");
assert.strictEqual(sessions.indexNames.length, 1, "sessions one index");
assert.true(
sessions.indexNames.contains(WbDb.IDX_SESSIONS_UPDATED),
"sessions contains session updated");
let sessionsUpdated = sessions.index(WbDb.IDX_SESSIONS_UPDATED);
assert.strictEqual(
sessionsUpdated.keyPath, "updated", "sessionsUpdated keyPath");
assert.false(sessionsUpdated.unique, "sessionsUpdated unique");
assert.false(sessionsUpdated.multiEntry, "sessionsUpdated multiEntry");
});
});
}