Commit 99ef16cd authored by Vincent Bechu's avatar Vincent Bechu

indexeddbstorage: use callback instead promise

this fix indexeddb usage in firefox service worker, which closes transaction automatically
parent 754e5df9
......@@ -148,9 +148,7 @@
return tx;
}
function handleCursor(request, callback) {
function resolver(resolve, reject) {
// Open DB //
function handleCursor(request, callback, resolve, reject) {
request.onerror = function (error) {
if (request.transaction) {
request.transaction.abort();
......@@ -175,9 +173,6 @@
}
};
}
// XXX Canceller???
return new RSVP.Promise(resolver);
}
IndexedDBStorage.prototype.buildQuery = function (options) {
var result_list = [];
......@@ -198,40 +193,45 @@
}
return openIndexedDB(this)
.push(function (db) {
return new RSVP.Promise(function (resolve, reject) {
var tx = openTransaction(db, ["metadata"], "readonly");
if (options.include_docs === true) {
return handleCursor(tx.objectStore("metadata").index("_id")
.openCursor(), pushIncludedMetadata);
handleCursor(tx.objectStore("metadata").index("_id").openCursor(),
pushIncludedMetadata, resolve, reject);
} else {
handleCursor(tx.objectStore("metadata").index("_id")
.openKeyCursor(), pushMetadata, resolve, reject);
}
return handleCursor(tx.objectStore("metadata").index("_id")
.openKeyCursor(), pushMetadata);
});
})
.push(function () {
return result_list;
});
};
function handleGet(request) {
function resolver(resolve, reject) {
function handleGet(request, resolve, reject) {
request.onerror = reject;
request.onsuccess = function () {
if (request.result) {
resolve(request.result);
}
} else {
// XXX How to get ID
reject(new jIO.util.jIOError("Cannot find document", 404));
};
}
return new RSVP.Promise(resolver);
};
}
IndexedDBStorage.prototype.get = function (id) {
return openIndexedDB(this)
.push(function (db) {
var transaction = openTransaction(db, ["metadata"],
"readonly");
return handleGet(transaction.objectStore("metadata").get(id));
return new RSVP.Promise(function (resolve, reject) {
var transaction = openTransaction(db, ["metadata"], "readonly");
handleGet(
transaction.objectStore("metadata").get(id),
resolve,
reject
);
});
})
.push(function (result) {
return result.doc;
......@@ -247,37 +247,51 @@
return openIndexedDB(this)
.push(function (db) {
return new RSVP.Promise(function (resolve, reject) {
var transaction = openTransaction(db, ["metadata", "attachment"],
"readonly");
return RSVP.all([
handleGet(transaction.objectStore("metadata").get(id)),
handleCursor(transaction.objectStore("attachment").index("_id")
.openCursor(IDBKeyRange.only(id)), addEntry)
]);
function getAttachments() {
handleCursor(
transaction.objectStore("attachment").index("_id")
.openCursor(IDBKeyRange.only(id)),
addEntry,
resolve,
reject
);
}
handleGet(
transaction.objectStore("metadata").get(id),
getAttachments,
reject
);
});
})
.push(function () {
return attachment_dict;
});
};
function handleRequest(request) {
function resolver(resolve, reject) {
function handleRequest(request, resolve, reject) {
request.onerror = reject;
request.onsuccess = function () {
resolve(request.result);
};
}
return new RSVP.Promise(resolver);
}
IndexedDBStorage.prototype.put = function (id, metadata) {
return openIndexedDB(this)
.push(function (db) {
return new RSVP.Promise(function (resolve, reject) {
var transaction = openTransaction(db, ["metadata"], "readwrite");
return handleRequest(transaction.objectStore("metadata").put({
handleRequest(
transaction.objectStore("metadata").put({
"_id": id,
"doc": metadata
}));
}),
resolve,
reject
);
});
});
};
......@@ -286,19 +300,38 @@
}
IndexedDBStorage.prototype.remove = function (id) {
var resolved_amount = 0;
return openIndexedDB(this)
.push(function (db) {
return new RSVP.Promise(function (resolve, reject) {
function resolver() {
if (resolved_amount < 2) {
resolved_amount += 1;
} else {
resolve();
}
}
var transaction = openTransaction(db, ["metadata", "attachment",
"blob"], "readwrite");
return RSVP.all([
handleRequest(transaction
.objectStore("metadata")["delete"](id)),
handleRequest(
transaction.objectStore("metadata")["delete"](id),
resolver,
reject
);
// XXX Why not possible to delete with KeyCursor?
handleCursor(transaction.objectStore("attachment").index("_id")
.openCursor(IDBKeyRange.only(id)), deleteEntry),
.openCursor(IDBKeyRange.only(id)),
deleteEntry,
resolver,
reject
);
handleCursor(transaction.objectStore("blob").index("_id")
.openCursor(IDBKeyRange.only(id)), deleteEntry)
]);
.openCursor(IDBKeyRange.only(id)),
deleteEntry,
resolver,
reject
);
});
});
};
......@@ -312,48 +345,64 @@
}
return openIndexedDB(this)
.push(function (db) {
transaction = openTransaction(db, ["attachment", "blob"], "readonly");
// XXX Should raise if key is not good
return handleGet(transaction.objectStore("attachment")
.get(buildKeyPath([id, name])));
})
.push(function (attachment) {
return new RSVP.Promise(function (resolve, reject) {
transaction = openTransaction(
db,
["attachment", "blob"],
"readonly"
);
function getBlob(attachment) {
var total_length = attachment.info.length,
i,
promise_list = [],
result_list = [],
store = transaction.objectStore("blob"),
start_index,
end_index;
type = attachment.info.content_type;
start = options.start || 0;
end = options.end || total_length;
if (end > total_length) {
end = total_length;
}
if (start < 0 || end < 0) {
throw new jIO.util.jIOError("_start and _end must be positive",
400);
throw new jIO.util.jIOError(
"_start and _end must be positive",
400
);
}
if (start > end) {
throw new jIO.util.jIOError("_start is greater than _end",
400);
}
start_index = Math.floor(start / UNITE);
end_index = Math.floor(end / UNITE);
end_index = Math.floor(end / UNITE) - 1;
if (end % UNITE === 0) {
end_index -= 1;
}
for (i = start_index; i <= end_index; i += 1) {
promise_list.push(
handleGet(store.get(buildKeyPath([id,
name, i])))
function resolver(result) {
result_list.push(result);
resolve(result_list);
}
function getPart(i) {
return function (result) {
if (result) {
result_list.push(result);
}
i += 1;
handleGet(store.get(buildKeyPath([id, name, i])),
(i <= end_index) ? getPart(i) : resolver,
reject
);
};
}
return RSVP.all(promise_list);
getPart(start_index - 1)();
}
// XXX Should raise if key is not good
handleGet(transaction.objectStore("attachment")
.get(buildKeyPath([id, name])),
getBlob,
reject
);
});
})
.push(function (result_list) {
var array_buffer_list = [],
......@@ -374,19 +423,24 @@
});
};
function removeAttachment(transaction, id, name) {
return RSVP.all([
function removeAttachment(transaction, id, name, resolve, reject) {
// XXX How to get the right attachment
handleRequest(transaction.objectStore("attachment")["delete"](
function deleteContent() {
handleCursor(
transaction.objectStore("blob").index("_id_attachment")
.openCursor(IDBKeyRange.only([id, name])),
deleteEntry,
resolve,
reject
);
}
handleRequest(
transaction.objectStore("attachment")["delete"](
buildKeyPath([id, name])
)),
handleCursor(transaction.objectStore("blob").index("_id_attachment")
.openCursor(IDBKeyRange.only(
[id, name]
)),
deleteEntry
)
]);
),
deleteContent,
reject
);
}
IndexedDBStorage.prototype.putAttachment = function (id, name, blob) {
......@@ -414,12 +468,29 @@
// Remove previous attachment
transaction = openTransaction(db, ["attachment", "blob"], "readwrite");
return removeAttachment(transaction, id, name);
})
.push(function () {
var promise_list = [
handleRequest(transaction.objectStore("attachment").put({
return new RSVP.Promise(function (resolve, reject) {
function write() {
var len = blob_part.length - 1,
attachment_store = transaction.objectStore("attachment"),
blob_store = transaction.objectStore("blob");
function putBlobPart(i) {
return function () {
i += 1;
handleRequest(
blob_store.put({
"_key_path": buildKeyPath([id, name, i]),
"_id" : id,
"_attachment" : name,
"_part" : i,
"blob": blob_part[i]
}),
(i < len) ? putBlobPart(i) : resolve,
reject
);
};
}
handleRequest(
attachment_store.put({
"_key_path": buildKeyPath([id, name]),
"_id": id,
"_attachment": name,
......@@ -427,25 +498,13 @@
"content_type": blob.type,
"length": blob.size
}
}))
],
len = blob_part.length,
blob_store = transaction.objectStore("blob"),
i;
for (i = 0; i < len; i += 1) {
promise_list.push(
handleRequest(blob_store.put({
"_key_path": buildKeyPath([id, name,
i]),
"_id" : id,
"_attachment" : name,
"_part" : i,
"blob": blob_part[i]
}))
}),
putBlobPart(-1),
reject
);
}
// Store all new data
return RSVP.all(promise_list);
removeAttachment(transaction, id, name, write, reject);
});
});
};
......@@ -454,7 +513,9 @@
.push(function (db) {
var transaction = openTransaction(db, ["attachment", "blob"],
"readwrite");
return removeAttachment(transaction, id, name);
return new RSVP.Promise(function (resolve, reject) {
removeAttachment(transaction, id, name, resolve, reject);
});
});
};
......
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