Commit 2abfb7f3 authored by Tristan Cavelier's avatar Tristan Cavelier

indexeddb handles partial_queries

parent 5d33de92
...@@ -85,13 +85,25 @@ ...@@ -85,13 +85,25 @@
} else { } else {
this._indices = []; this._indices = [];
} }
if (typeof description.version === "number" &&
isFinite(description.version)) {
this._version = description.version;
} else {
this._version = 1;
}
function checkIndexedValue(indexed) {
if (typeof indexed !== "string" || indexed === "") {
throw new TypeError("IndexedDBStorage 'indices' must be an " +
"array of non empty strings.");
}
}
var i, l, index; var i, l, index;
for (i = 0, l = this._indices.length; i < l; i += 1) { for (i = 0, l = this._indices.length; i < l; i += 1) {
index = this._indices[i]; index = this._indices[i];
if (typeof index !== "string" || index === "") { if (!Array.isArray(index)) {
throw new TypeError("IndexedDBStorage 'indices' must be an " + index = [index];
"array of non empty strings.");
} }
index.forEach(checkIndexedValue);
} }
} }
...@@ -122,7 +134,8 @@ ...@@ -122,7 +134,8 @@
for (i = 0, l = shared.connector._indices.length; i < l; i += 1) { for (i = 0, l = shared.connector._indices.length; i < l; i += 1) {
index = shared.connector._indices[i]; index = shared.connector._indices[i];
try { try {
shared.store.createIndex(index, index); //console.log('creating index', JSON.stringify(index), index);
shared.store.createIndex(JSON.stringify(index), index);
} catch (ignore) { } catch (ignore) {
// index already exist // index already exist
} }
...@@ -155,7 +168,10 @@ ...@@ -155,7 +168,10 @@
} }
IndexedDBStorage.prototype.createDBIfNecessary = function () { IndexedDBStorage.prototype.createDBIfNecessary = function () {
var shared = {}, open_req = indexedDB.open(this._database_name); var shared = {"connector": this}, open_req = indexedDB.open(
this._database_name,
this._version
);
// No request.abort() is provided so we cannot cancel database creation // No request.abort() is provided so we cannot cancel database creation
return new Promise(function (resolve, reject) { return new Promise(function (resolve, reject) {
shared.reject = reject; shared.reject = reject;
...@@ -180,7 +196,10 @@ ...@@ -180,7 +196,10 @@
shared.reject = reject; shared.reject = reject;
// Open DB // // Open DB //
var open_req = indexedDB.open(shared.connector._database_name); var open_req = indexedDB.open(
shared.connector._database_name,
shared.connector._version
);
open_req.onerror = function (event) { open_req.onerror = function (event) {
reject(event.target.errorCode); reject(event.target.errorCode);
}; };
...@@ -241,7 +260,10 @@ ...@@ -241,7 +260,10 @@
shared.reject = reject; shared.reject = reject;
// Open DB // // Open DB //
var open_req = indexedDB.open(shared.connector._database_name); var open_req = indexedDB.open(
shared.connector._database_name,
shared.connector._version
);
open_req.onerror = function (event) { open_req.onerror = function (event) {
reject(event.target.errorCode); reject(event.target.errorCode);
}; };
...@@ -302,7 +324,10 @@ ...@@ -302,7 +324,10 @@
shared.reject = reject; shared.reject = reject;
// Open DB // // Open DB //
var open_req = indexedDB.open(shared.connector._database_name); var open_req = indexedDB.open(
shared.connector._database_name,
shared.connector._version
);
open_req.onerror = function (event) { open_req.onerror = function (event) {
reject(event.target.errorCode); reject(event.target.errorCode);
}; };
...@@ -373,7 +398,10 @@ ...@@ -373,7 +398,10 @@
shared.reject = reject; shared.reject = reject;
// Open DB // // Open DB //
var open_req = indexedDB.open(shared.connector._database_name); var open_req = indexedDB.open(
shared.connector._database_name,
shared.connector._version
);
open_req.onerror = function (event) { open_req.onerror = function (event) {
reject(event.target.errorCode); reject(event.target.errorCode);
}; };
...@@ -427,27 +455,32 @@ ...@@ -427,27 +455,32 @@
}).then(command.success, command.error, command.notify); }).then(command.success, command.error, command.notify);
}; };
function makeUnsupportedOptionsError(rejected_options) {
throw {
"status": 501,
"error": "UnsupportedOptionError",
"reason": "unsupported option",
"arguments": rejected_options
};
}
// XXX doc string // XXX doc string
IndexedDBStorage.prototype.getList = function (option) { IndexedDBStorage.prototype.getList = function (option) {
var rejected_options = [], supported_options = { var rejected_options = [], supported_options = {
"limit": true, "limit": true,
"select_list": true, "select_list": true,
"include_docs": true "include_docs": true,
}, rows = [], onCancel, open_req; "partial_query": true
}, rows = [], onCancel, open_req, indexeddbstorage = this;
Object.keys(option).forEach(function (opt) { Object.keys(option).forEach(function (opt) {
if (!supported_options[opt]) { if (!supported_options[opt]) {
rejected_options.push(opt); rejected_options.push(opt);
} }
}); });
if (rejected_options.length) { if (rejected_options.length) {
throw { throw makeUnsupportedOptionsError(rejected_options);
"status": 501,
"error": "UnsupportedOptionError",
"reason": "unsupported option",
"arguments": rejected_options
};
} }
open_req = indexedDB.open(this._database_name); open_req = indexedDB.open(this._database_name, this._version);
return new Promise(function (resolve, reject, notify) { return new Promise(function (resolve, reject, notify) {
open_req.onerror = function () { open_req.onerror = function () {
if (open_req.result) { open_req.result.close(); } if (open_req.result) { open_req.result.close(); }
...@@ -456,13 +489,49 @@ ...@@ -456,13 +489,49 @@
open_req.onsuccess = function () { open_req.onsuccess = function () {
var tx, store, index, date, index_req, db = open_req.result; var tx, store, index, date, index_req, db = open_req.result;
try { try {
if (option.partial_query !== undefined) {
// translate query to a string like
// "\"metadata\"" or "[\"metadata1\",\"metadata2\"]"
option.partial_query =
jIO.QueryFactory.create(option.partial_query);
//console.log("original query (as object)", option.partial_query);
if (option.partial_query.type === "simple") {
option.partial_query = JSON.stringify(option.partial_query.key);
} else if (option.partial_query.operator === "AND") {
option.partial_query =
JSON.stringify(
option.partial_query.query_list.map(function (query) {
if (query.type === "simple") {
return query.key;
}
throw makeUnsupportedOptionsError(["partial_query"]);
})
);
} else {
throw makeUnsupportedOptionsError(["partial_query"]);
}
// choose good index according to translated query
indexeddbstorage._indices.some(function (indexed) {
indexed = JSON.stringify(indexed);
if (indexed === option.partial_query) {
index = indexed;
return true;
}
return false;
});
if (index === undefined) {
throw makeUnsupportedOptionsError(["partial_query"]);
}
}
tx = db.transaction("metadata", "readonly"); tx = db.transaction("metadata", "readonly");
onCancel = function () { onCancel = function () {
tx.abort(); tx.abort();
db.close(); db.close();
}; };
store = tx.objectStore("metadata"); store = tx.objectStore("metadata");
index = store.index("_id"); //console.log('using index', index || "_id");
index = store.index(index || "_id");
index_req = index.openCursor(); index_req = index.openCursor();
date = Date.now(); date = Date.now();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment