1 if (this.importScripts) {
2 importScripts('../../../resources/js-test.js');
3 importScripts('shared.js');
6 description("Test IndexedDB's cursor skips deleted entries.");
8 var names = ['Alpha', 'Bravo', 'Charlie', 'Delta', 'Echo', 'Foxtrot', 'Golf',
9 'Hotel', 'India', 'Juliet', 'Kilo', 'Lima', 'Mike', 'November',
10 'Oscar', 'Papa', 'Quebec', 'Romeo', 'Sierra', 'Tango', 'Uniform',
11 'Victor', 'Whiskey', 'X-ray', 'Yankee', 'Zulu'];
13 indexedDBTest(prepareDatabase, basicCursorTest);
14 function prepareDatabase()
16 db = event.target.result;
17 debug("setVersionSuccess():");
18 self.trans = evalAndLog("trans = event.target.transaction");
19 shouldBeNonNull("trans");
20 trans.onabort = unexpectedAbortCallback;
22 var objectStore = evalAndLog("objectStore = db.createObjectStore('store', {keyPath: 'id'})");
23 evalAndLog("objectStore.createIndex('nameIndex', 'name')");
24 resetObjectStore(function() {});
27 var silentErrorHandler = function() { event.preventDefault(); }
29 function resetObjectStore(callback)
31 debug("\nresetObjectStore():");
32 if (callback === undefined)
33 callback = function () {};
35 var objectStore = trans.objectStore('store');
36 for (var i = 0; i < names.length; i++)
37 objectStore.delete(i).onerror = silentErrorHandler;
38 for (var i = 0; i < names.length; i++)
39 objectStore.add({id: i, name: names[i]}).onerror = unexpectedErrorCallback;
45 function contains(arr, obj)
47 for (var i = 0; i < arr.length; i++) {
58 function testCursor(deleteList, createCursorCommand, callback)
60 debug("\ntestCursor():");
65 request = evalAndLog(createCursorCommand);
67 request.onerror = unexpectedErrorCallback;
68 request.onsuccess = function () {
69 if (event.target.result == null) {
70 // Make sure we have seen every non-deleted item.
71 for (var i = 0; i < names.length; i++) {
72 if (contains(deleted, i))
75 if (!contains(seen, i))
76 testFailed("Cursor did not see item with id: " + i);
79 // Make sure we used every rule in |deleteList|.
80 for (var i = 0; i < deleteList.length; i++) {
81 if (!contains(seen, deleteList[i].id))
82 testFailed("deleteList rule with id: " + deleteList[i].id + " was never used.");
90 cursor = event.target.result;
91 debug(event.target.result.value.id + ": " + event.target.result.value.name);
92 seen.push(event.target.result.value.id);
94 // Make sure we don't see any deleted items.
95 if (contains(deleted, event.target.result.value.id))
96 testFailed("Cursor hit previously deleted element.");
98 for (var i = 0; i < deleteList.length; i++) {
99 if (event.target.result.value.id == deleteList[i].id) {
100 // Delete objects targeted by this id.
101 var targets = deleteList[i].targets;
102 for (var j = 0; j < targets.length; j++) {
103 deleted.push(targets[j]);
104 request = evalAndLog("request = trans.objectStore('store').delete(" + targets[j] + ")");
105 request.onerror = unexpectedErrorCallback;
106 if (j == targets.length - 1)
107 request.onsuccess = function() { cursor.continue(); }
117 function basicCursorTest()
119 debug("basicCursorTest()");
121 evalAndLog("trans = db.transaction(['store'], 'readwrite')");
122 trans.onabort = unexpectedAbortCallback;
123 trans.oncomplete = transactionComplete;
125 var deletes = [{id: 1, targets: [0]},
126 {id: 2, targets: [names.length - 1]},
127 {id: 3, targets: [5,6,7]},
128 {id: 10, targets: [10]},
129 {id: 12, targets: [13]},
130 {id: 15, targets: [14]},
131 {id: 20, targets: [17,18]}
134 testCursor(deletes, "trans.objectStore('store').openCursor(IDBKeyRange.lowerBound(0))", function() { resetObjectStore(reverseCursorTest); });
137 function reverseCursorTest()
139 debug("reverseCursorTest():");
141 var deletes = [{id: 24, targets: [names.length - 1]},
142 {id: 23, targets: [0]},
143 {id: 22, targets: [20, 19, 18]},
144 {id: 15, targets: [15]},
145 {id: 13, targets: [12]},
146 {id: 10, targets: [11]},
147 {id: 5, targets: [7,8]}
150 testCursor(deletes, "trans.objectStore('store').openCursor(IDBKeyRange.lowerBound(0), 'prev')", function() { resetObjectStore(indexCursorTest); });
153 function indexCursorTest()
155 debug("indexCursorTest():");
157 var deletes = [{id: 1, targets: [0]},
158 {id: 2, targets: [names.length - 1]},
159 {id: 3, targets: [5,6,7]},
160 {id: 10, targets: [10]},
161 {id: 12, targets: [13]},
162 {id: 15, targets: [14]},
163 {id: 20, targets: [17,18]}
166 testCursor(deletes, "trans.objectStore('store').index('nameIndex').openCursor(IDBKeyRange.lowerBound('Alpha'))", function() { });
169 function transactionComplete()
171 debug("transactionComplete():");