| if (this.importScripts) { |
| importScripts('../../../resources/js-test.js'); |
| importScripts('shared.js'); |
| } |
| |
| description("Test IndexedDB's cursor skips deleted entries."); |
| |
| var names = ['Alpha', 'Bravo', 'Charlie', 'Delta', 'Echo', 'Foxtrot', 'Golf', |
| 'Hotel', 'India', 'Juliet', 'Kilo', 'Lima', 'Mike', 'November', |
| 'Oscar', 'Papa', 'Quebec', 'Romeo', 'Sierra', 'Tango', 'Uniform', |
| 'Victor', 'Whiskey', 'X-ray', 'Yankee', 'Zulu']; |
| |
| indexedDBTest(prepareDatabase, basicCursorTest); |
| function prepareDatabase() |
| { |
| db = event.target.result; |
| debug("setVersionSuccess():"); |
| self.trans = evalAndLog("trans = event.target.transaction"); |
| shouldBeNonNull("trans"); |
| trans.onabort = unexpectedAbortCallback; |
| |
| var objectStore = evalAndLog("objectStore = db.createObjectStore('store', {keyPath: 'id'})"); |
| evalAndLog("objectStore.createIndex('nameIndex', 'name')"); |
| resetObjectStore(function() {}); |
| } |
| |
| var silentErrorHandler = function() { event.preventDefault(); } |
| |
| function resetObjectStore(callback) |
| { |
| debug("\nresetObjectStore():"); |
| if (callback === undefined) |
| callback = function () {}; |
| |
| var objectStore = trans.objectStore('store'); |
| for (var i = 0; i < names.length; i++) |
| objectStore.delete(i).onerror = silentErrorHandler; |
| for (var i = 0; i < names.length; i++) |
| objectStore.add({id: i, name: names[i]}).onerror = unexpectedErrorCallback; |
| |
| debug(""); |
| callback(); |
| } |
| |
| function contains(arr, obj) |
| { |
| for (var i = 0; i < arr.length; i++) { |
| if (arr[i] == obj) |
| return true; |
| } |
| return false; |
| } |
| |
| var cursor; |
| var deleted; |
| var seen; |
| |
| function testCursor(deleteList, createCursorCommand, callback) |
| { |
| debug("\ntestCursor():"); |
| deleted = []; |
| seen = []; |
| |
| // Create the cursor. |
| request = evalAndLog(createCursorCommand); |
| |
| request.onerror = unexpectedErrorCallback; |
| request.onsuccess = function () { |
| if (event.target.result == null) { |
| // Make sure we have seen every non-deleted item. |
| for (var i = 0; i < names.length; i++) { |
| if (contains(deleted, i)) |
| continue; |
| |
| if (!contains(seen, i)) |
| testFailed("Cursor did not see item with id: " + i); |
| } |
| |
| // Make sure we used every rule in |deleteList|. |
| for (var i = 0; i < deleteList.length; i++) { |
| if (!contains(seen, deleteList[i].id)) |
| testFailed("deleteList rule with id: " + deleteList[i].id + " was never used."); |
| } |
| |
| debug(""); |
| callback(); |
| return; |
| } |
| |
| cursor = event.target.result; |
| debug(event.target.result.value.id + ": " + event.target.result.value.name); |
| seen.push(event.target.result.value.id); |
| |
| // Make sure we don't see any deleted items. |
| if (contains(deleted, event.target.result.value.id)) |
| testFailed("Cursor hit previously deleted element."); |
| |
| for (var i = 0; i < deleteList.length; i++) { |
| if (event.target.result.value.id == deleteList[i].id) { |
| // Delete objects targeted by this id. |
| var targets = deleteList[i].targets; |
| for (var j = 0; j < targets.length; j++) { |
| deleted.push(targets[j]); |
| request = evalAndLog("request = trans.objectStore('store').delete(" + targets[j] + ")"); |
| request.onerror = unexpectedErrorCallback; |
| if (j == targets.length - 1) |
| request.onsuccess = function() { cursor.continue(); } |
| } |
| return; |
| } |
| } |
| |
| cursor.continue(); |
| } |
| } |
| |
| function basicCursorTest() |
| { |
| debug("basicCursorTest()"); |
| |
| evalAndLog("trans = db.transaction(['store'], 'readwrite')"); |
| trans.onabort = unexpectedAbortCallback; |
| trans.oncomplete = transactionComplete; |
| |
| var deletes = [{id: 1, targets: [0]}, |
| {id: 2, targets: [names.length - 1]}, |
| {id: 3, targets: [5,6,7]}, |
| {id: 10, targets: [10]}, |
| {id: 12, targets: [13]}, |
| {id: 15, targets: [14]}, |
| {id: 20, targets: [17,18]} |
| ]; |
| |
| testCursor(deletes, "trans.objectStore('store').openCursor(IDBKeyRange.lowerBound(0))", function() { resetObjectStore(reverseCursorTest); }); |
| } |
| |
| function reverseCursorTest() |
| { |
| debug("reverseCursorTest():"); |
| |
| var deletes = [{id: 24, targets: [names.length - 1]}, |
| {id: 23, targets: [0]}, |
| {id: 22, targets: [20, 19, 18]}, |
| {id: 15, targets: [15]}, |
| {id: 13, targets: [12]}, |
| {id: 10, targets: [11]}, |
| {id: 5, targets: [7,8]} |
| ]; |
| |
| testCursor(deletes, "trans.objectStore('store').openCursor(IDBKeyRange.lowerBound(0), 'prev')", function() { resetObjectStore(indexCursorTest); }); |
| } |
| |
| function indexCursorTest() |
| { |
| debug("indexCursorTest():"); |
| |
| var deletes = [{id: 1, targets: [0]}, |
| {id: 2, targets: [names.length - 1]}, |
| {id: 3, targets: [5,6,7]}, |
| {id: 10, targets: [10]}, |
| {id: 12, targets: [13]}, |
| {id: 15, targets: [14]}, |
| {id: 20, targets: [17,18]} |
| ]; |
| |
| testCursor(deletes, "trans.objectStore('store').index('nameIndex').openCursor(IDBKeyRange.lowerBound('Alpha'))", function() { }); |
| } |
| |
| function transactionComplete() |
| { |
| debug("transactionComplete():"); |
| finishJSTest(); |
| } |