Bug 1406181 - Add openForPrincipal static method and changes to IDB cursor wrapping in IndexedDB.jsm. r=aswan

MozReview-Commit-ID: vicgBmHhJp

--HG--
extra : rebase_source : 2fde2dee2d46a21240c161eb77b69e02ac601cf1
This commit is contained in:
Luca Greco 2018-04-14 15:10:29 +02:00
Родитель 5111b8831a
Коммит 855569b623
1 изменённых файлов: 73 добавлений и 13 удалений

Просмотреть файл

@ -123,20 +123,52 @@ function forwardMethods(cls, target, methods) {
} }
class Cursor { class Cursor {
constructor(cursor, source) { constructor(cursorRequest, source) {
this.cursor = cursor; this.cursorRequest = cursorRequest;
this.source = source; this.source = source;
this.cursor = null;
}
get done() {
return !this.cursor;
}
// This method is used internally to wait the cursor's IDBRequest to have been
// completed and the internal cursor has been updated (used when we initially
// create the cursor from Cursed.openCursor/openKeyCursor, and in the method
// of this class defined by defineCursorUpdateMethods).
async awaitRequest() {
this.cursor = await wrapRequest(this.cursorRequest);
return this;
} }
} }
/**
* Define the Cursor class methods that update the cursor (continue, continuePrimaryKey
* and advance) as async functions that call the related IDBCursor methods and
* await the cursor's IDBRequest to be completed.
*
* @param {function} cls
* The class constructor for which to define the cursor update methods.
* @param {Array<string>} methods
* A list of "cursor update" method names to define.
*/
function defineCursorUpdateMethods(cls, methods) {
for (let method of methods) {
cls.prototype[method] = async function(...args) {
const promise = this.awaitRequest();
this.cursor[method](...args);
await promise;
};
}
}
defineCursorUpdateMethods(Cursor, ["advance", "continue", "continuePrimaryKey"]);
forwardGetters(Cursor, "cursor", forwardGetters(Cursor, "cursor",
["direction", "key", "primaryKey"]); ["direction", "key", "primaryKey"]);
wrapMethods(Cursor, "cursor", ["delete", "update"]); wrapMethods(Cursor, "cursor", ["delete", "update"]);
forwardMethods(Cursor, "cursor",
["advance", "continue", "continuePrimaryKey"]);
class CursorWithValue extends Cursor {} class CursorWithValue extends Cursor {}
forwardGetters(CursorWithValue, "cursor", ["value"]); forwardGetters(CursorWithValue, "cursor", ["value"]);
@ -147,15 +179,13 @@ class Cursed {
} }
openCursor(...args) { openCursor(...args) {
return wrapRequest(this.cursed.openCursor(...args)).then(cursor => { const cursor = new CursorWithValue(this.cursed.openCursor(...args), this);
return new CursorWithValue(cursor, this); return cursor.awaitRequest();
});
} }
openKeyCursor(...args) { openKeyCursor(...args) {
return wrapRequest(this.cursed.openKeyCursor(...args)).then(cursor => { const cursor = new Cursor(this.cursed.openKeyCursor(...args), this);
return new Cursor(cursor, this); return cursor.awaitRequest();
});
} }
} }
@ -252,7 +282,37 @@ class IndexedDB {
*/ */
static open(dbName, options, onupgradeneeded = null) { static open(dbName, options, onupgradeneeded = null) {
let request = indexedDB.open(dbName, options); let request = indexedDB.open(dbName, options);
return this._wrapOpenRequest(request, onupgradeneeded);
}
/**
* Opens the database for a given principal and with the given name, returns
* a Promise which resolves to an IndexedDB instance when the operation completes.
*
* @param {nsIPrincipal} principal
* The principal to open the database for.
* @param {string} dbName
* The name of the database to open.
* @param {object} options
* The options with which to open the database.
* @param {integer} options.version
* The schema version with which the database needs to be opened. If
* the database does not exist, or its current schema version does
* not match, the `onupgradeneeded` function will be called.
* @param {function} [onupgradeneeded]
* A function which will be called with an IndexedDB object as its
* first parameter when the database needs to be created, or its
* schema needs to be upgraded. If this function is not provided, the
* {@link #onupgradeneeded} method will be called instead.
*
* @returns {Promise<IndexedDB>}
*/
static openForPrincipal(principal, dbName, options, onupgradeneeded = null) {
const request = indexedDB.openForPrincipal(principal, dbName, options);
return this._wrapOpenRequest(request, onupgradeneeded);
}
static _wrapOpenRequest(request, onupgradeneeded = null) {
request.onupgradeneeded = event => { request.onupgradeneeded = event => {
let db = new this(request.result); let db = new this(request.result);
if (onupgradeneeded) { if (onupgradeneeded) {
@ -262,7 +322,7 @@ class IndexedDB {
} }
}; };
return wrapRequest(request).then(db => new IndexedDB(db)); return wrapRequest(request).then(db => new this(db));
} }
constructor(db) { constructor(db) {