Skip to content

Commit c7cc245

Browse files
authored
Merge pull request #54 from microsoft/bviswanathan/db_open_log
Add log statements to IndexedDbProvider open
2 parents 2735dda + bacd975 commit c7cc245

File tree

6 files changed

+201
-16
lines changed

6 files changed

+201
-16
lines changed

karma.browser.conf.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ module.exports = (config) => {
66
files: [
77
{ pattern: "dist/ObjectStoreProvider.spec.js" },
88
{ pattern: "dist/SortedBTree.spec.js" },
9+
{ pattern: "dist/LogWriter.spec.js" },
910
],
1011
customLaunchers: {
1112
FirefoxHeadless: {

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@microsoft/objectstoreprovider",
3-
"version": "0.6.42",
3+
"version": "0.6.43",
44
"description": "A cross-browser object store library",
55
"author": "Mukundan Kavanur Kidambi <[email protected]>",
66
"scripts": {

src/IndexedDbProvider.ts

Lines changed: 84 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ import {
5757
TransactionToken,
5858
TransactionLockHelper,
5959
} from "./TransactionLockHelper";
60+
import { LogWriter } from "./LogWriter";
6061

6162
const IndexPrefix = "nsp_i_";
6263

@@ -80,7 +81,7 @@ export class IndexedDbProvider extends DbProvider {
8081
private _handleOnClose: OnCloseHandler | undefined = undefined;
8182

8283
private _lockHelper: TransactionLockHelper | undefined;
83-
private logger: IObjectStoreProviderLogger;
84+
private logWriter: LogWriter;
8485

8586
// By default, it uses the in-browser indexed db factory, but you can pass in an explicit factory. Currently only used for unit tests.
8687
constructor(
@@ -91,7 +92,7 @@ export class IndexedDbProvider extends DbProvider {
9192
) {
9293
super();
9394

94-
this.logger = logger ? logger : console;
95+
this.logWriter = new LogWriter(logger ? logger : console);
9596

9697
if (explicitDbFactory) {
9798
this._dbFactory = explicitDbFactory;
@@ -155,20 +156,29 @@ export class IndexedDbProvider extends DbProvider {
155156

156157
if (!this._dbFactory) {
157158
// Couldn't even find a supported indexeddb object on the browser...
158-
return Promise.reject<void>("No support for IndexedDB in this browser");
159+
const message = `No support for IndexedDB in this browser, returning`;
160+
this.logWriter.error(message);
161+
return Promise.reject<void>(message);
159162
}
160163

161164
if (wipeIfExists) {
165+
this.logWriter.log(`Wiping db`, { dbName });
162166
try {
163167
let req = this._dbFactory.deleteDatabase(dbName);
164168
await IndexedDbProvider.WrapRequest(req);
165-
} catch (e) {
169+
} catch (e: any) {
166170
// Don't care
171+
this.logWriter.error(
172+
`Wiping db failed, message: ${e?.message}. Ignoring and proceeding further`,
173+
{ dbName }
174+
);
167175
}
176+
this.logWriter.log(`Wiping db success`, { dbName });
168177
}
169178

170179
this._lockHelper = new TransactionLockHelper(schema, true);
171180

181+
this.logWriter.log(`Opening db, version: ${schema.version}`, { dbName });
172182
const dbOpen = this._dbFactory.open(dbName, schema.version);
173183

174184
let migrationPutters: Promise<void>[] = [];
@@ -179,9 +189,12 @@ export class IndexedDbProvider extends DbProvider {
179189
const trans = target.transaction;
180190

181191
if (!trans) {
192+
this.logWriter.error(`No transaction, unable to do upgrade`);
182193
throw new Error("onupgradeneeded: target is null!");
183194
}
184195

196+
this.logWriter.log(`Upgrade needed for db`, { dbName });
197+
185198
// Avoid clearing object stores when event.oldVersion returns 0.
186199
// oldVersion returns 0 if db doesn't exist yet: https://developer.mozilla.org/en-US/docs/Web/API/IDBVersionChangeEvent/oldVersion
187200
if (event.oldVersion) {
@@ -190,8 +203,8 @@ export class IndexedDbProvider extends DbProvider {
190203
event.oldVersion < schema.lastUsableVersion
191204
) {
192205
// Clear all stores if it's past the usable version
193-
this.logger.log(
194-
"Old version detected (" + event.oldVersion + "), clearing all data"
206+
this.logWriter.log(
207+
`Old version detected (${event.oldVersion}), clearing all data`
195208
);
196209
each(db.objectStoreNames, (name) => {
197210
db.deleteObjectStore(name);
@@ -204,9 +217,12 @@ export class IndexedDbProvider extends DbProvider {
204217
db.deleteObjectStore(storeName);
205218
}
206219
});
220+
221+
this.logWriter.log(`Deleted all object stores`, { dbName });
207222
}
208223

209224
// Create all stores
225+
this.logWriter.log(`Creating stores as part of upgrade process`);
210226
each(schema.stores, (storeSchema) => {
211227
let store: IDBObjectStore;
212228
const storeExistedBefore = includes(
@@ -222,6 +238,10 @@ export class IndexedDbProvider extends DbProvider {
222238
}
223239

224240
// Any is to fix a lib.d.ts issue in TS 2.0.3 - it doesn't realize that keypaths can be compound for some reason...
241+
this.logWriter.log(`Store doesn't exist, creating object store`, {
242+
dbName,
243+
storeName: storeSchema.name,
244+
});
225245
store = db.createObjectStore(storeSchema.name, {
226246
keyPath: primaryKeyPath,
227247
} as any);
@@ -261,6 +281,11 @@ export class IndexedDbProvider extends DbProvider {
261281
}
262282

263283
if (nuke) {
284+
this.logWriter.log(`Index no longer exists, deleting`, {
285+
dbName,
286+
storeName: storeSchema.name,
287+
indexName,
288+
});
264289
store.deleteIndex(indexName);
265290
}
266291
});
@@ -279,6 +304,10 @@ export class IndexedDbProvider extends DbProvider {
279304
throw new Error("Can't use multiEntry and compound keys");
280305
} else {
281306
// Create an object store for the index
307+
this.logWriter.log(`Creating object store and index`, {
308+
dbName,
309+
storeName: storeSchema.name,
310+
});
282311
let indexStore = db.createObjectStore(
283312
storeSchema.name + "_" + indexSchema.name,
284313
{ autoIncrement: true }
@@ -292,6 +321,11 @@ export class IndexedDbProvider extends DbProvider {
292321
}
293322
} else if (isCompoundKeyPath(keyPath)) {
294323
// Going to have to hack the compound index into a column, so here it is.
324+
this.logWriter.log(`Creating index`, {
325+
dbName,
326+
storeName: storeSchema.name,
327+
indexName: indexSchema.name,
328+
});
295329
store.createIndex(
296330
indexSchema.name,
297331
IndexPrefix + indexSchema.name,
@@ -300,11 +334,21 @@ export class IndexedDbProvider extends DbProvider {
300334
}
301335
);
302336
} else {
337+
this.logWriter.log(`Creating index`, {
338+
dbName,
339+
storeName: storeSchema.name,
340+
indexName: indexSchema.name,
341+
});
303342
store.createIndex(indexSchema.name, keyPath, {
304343
unique: indexSchema.unique,
305344
});
306345
}
307346
} else if (indexSchema.fullText) {
347+
this.logWriter.log(`Creating index`, {
348+
dbName,
349+
storeName: storeSchema.name,
350+
indexName: indexSchema.name,
351+
});
308352
store.createIndex(
309353
indexSchema.name,
310354
IndexPrefix + indexSchema.name,
@@ -318,6 +362,11 @@ export class IndexedDbProvider extends DbProvider {
318362
needsMigrate = true;
319363
}
320364
} else {
365+
this.logWriter.log(`Creating index`, {
366+
dbName,
367+
storeName: storeSchema.name,
368+
indexName: indexSchema.name,
369+
});
321370
store.createIndex(indexSchema.name, keyPath, {
322371
unique: indexSchema.unique,
323372
multiEntry: indexSchema.multiEntry,
@@ -339,12 +388,15 @@ export class IndexedDbProvider extends DbProvider {
339388
fakeToken,
340389
schema,
341390
this._fakeComplicatedKeys,
342-
this.logger
391+
this.logWriter
343392
);
344393
const tStore = iTrans.getStore(storeSchema.name);
345394

346395
const cursorReq = store.openCursor();
347396
let thisIndexPutters: Promise<void>[] = [];
397+
this.logWriter.log(`Adding store to migrationPutters`, {
398+
storeName: storeSchema.name,
399+
});
348400
migrationPutters.push(
349401
IndexedDbIndex.iterateOverCursorRequest(cursorReq, (cursor) => {
350402
const err = attempt(() => {
@@ -358,7 +410,15 @@ export class IndexedDbProvider extends DbProvider {
358410
if (err) {
359411
thisIndexPutters.push(Promise.reject<void>(err));
360412
}
361-
}).then(() => Promise.all(thisIndexPutters).then(noop))
413+
}).then(
414+
() => Promise.all(thisIndexPutters).then(noop),
415+
(err) => {
416+
this.logWriter.error(
417+
`Error when iterating over cursor on idb index, message: ${err?.message}`,
418+
{ storeName: storeSchema.name }
419+
);
420+
}
421+
)
362422
);
363423
}
364424
});
@@ -368,7 +428,12 @@ export class IndexedDbProvider extends DbProvider {
368428

369429
return promise.then(
370430
(db) => {
431+
this.logWriter.log(
432+
`Waiting for migrationPutters: ${migrationPutters.length} to complete for db`,
433+
{ dbName }
434+
);
371435
return Promise.all(migrationPutters).then(() => {
436+
this.logWriter.log(`Opening db success`, { dbName });
372437
this._db = db;
373438
this._db.onclose = (event: Event) => {
374439
if (this._handleOnClose) {
@@ -409,14 +474,18 @@ export class IndexedDbProvider extends DbProvider {
409474
err.target.error.name === "VersionError"
410475
) {
411476
if (!wipeIfExists) {
412-
this.logger.log(
413-
"Database version too new, Wiping: " +
414-
(err.target.error.message || err.target.error.name)
477+
this.logWriter.log(
478+
`Database version too new, Wiping: ${
479+
err.target.error.message || err.target.error.name
480+
}`
415481
);
416482

417483
return this.open(dbName, schema, true, verbose);
418484
}
419485
}
486+
this.logWriter.error(`Error opening db, message: ${err?.message}`, {
487+
dbName,
488+
});
420489
return Promise.reject<void>(err);
421490
}
422491
);
@@ -520,7 +589,7 @@ export class IndexedDbProvider extends DbProvider {
520589
transToken,
521590
this._schema!!!,
522591
this._fakeComplicatedKeys,
523-
this.logger
592+
this.logWriter
524593
)
525594
);
526595
}
@@ -538,7 +607,7 @@ class IndexedDbTransaction implements DbTransaction {
538607
private _transToken: TransactionToken,
539608
private _schema: DbSchema,
540609
private _fakeComplicatedKeys: boolean,
541-
private logger: IObjectStoreProviderLogger
610+
private logWriter: LogWriter
542611
) {
543612
this._stores = map(this._transToken.storeNames, (storeName) =>
544613
this._trans.objectStore(storeName)
@@ -566,7 +635,7 @@ class IndexedDbTransaction implements DbTransaction {
566635
);
567636

568637
if (history.length > 1) {
569-
this.logger.warn(
638+
this.logWriter.warn(
570639
"IndexedDbTransaction Errored after Resolution, Swallowing. Error: " +
571640
(this._trans.error ? this._trans.error.message : undefined) +
572641
", History: " +
@@ -590,7 +659,7 @@ class IndexedDbTransaction implements DbTransaction {
590659
);
591660

592661
if (history.length > 1) {
593-
this.logger.warn(
662+
this.logWriter.warn(
594663
"IndexedDbTransaction Aborted after Resolution, Swallowing. Error: " +
595664
(this._trans.error ? this._trans.error.message : undefined) +
596665
", History: " +

src/LogWriter.ts

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import { IObjectStoreProviderLogger } from "./ObjectStoreProvider";
2+
3+
export interface ILoggerContext {
4+
dbName?: string;
5+
storeName?: string;
6+
indexName?: string;
7+
}
8+
9+
export class LogWriter {
10+
constructor(public logger: IObjectStoreProviderLogger) {}
11+
12+
public log(message: string, context?: ILoggerContext) {
13+
const messageToWrite = this.computeMessageToWrite(message, context);
14+
this.logger.log(messageToWrite);
15+
}
16+
17+
public error(message: string, context?: ILoggerContext) {
18+
const messageToWrite = this.computeMessageToWrite(message, context);
19+
this.logger.error(messageToWrite);
20+
}
21+
22+
public warn(message: string, context?: ILoggerContext) {
23+
const messageToWrite = this.computeMessageToWrite(message, context);
24+
this.logger.warn(messageToWrite);
25+
}
26+
27+
private computeMessageToWrite(message: string, context?: ILoggerContext) {
28+
let contextMessages: string[] = [];
29+
if (context) {
30+
for (const key in context) {
31+
const value = context[key as keyof ILoggerContext];
32+
if (!value) {
33+
continue;
34+
}
35+
contextMessages.push(`${key}: ${value}`);
36+
}
37+
}
38+
if (!contextMessages.length) {
39+
return message;
40+
}
41+
return `${message}. ${contextMessages.join(", ")}`;
42+
}
43+
}

0 commit comments

Comments
 (0)