From aeedb948cc3c219ed24eb5429b7888edee0b4e68 Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Fri, 17 Sep 2021 18:19:26 +0200 Subject: [PATCH] pass logger to Storage and make it available in Transaction --- src/domain/SessionPickerViewModel.js | 8 ++++++-- src/logging/LogItem.js | 4 ++++ src/matrix/storage/idb/Storage.ts | 15 +++++++++------ src/matrix/storage/idb/StorageFactory.ts | 17 +++++++++-------- src/matrix/storage/idb/Transaction.ts | 16 +++++++++++++--- 5 files changed, 41 insertions(+), 19 deletions(-) diff --git a/src/domain/SessionPickerViewModel.js b/src/domain/SessionPickerViewModel.js index 3bbbcef7..fc669df1 100644 --- a/src/domain/SessionPickerViewModel.js +++ b/src/domain/SessionPickerViewModel.js @@ -150,7 +150,9 @@ export class SessionPickerViewModel extends ViewModel { async _exportData(id) { const sessionInfo = await this.platform.sessionInfoStorage.get(id); - const stores = await this.platform.storageFactory.export(id); + const stores = await this.logger.run("export", log => { + return this.platform.storageFactory.export(id, log); + }); const data = {sessionInfo, stores}; return data; } @@ -161,7 +163,9 @@ export class SessionPickerViewModel extends ViewModel { const {sessionInfo} = data; sessionInfo.comment = `Imported on ${new Date().toLocaleString()} from id ${sessionInfo.id}.`; sessionInfo.id = this._createSessionContainer().createNewSessionId(); - await this.platform.storageFactory.import(sessionInfo.id, data.stores); + await this.logger.run("import", log => { + return this.platform.storageFactory.import(sessionInfo.id, data.stores, log); + }); await this.platform.sessionInfoStorage.add(sessionInfo); this._sessions.set(new SessionItemViewModel(sessionInfo, this)); } catch (err) { diff --git a/src/logging/LogItem.js b/src/logging/LogItem.js index fcb88eff..69128270 100644 --- a/src/logging/LogItem.js +++ b/src/logging/LogItem.js @@ -231,4 +231,8 @@ export class LogItem { this._children.push(item); return item; } + + get logger() { + return this._logger; + } } diff --git a/src/matrix/storage/idb/Storage.ts b/src/matrix/storage/idb/Storage.ts index bffdb642..6f7f4c90 100644 --- a/src/matrix/storage/idb/Storage.ts +++ b/src/matrix/storage/idb/Storage.ts @@ -17,20 +17,23 @@ limitations under the License. import {Transaction} from "./Transaction"; import { STORE_NAMES, StoreNames, StorageError } from "../common"; import { reqAsPromise } from "./utils"; +import { BaseLogger } from "../../../logging/BaseLogger.js"; const WEBKITEARLYCLOSETXNBUG_BOGUS_KEY = "782rh281re38-boguskey"; export class Storage { private _db: IDBDatabase; private _hasWebkitEarlyCloseTxnBug: boolean; - private _IDBKeyRange: typeof IDBKeyRange - storeNames: typeof StoreNames; + readonly logger: BaseLogger; + readonly IDBKeyRange: typeof IDBKeyRange; + readonly storeNames: typeof StoreNames; - constructor(idbDatabase: IDBDatabase, _IDBKeyRange: typeof IDBKeyRange, hasWebkitEarlyCloseTxnBug: boolean) { + constructor(idbDatabase: IDBDatabase, _IDBKeyRange: typeof IDBKeyRange, hasWebkitEarlyCloseTxnBug: boolean, logger: BaseLogger) { this._db = idbDatabase; - this._IDBKeyRange = _IDBKeyRange; + this.IDBKeyRange = _IDBKeyRange; this._hasWebkitEarlyCloseTxnBug = hasWebkitEarlyCloseTxnBug; this.storeNames = StoreNames; + this.logger = logger; } _validateStoreNames(storeNames: StoreNames[]): void { @@ -49,7 +52,7 @@ export class Storage { if (this._hasWebkitEarlyCloseTxnBug) { await reqAsPromise(txn.objectStore(storeNames[0]).get(WEBKITEARLYCLOSETXNBUG_BOGUS_KEY)); } - return new Transaction(txn, storeNames, this._IDBKeyRange); + return new Transaction(txn, storeNames, this); } catch(err) { throw new StorageError("readTxn failed", err); } @@ -64,7 +67,7 @@ export class Storage { if (this._hasWebkitEarlyCloseTxnBug) { await reqAsPromise(txn.objectStore(storeNames[0]).get(WEBKITEARLYCLOSETXNBUG_BOGUS_KEY)); } - return new Transaction(txn, storeNames, this._IDBKeyRange); + return new Transaction(txn, storeNames, this); } catch(err) { throw new StorageError("readWriteTxn failed", err); } diff --git a/src/matrix/storage/idb/StorageFactory.ts b/src/matrix/storage/idb/StorageFactory.ts index 6db78c36..38b48a17 100644 --- a/src/matrix/storage/idb/StorageFactory.ts +++ b/src/matrix/storage/idb/StorageFactory.ts @@ -20,9 +20,10 @@ import { exportSession, importSession, Export } from "./export"; import { schema } from "./schema"; import { detectWebkitEarlyCloseTxnBug } from "./quirks"; import { BaseLogger } from "../../../logging/BaseLogger.js"; +import { LogItem } from "../../../logging/LogItem.js"; const sessionName = (sessionId: string) => `hydrogen_session_${sessionId}`; -const openDatabaseWithSessionId = function(sessionId: string, idbFactory: IDBFactory, log?: BaseLogger) { +const openDatabaseWithSessionId = function(sessionId: string, idbFactory: IDBFactory, log: LogItem) { const create = (db, txn, oldVersion, version) => createStores(db, txn, oldVersion, version, log); return openDatabase(sessionName(sessionId), create, schema.length, idbFactory); } @@ -59,7 +60,7 @@ export class StorageFactory { this._IDBKeyRange = _IDBKeyRange; } - async create(sessionId: string, log?: BaseLogger): Promise { + async create(sessionId: string, log: LogItem): Promise { await this._serviceWorkerHandler?.preventConcurrentSessionAccess(sessionId); requestPersistedStorage().then(persisted => { // Firefox lies here though, and returns true even if the user denied the request @@ -70,7 +71,7 @@ export class StorageFactory { const hasWebkitEarlyCloseTxnBug = await detectWebkitEarlyCloseTxnBug(this._idbFactory); const db = await openDatabaseWithSessionId(sessionId, this._idbFactory, log); - return new Storage(db, this._IDBKeyRange, hasWebkitEarlyCloseTxnBug); + return new Storage(db, this._IDBKeyRange, hasWebkitEarlyCloseTxnBug, log.logger); } delete(sessionId: string): Promise { @@ -79,18 +80,18 @@ export class StorageFactory { return reqAsPromise(req); } - async export(sessionId: string): Promise { - const db = await openDatabaseWithSessionId(sessionId, this._idbFactory); + async export(sessionId: string, log: LogItem): Promise { + const db = await openDatabaseWithSessionId(sessionId, this._idbFactory, log); return await exportSession(db); } - async import(sessionId: string, data: Export): Promise { - const db = await openDatabaseWithSessionId(sessionId, this._idbFactory); + async import(sessionId: string, data: Export, log: LogItem): Promise { + const db = await openDatabaseWithSessionId(sessionId, this._idbFactory, log); return await importSession(db, data); } } -async function createStores(db: IDBDatabase, txn: IDBTransaction, oldVersion: number | null, version: number, log?: BaseLogger): Promise { +async function createStores(db: IDBDatabase, txn: IDBTransaction, oldVersion: number | null, version: number, log: LogItem): Promise { const startIdx = oldVersion || 0; return log.wrap({l: "storage migration", oldVersion, version}, async log => { for(let i = startIdx; i < version; ++i) { diff --git a/src/matrix/storage/idb/Transaction.ts b/src/matrix/storage/idb/Transaction.ts index ea21b745..e9b127ff 100644 --- a/src/matrix/storage/idb/Transaction.ts +++ b/src/matrix/storage/idb/Transaction.ts @@ -35,18 +35,28 @@ import {OutboundGroupSessionStore} from "./stores/OutboundGroupSessionStore"; import {GroupSessionDecryptionStore} from "./stores/GroupSessionDecryptionStore"; import {OperationStore} from "./stores/OperationStore"; import {AccountDataStore} from "./stores/AccountDataStore"; +import {BaseLogger} from "../../../logging/BaseLogger.js"; export class Transaction { private _txn: IDBTransaction; private _allowedStoreNames: StoreNames[]; private _stores: { [storeName in StoreNames]?: any }; + private _storage: Storage; - constructor(txn: IDBTransaction, allowedStoreNames: StoreNames[], IDBKeyRange) { + constructor(txn: IDBTransaction, allowedStoreNames: StoreNames[], storage: Storage) { this._txn = txn; this._allowedStoreNames = allowedStoreNames; this._stores = {}; - // @ts-ignore - this.IDBKeyRange = IDBKeyRange; + this._storage = storage; + this._writeErrors = []; + } + + get IDBKeyRange(): typeof IDBKeyRange { + return this._storage.IDBKeyRange; + } + + get logger(): BaseLogger { + return this._storage.logger; } _idbStore(name: StoreNames): Store {