forked from mystiq/hydrogen-web
pass logger to Storage and make it available in Transaction
This commit is contained in:
parent
cce7606960
commit
aeedb948cc
5 changed files with 41 additions and 19 deletions
|
@ -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) {
|
||||
|
|
|
@ -231,4 +231,8 @@ export class LogItem {
|
|||
this._children.push(item);
|
||||
return item;
|
||||
}
|
||||
|
||||
get logger() {
|
||||
return this._logger;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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<Storage> {
|
||||
async create(sessionId: string, log: LogItem): Promise<Storage> {
|
||||
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<IDBDatabase> {
|
||||
|
@ -79,18 +80,18 @@ export class StorageFactory {
|
|||
return reqAsPromise(req);
|
||||
}
|
||||
|
||||
async export(sessionId: string): Promise<Export> {
|
||||
const db = await openDatabaseWithSessionId(sessionId, this._idbFactory);
|
||||
async export(sessionId: string, log: LogItem): Promise<Export> {
|
||||
const db = await openDatabaseWithSessionId(sessionId, this._idbFactory, log);
|
||||
return await exportSession(db);
|
||||
}
|
||||
|
||||
async import(sessionId: string, data: Export): Promise<void> {
|
||||
const db = await openDatabaseWithSessionId(sessionId, this._idbFactory);
|
||||
async import(sessionId: string, data: Export, log: LogItem): Promise<void> {
|
||||
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<void> {
|
||||
async function createStores(db: IDBDatabase, txn: IDBTransaction, oldVersion: number | null, version: number, log: LogItem): Promise<void> {
|
||||
const startIdx = oldVersion || 0;
|
||||
return log.wrap({l: "storage migration", oldVersion, version}, async log => {
|
||||
for(let i = startIdx; i < version; ++i) {
|
||||
|
|
|
@ -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<any> {
|
||||
|
|
Loading…
Reference in a new issue