Commit bd7c3188 authored by Romain Courteaud's avatar Romain Courteaud

IndexedDB storage: only delete attachment related to the document!

openCursor only return one entry per index value by default.
Use IDBKeyRange to get the expected behaviour.
parent 543a7490
...@@ -28,9 +28,9 @@ ...@@ -28,9 +28,9 @@
*/ */
/*jslint nomen: true */ /*jslint nomen: true */
/*global indexedDB, jIO, RSVP, Blob, Math*/ /*global indexedDB, jIO, RSVP, Blob, Math, IDBKeyRange*/
(function (indexedDB, jIO, RSVP, Blob, Math) { (function (indexedDB, jIO, RSVP, Blob, Math, IDBKeyRange) {
"use strict"; "use strict";
// Read only as changing it can lead to data corruption // Read only as changing it can lead to data corruption
...@@ -219,7 +219,7 @@ ...@@ -219,7 +219,7 @@
return RSVP.all([ return RSVP.all([
handleGet(transaction.objectStore("metadata").get(param._id)), handleGet(transaction.objectStore("metadata").get(param._id)),
handleCursor(transaction.objectStore("attachment").index("_id") handleCursor(transaction.objectStore("attachment").index("_id")
.openCursor(), addEntry) .openCursor(IDBKeyRange.only(param._id)), addEntry)
]); ]);
}) })
.push(function (result_list) { .push(function (result_list) {
...@@ -263,9 +263,9 @@ ...@@ -263,9 +263,9 @@
.objectStore("metadata")["delete"](param._id)), .objectStore("metadata")["delete"](param._id)),
// XXX Why not possible to delete with KeyCursor? // XXX Why not possible to delete with KeyCursor?
handleCursor(transaction.objectStore("attachment").index("_id") handleCursor(transaction.objectStore("attachment").index("_id")
.openCursor(), deleteEntry), .openCursor(IDBKeyRange.only(param._id)), deleteEntry),
handleCursor(transaction.objectStore("blob").index("_id") handleCursor(transaction.objectStore("blob").index("_id")
.openCursor(), deleteEntry) .openCursor(IDBKeyRange.only(param._id)), deleteEntry)
]); ]);
}); });
}; };
...@@ -338,7 +338,11 @@ ...@@ -338,7 +338,11 @@
buildKeyPath([param._id, param._attachment]) buildKeyPath([param._id, param._attachment])
)), )),
handleCursor(transaction.objectStore("blob").index("_id_attachment") handleCursor(transaction.objectStore("blob").index("_id_attachment")
.openCursor(), deleteEntry) .openCursor(IDBKeyRange.only(
[param._id, param._attachment]
)),
deleteEntry
)
]); ]);
} }
...@@ -412,4 +416,4 @@ ...@@ -412,4 +416,4 @@
}; };
jIO.addStorage("indexeddb", IndexedDBStorage); jIO.addStorage("indexeddb", IndexedDBStorage);
}(indexedDB, jIO, RSVP, Blob, Math)); }(indexedDB, jIO, RSVP, Blob, Math, IDBKeyRange));
/*jslint nomen: true */ /*jslint nomen: true */
/*global indexedDB, Blob, sinon, IDBDatabase, /*global indexedDB, Blob, sinon, IDBDatabase,
IDBTransaction, IDBIndex, IDBObjectStore, IDBCursor*/ IDBTransaction, IDBIndex, IDBObjectStore, IDBCursor, IDBKeyRange*/
(function (jIO, QUnit, indexedDB, Blob, sinon, IDBDatabase, (function (jIO, QUnit, indexedDB, Blob, sinon, IDBDatabase,
IDBTransaction, IDBIndex, IDBObjectStore, IDBCursor) { IDBTransaction, IDBIndex, IDBObjectStore, IDBCursor, IDBKeyRange) {
"use strict"; "use strict";
var test = QUnit.test, var test = QUnit.test,
stop = QUnit.stop, stop = QUnit.stop,
...@@ -274,7 +274,7 @@ ...@@ -274,7 +274,7 @@
test("spy indexedDB usage", function () { test("spy indexedDB usage", function () {
var context = this; var context = this;
stop(); stop();
expect(15); expect(17);
deleteIndexedDB(context.jio) deleteIndexedDB(context.jio)
.then(function () { .then(function () {
...@@ -292,6 +292,7 @@ ...@@ -292,6 +292,7 @@
context.spy_create_index = sinon.spy(IDBObjectStore.prototype, context.spy_create_index = sinon.spy(IDBObjectStore.prototype,
"createIndex"); "createIndex");
context.spy_cursor = sinon.spy(IDBIndex.prototype, "openCursor"); context.spy_cursor = sinon.spy(IDBIndex.prototype, "openCursor");
context.spy_key_range = sinon.spy(IDBKeyRange, "only");
return context.jio.get({"_id": "foo"}); return context.jio.get({"_id": "foo"});
}) })
...@@ -333,6 +334,10 @@ ...@@ -333,6 +334,10 @@
ok(context.spy_cursor.calledOnce, "cursor count " + ok(context.spy_cursor.calledOnce, "cursor count " +
context.spy_cursor.callCount); context.spy_cursor.callCount);
ok(context.spy_key_range.calledOnce, "key range count " +
context.spy_key_range.callCount);
deepEqual(context.spy_key_range.firstCall.args[0], "foo",
"key range first argument");
}) })
.always(function () { .always(function () {
context.spy_open.restore(); context.spy_open.restore();
...@@ -351,6 +356,8 @@ ...@@ -351,6 +356,8 @@
delete context.spy_create_index; delete context.spy_create_index;
context.spy_cursor.restore(); context.spy_cursor.restore();
delete context.spy_cursor; delete context.spy_cursor;
context.spy_key_range.restore();
delete context.spy_key_range;
}) })
.fail(function (error) { .fail(function (error) {
ok(false, error); ok(false, error);
...@@ -459,7 +466,7 @@ ...@@ -459,7 +466,7 @@
test("spy indexedDB usage", function () { test("spy indexedDB usage", function () {
var context = this; var context = this;
stop(); stop();
expect(31); expect(32);
deleteIndexedDB(context.jio) deleteIndexedDB(context.jio)
.then(function () { .then(function () {
...@@ -474,6 +481,7 @@ ...@@ -474,6 +481,7 @@
context.spy_create_index = sinon.spy(IDBObjectStore.prototype, context.spy_create_index = sinon.spy(IDBObjectStore.prototype,
"createIndex"); "createIndex");
context.spy_cursor = sinon.spy(IDBIndex.prototype, "openCursor"); context.spy_cursor = sinon.spy(IDBIndex.prototype, "openCursor");
context.spy_key_range = sinon.spy(IDBKeyRange, "only");
return context.jio.put({"_id": "foo", "title": "bar"}); return context.jio.put({"_id": "foo", "title": "bar"});
}) })
...@@ -561,6 +569,9 @@ ...@@ -561,6 +569,9 @@
ok(!context.spy_cursor.called, "cursor count " + ok(!context.spy_cursor.called, "cursor count " +
context.spy_cursor.callCount); context.spy_cursor.callCount);
ok(!context.spy_key_range.called, "key range count " +
context.spy_key_range.callCount);
}) })
.always(function () { .always(function () {
context.spy_open.restore(); context.spy_open.restore();
...@@ -579,6 +590,8 @@ ...@@ -579,6 +590,8 @@
delete context.spy_create_index; delete context.spy_create_index;
context.spy_cursor.restore(); context.spy_cursor.restore();
delete context.spy_cursor; delete context.spy_cursor;
context.spy_key_range.restore();
delete context.spy_key_range;
}) })
.fail(function (error) { .fail(function (error) {
ok(false, error); ok(false, error);
...@@ -623,7 +636,7 @@ ...@@ -623,7 +636,7 @@
test("spy indexedDB usage with one document", function () { test("spy indexedDB usage with one document", function () {
var context = this; var context = this;
stop(); stop();
expect(18); expect(21);
deleteIndexedDB(context.jio) deleteIndexedDB(context.jio)
.then(function () { .then(function () {
...@@ -642,6 +655,7 @@ ...@@ -642,6 +655,7 @@
"createIndex"); "createIndex");
context.spy_cursor = sinon.spy(IDBIndex.prototype, "openCursor"); context.spy_cursor = sinon.spy(IDBIndex.prototype, "openCursor");
context.spy_cursor_delete = sinon.spy(IDBCursor.prototype, "delete"); context.spy_cursor_delete = sinon.spy(IDBCursor.prototype, "delete");
context.spy_key_range = sinon.spy(IDBKeyRange, "only");
return context.jio.remove({"_id": "foo"}); return context.jio.remove({"_id": "foo"});
}) })
...@@ -690,6 +704,13 @@ ...@@ -690,6 +704,13 @@
equal(context.spy_cursor_delete.callCount, 0, "cursor count " + equal(context.spy_cursor_delete.callCount, 0, "cursor count " +
context.spy_cursor_delete.callCount); context.spy_cursor_delete.callCount);
ok(context.spy_key_range.calledTwice, "key range count " +
context.spy_key_range.callCount);
deepEqual(context.spy_key_range.firstCall.args[0], "foo",
"key range first argument");
deepEqual(context.spy_key_range.secondCall.args[0], "foo",
"key range first argument");
}) })
.always(function () { .always(function () {
context.spy_open.restore(); context.spy_open.restore();
...@@ -710,6 +731,8 @@ ...@@ -710,6 +731,8 @@
delete context.spy_cursor; delete context.spy_cursor;
context.spy_cursor_delete.restore(); context.spy_cursor_delete.restore();
delete context.spy_cursor_delete; delete context.spy_cursor_delete;
context.spy_key_range.restore();
delete context.spy_key_range;
}) })
.fail(function (error) { .fail(function (error) {
ok(false, error); ok(false, error);
...@@ -722,7 +745,7 @@ ...@@ -722,7 +745,7 @@
test("spy indexedDB usage with 2 attachments", function () { test("spy indexedDB usage with 2 attachments", function () {
var context = this; var context = this;
stop(); stop();
expect(18); expect(21);
deleteIndexedDB(context.jio) deleteIndexedDB(context.jio)
.then(function () { .then(function () {
...@@ -751,6 +774,7 @@ ...@@ -751,6 +774,7 @@
"createIndex"); "createIndex");
context.spy_cursor = sinon.spy(IDBIndex.prototype, "openCursor"); context.spy_cursor = sinon.spy(IDBIndex.prototype, "openCursor");
context.spy_cursor_delete = sinon.spy(IDBCursor.prototype, "delete"); context.spy_cursor_delete = sinon.spy(IDBCursor.prototype, "delete");
context.spy_key_range = sinon.spy(IDBKeyRange, "only");
return context.jio.remove({"_id": "foo"}); return context.jio.remove({"_id": "foo"});
}) })
...@@ -796,9 +820,16 @@ ...@@ -796,9 +820,16 @@
ok(context.spy_cursor.calledTwice, "cursor count " + ok(context.spy_cursor.calledTwice, "cursor count " +
context.spy_cursor.callCount); context.spy_cursor.callCount);
equal(context.spy_cursor_delete.callCount, 3, "cursor count " + equal(context.spy_cursor_delete.callCount, 4, "cursor count " +
context.spy_cursor_delete.callCount); context.spy_cursor_delete.callCount);
ok(context.spy_key_range.calledTwice, "key range count " +
context.spy_key_range.callCount);
deepEqual(context.spy_key_range.firstCall.args[0], "foo",
"key range first argument");
deepEqual(context.spy_key_range.secondCall.args[0], "foo",
"key range first argument");
}) })
.always(function () { .always(function () {
context.spy_open.restore(); context.spy_open.restore();
...@@ -819,6 +850,8 @@ ...@@ -819,6 +850,8 @@
delete context.spy_cursor; delete context.spy_cursor;
context.spy_cursor_delete.restore(); context.spy_cursor_delete.restore();
delete context.spy_cursor_delete; delete context.spy_cursor_delete;
context.spy_key_range.restore();
delete context.spy_key_range;
}) })
.fail(function (error) { .fail(function (error) {
ok(false, error); ok(false, error);
...@@ -1020,7 +1053,7 @@ ...@@ -1020,7 +1053,7 @@
var context = this, var context = this,
attachment = "attachment"; attachment = "attachment";
stop(); stop();
expect(15); expect(17);
deleteIndexedDB(context.jio) deleteIndexedDB(context.jio)
.then(function () { .then(function () {
...@@ -1045,6 +1078,7 @@ ...@@ -1045,6 +1078,7 @@
"createIndex"); "createIndex");
context.spy_cursor = sinon.spy(IDBIndex.prototype, "openCursor"); context.spy_cursor = sinon.spy(IDBIndex.prototype, "openCursor");
context.spy_cursor_delete = sinon.spy(IDBCursor.prototype, "delete"); context.spy_cursor_delete = sinon.spy(IDBCursor.prototype, "delete");
context.spy_key_range = sinon.spy(IDBKeyRange, "only");
return context.jio.removeAttachment({"_id": "foo", return context.jio.removeAttachment({"_id": "foo",
"_attachment": attachment}); "_attachment": attachment});
...@@ -1088,6 +1122,12 @@ ...@@ -1088,6 +1122,12 @@
context.spy_cursor.callCount); context.spy_cursor.callCount);
equal(context.spy_cursor_delete.callCount, 2, "cursor count " + equal(context.spy_cursor_delete.callCount, 2, "cursor count " +
context.spy_cursor_delete.callCount); context.spy_cursor_delete.callCount);
ok(context.spy_key_range.calledOnce, "key range count " +
context.spy_key_range.callCount);
deepEqual(context.spy_key_range.firstCall.args[0],
["foo", "attachment"],
"key range first argument");
}) })
.always(function () { .always(function () {
context.spy_open.restore(); context.spy_open.restore();
...@@ -1108,6 +1148,8 @@ ...@@ -1108,6 +1148,8 @@
delete context.spy_cursor; delete context.spy_cursor;
context.spy_cursor_delete.restore(); context.spy_cursor_delete.restore();
delete context.spy_cursor_delete; delete context.spy_cursor_delete;
context.spy_key_range.restore();
delete context.spy_key_range;
}) })
.fail(function (error) { .fail(function (error) {
ok(false, error); ok(false, error);
...@@ -1133,7 +1175,7 @@ ...@@ -1133,7 +1175,7 @@
var context = this, var context = this,
attachment = "attachment"; attachment = "attachment";
stop(); stop();
expect(21); expect(23);
deleteIndexedDB(context.jio) deleteIndexedDB(context.jio)
.then(function () { .then(function () {
...@@ -1153,6 +1195,7 @@ ...@@ -1153,6 +1195,7 @@
"createIndex"); "createIndex");
context.spy_cursor = sinon.spy(IDBIndex.prototype, "openCursor"); context.spy_cursor = sinon.spy(IDBIndex.prototype, "openCursor");
context.spy_cursor_delete = sinon.spy(IDBCursor.prototype, "delete"); context.spy_cursor_delete = sinon.spy(IDBCursor.prototype, "delete");
context.spy_key_range = sinon.spy(IDBKeyRange, "only");
return context.jio.putAttachment({"_id": "foo", return context.jio.putAttachment({"_id": "foo",
"_attachment": attachment, "_attachment": attachment,
...@@ -1201,6 +1244,11 @@ ...@@ -1201,6 +1244,11 @@
context.spy_cursor.callCount); context.spy_cursor.callCount);
equal(context.spy_cursor_delete.callCount, 0, "delete count " + equal(context.spy_cursor_delete.callCount, 0, "delete count " +
context.spy_cursor_delete.callCount); context.spy_cursor_delete.callCount);
ok(context.spy_key_range.calledOnce, "key range count " +
context.spy_key_range.callCount);
deepEqual(context.spy_key_range.firstCall.args[0],
["foo", "attachment"],
"key range first argument");
equal(context.spy_put.callCount, 3, "put count " + equal(context.spy_put.callCount, 3, "put count " +
context.spy_put.callCount); context.spy_put.callCount);
...@@ -1249,6 +1297,8 @@ ...@@ -1249,6 +1297,8 @@
delete context.spy_cursor; delete context.spy_cursor;
context.spy_cursor_delete.restore(); context.spy_cursor_delete.restore();
delete context.spy_cursor_delete; delete context.spy_cursor_delete;
context.spy_key_range.restore();
delete context.spy_key_range;
}) })
.fail(function (error) { .fail(function (error) {
ok(false, error); ok(false, error);
...@@ -1259,4 +1309,4 @@ ...@@ -1259,4 +1309,4 @@
}); });
}(jIO, QUnit, indexedDB, Blob, sinon, IDBDatabase, }(jIO, QUnit, indexedDB, Blob, sinon, IDBDatabase,
IDBTransaction, IDBIndex, IDBObjectStore, IDBCursor)); IDBTransaction, IDBIndex, IDBObjectStore, IDBCursor, IDBKeyRange));
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