Skip to content
Permalink
Browse files
Modern IDB:Make in-memory ObjectStore cursors work.
https://bugs.webkit.org/show_bug.cgi?id=151196

Reviewed by Darin Adler.

Source/WebCore:

Tests: storage/indexeddb/modern/cursor-2.html
       storage/indexeddb/modern/cursor-3.html
       storage/indexeddb/modern/cursor-4.html
       storage/indexeddb/modern/cursor-5.html
       storage/indexeddb/modern/cursor-6.html
       storage/indexeddb/modern/cursor-7.html
       storage/indexeddb/modern/cursor-8.html
       storage/indexeddb/modern/objectstore-cursor-advance-failures.html
       storage/indexeddb/modern/objectstore-cursor-continue-failures.html

Object store cursors directly hold on to a std::set<>::iterator to act as the cursor.

The object store tells all of its cursors when it is cleared or records are deleted
so the cursors can invalidate their iterators as needed.

In case of such invalidation, the cursor hangs on to the current key value so it can
pick up where it left off in case it is iterated.

* CMakeLists.txt:
* WebCore.xcodeproj/project.pbxproj:

* Modules/indexeddb/IDBGetResult.h:
(WebCore::IDBGetResult::isolatedCopy):

* Modules/indexeddb/IDBKeyRangeData.cpp:
(WebCore::IDBKeyRangeData::containsKey):
(WebCore::IDBKeyRangeData::loggingString):
* Modules/indexeddb/IDBKeyRangeData.h:

* Modules/indexeddb/client/IDBAnyImpl.cpp:
(WebCore::IDBClient::IDBAny::modernIDBCursor):

* Modules/indexeddb/client/IDBCursorImpl.cpp:
(WebCore::IDBClient::IDBCursor::update):
(WebCore::IDBClient::IDBCursor::advance):
(WebCore::IDBClient::IDBCursor::continueFunction):
(WebCore::IDBClient::IDBCursor::setGetResult):
* Modules/indexeddb/client/IDBCursorImpl.h:

* Modules/indexeddb/client/IDBRequestImpl.cpp:
(WebCore::IDBClient::IDBRequest::dispatchEvent):
(WebCore::IDBClient::IDBRequest::didOpenOrIterateCursor):
* Modules/indexeddb/client/IDBRequestImpl.h:
(WebCore::IDBClient::IDBRequest::pendingCursor):

* Modules/indexeddb/client/IDBTransactionImpl.cpp:
(WebCore::IDBClient::IDBTransaction::addRequest): Deleted.

* Modules/indexeddb/client/TransactionOperation.cpp:
(WebCore::IDBClient::TransactionOperation::TransactionOperation):
* Modules/indexeddb/client/TransactionOperation.h:
(WebCore::IDBClient::TransactionOperation::cursorIdentifier):

* Modules/indexeddb/server/IDBBackingStore.h:

* Modules/indexeddb/server/MemoryBackingStoreTransaction.cpp:
(WebCore::IDBServer::MemoryBackingStoreTransaction::objectStoreCleared):
(WebCore::IDBServer::MemoryBackingStoreTransaction::abort):
* Modules/indexeddb/server/MemoryBackingStoreTransaction.h:

* Modules/indexeddb/server/MemoryCursor.cpp: Added.
(WebCore::IDBServer::cursorMap):
(WebCore::IDBServer::MemoryCursor::MemoryCursor):
(WebCore::IDBServer::MemoryCursor::~MemoryCursor):
(WebCore::IDBServer::MemoryCursor::cursorForIdentifier):
* Modules/indexeddb/server/MemoryCursor.h: Added.

* Modules/indexeddb/server/MemoryIDBBackingStore.cpp:
(WebCore::IDBServer::MemoryIDBBackingStore::openCursor):
(WebCore::IDBServer::MemoryIDBBackingStore::iterateCursor):
* Modules/indexeddb/server/MemoryIDBBackingStore.h:

* Modules/indexeddb/server/MemoryObjectStore.cpp:
(WebCore::IDBServer::MemoryObjectStore::clear):
(WebCore::IDBServer::MemoryObjectStore::replaceKeyValueStore):
(WebCore::IDBServer::MemoryObjectStore::deleteRecord):
(WebCore::IDBServer::MemoryObjectStore::addRecord):
(WebCore::IDBServer::MemoryObjectStore::updateCursorsForPutRecord):
(WebCore::IDBServer::MemoryObjectStore::updateCursorsForDeleteRecord):
(WebCore::IDBServer::MemoryObjectStore::maybeOpenCursor):
* Modules/indexeddb/server/MemoryObjectStore.h:
(WebCore::IDBServer::MemoryObjectStore::orderedKeys):

* Modules/indexeddb/server/MemoryObjectStoreCursor.cpp: Added.
(WebCore::IDBServer::MemoryObjectStoreCursor::create):
(WebCore::IDBServer::MemoryObjectStoreCursor::MemoryObjectStoreCursor):
(WebCore::IDBServer::MemoryObjectStoreCursor::objectStoreCleared):
(WebCore::IDBServer::MemoryObjectStoreCursor::keyDeleted):
(WebCore::IDBServer::MemoryObjectStoreCursor::keyAdded):
(WebCore::IDBServer::MemoryObjectStoreCursor::setFirstInRemainingRange):
(WebCore::IDBServer::MemoryObjectStoreCursor::firstForwardIteratorInRemainingRange):
(WebCore::IDBServer::MemoryObjectStoreCursor::firstReverseIteratorInRemainingRange):
(WebCore::IDBServer::MemoryObjectStoreCursor::currentData):
(WebCore::IDBServer::MemoryObjectStoreCursor::incrementForwardIterator):
(WebCore::IDBServer::MemoryObjectStoreCursor::incrementReverseIterator):
(WebCore::IDBServer::MemoryObjectStoreCursor::hasValidPosition):
(WebCore::IDBServer::MemoryObjectStoreCursor::iterate):
* Modules/indexeddb/server/MemoryObjectStoreCursor.h: Added.

* Modules/indexeddb/server/UniqueIDBDatabase.cpp:
(WebCore::IDBServer::UniqueIDBDatabase::iterateCursor):
(WebCore::IDBServer::UniqueIDBDatabase::performIterateCursor):
* Modules/indexeddb/server/UniqueIDBDatabase.h:

* Modules/indexeddb/shared/IDBCursorInfo.h:
(WebCore::IDBCursorInfo::range):

* Modules/indexeddb/shared/IDBRequestData.cpp:
(WebCore::IDBRequestData::IDBRequestData):
(WebCore::IDBRequestData::cursorIdentifier):
* Modules/indexeddb/shared/IDBRequestData.h:

LayoutTests:

* storage/indexeddb/modern/cursor-1-expected.txt:
* storage/indexeddb/modern/cursor-2-expected.txt: Added.
* storage/indexeddb/modern/cursor-2.html: Added.
* storage/indexeddb/modern/cursor-3-expected.txt: Added.
* storage/indexeddb/modern/cursor-3.html: Added.
* storage/indexeddb/modern/cursor-4-expected.txt: Added.
* storage/indexeddb/modern/cursor-4.html: Added.
* storage/indexeddb/modern/cursor-5-expected.txt: Added.
* storage/indexeddb/modern/cursor-5.html: Added.
* storage/indexeddb/modern/cursor-6-expected.txt: Added.
* storage/indexeddb/modern/cursor-6.html: Added.
* storage/indexeddb/modern/cursor-7-expected.txt: Added.
* storage/indexeddb/modern/cursor-7.html: Added.
* storage/indexeddb/modern/cursor-8-expected.txt: Added.
* storage/indexeddb/modern/cursor-8.html: Added.
* storage/indexeddb/modern/objectstore-cursor-advance-failures-expected.txt: Added.
* storage/indexeddb/modern/objectstore-cursor-advance-failures.html: Added.
* storage/indexeddb/modern/objectstore-cursor-continue-failures-expected.txt: Added.
* storage/indexeddb/modern/objectstore-cursor-continue-failures.html: Added.


Canonical link: https://commits.webkit.org/169482@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@192490 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
beidson committed Nov 16, 2015
1 parent 6010186 commit b1c2c2e56960215f6c894bfa297fe545051143ce
Showing 50 changed files with 2,221 additions and 62 deletions.
@@ -1,3 +1,30 @@
2015-11-16 Brady Eidson <beidson@apple.com>

Modern IDB:Make in-memory ObjectStore cursors work.
https://bugs.webkit.org/show_bug.cgi?id=151196

Reviewed by Darin Adler.

* storage/indexeddb/modern/cursor-1-expected.txt:
* storage/indexeddb/modern/cursor-2-expected.txt: Added.
* storage/indexeddb/modern/cursor-2.html: Added.
* storage/indexeddb/modern/cursor-3-expected.txt: Added.
* storage/indexeddb/modern/cursor-3.html: Added.
* storage/indexeddb/modern/cursor-4-expected.txt: Added.
* storage/indexeddb/modern/cursor-4.html: Added.
* storage/indexeddb/modern/cursor-5-expected.txt: Added.
* storage/indexeddb/modern/cursor-5.html: Added.
* storage/indexeddb/modern/cursor-6-expected.txt: Added.
* storage/indexeddb/modern/cursor-6.html: Added.
* storage/indexeddb/modern/cursor-7-expected.txt: Added.
* storage/indexeddb/modern/cursor-7.html: Added.
* storage/indexeddb/modern/cursor-8-expected.txt: Added.
* storage/indexeddb/modern/cursor-8.html: Added.
* storage/indexeddb/modern/objectstore-cursor-advance-failures-expected.txt: Added.
* storage/indexeddb/modern/objectstore-cursor-advance-failures.html: Added.
* storage/indexeddb/modern/objectstore-cursor-continue-failures-expected.txt: Added.
* storage/indexeddb/modern/objectstore-cursor-continue-failures.html: Added.

2015-11-16 Ryan Haddad <ryanhaddad@apple.com>

Removed Yosemite modifier for flaky test http/tests/media/video-preload.html
@@ -1,11 +1,11 @@
This tests basic IDBCursor functionality
Initial upgrade needed: Old version - 0 New version - 1
Error opening cursor (expected for now)
Success opening cursor
Cursor is: [object IDBCursorWithValue]
Cursor direction is: next
Cursor source is: [object IDBObjectStore] (TestObjectStore)
Cursor key is: null
Cursor primary key is: null
Cursor key is: 0
Cursor primary key is: 0
Error opening cursor (expected for now)
Cursor is: [object IDBCursorWithValue]
Cursor direction is: next
@@ -18,12 +18,12 @@ Cursor direction is: next
Cursor source is: [object IDBIndex] (TestIndex1)
Cursor key is: null
Cursor primary key is: null
Error opening cursor (expected for now)
Success opening cursor
Cursor is: [object IDBCursorWithValue]
Cursor direction is: nextunique
Cursor source is: [object IDBObjectStore] (TestObjectStore)
Cursor key is: null
Cursor primary key is: null
Cursor key is: 0
Cursor primary key is: 0
Error opening cursor (expected for now)
Cursor is: [object IDBCursorWithValue]
Cursor direction is: nextunique
@@ -36,12 +36,12 @@ Cursor direction is: nextunique
Cursor source is: [object IDBIndex] (TestIndex1)
Cursor key is: null
Cursor primary key is: null
Error opening cursor (expected for now)
Success opening cursor
Cursor is: [object IDBCursorWithValue]
Cursor direction is: prev
Cursor source is: [object IDBObjectStore] (TestObjectStore)
Cursor key is: null
Cursor primary key is: null
Cursor key is: foo
Cursor primary key is: foo
Error opening cursor (expected for now)
Cursor is: [object IDBCursorWithValue]
Cursor direction is: prev
@@ -54,12 +54,12 @@ Cursor direction is: prev
Cursor source is: [object IDBIndex] (TestIndex1)
Cursor key is: null
Cursor primary key is: null
Error opening cursor (expected for now)
Success opening cursor
Cursor is: [object IDBCursorWithValue]
Cursor direction is: prevunique
Cursor source is: [object IDBObjectStore] (TestObjectStore)
Cursor key is: null
Cursor primary key is: null
Cursor key is: foo
Cursor primary key is: foo
Error opening cursor (expected for now)
Cursor is: [object IDBCursorWithValue]
Cursor direction is: prevunique
@@ -0,0 +1,173 @@
This test checks basic functionality walking a "next" and "prev" cursor on an object store with some records.
Initial upgrade needed: Old version - 0 New version - 1
Success iterating next cursor
Cursor is: [object IDBCursorWithValue]
Cursor direction is: next
Cursor source is: [object IDBObjectStore] (TestObjectStore)
Cursor key is: 0
Cursor value is: Record 0
Cursor primary key is: 0
Success iterating next cursor
Cursor is: [object IDBCursorWithValue]
Cursor direction is: next
Cursor source is: [object IDBObjectStore] (TestObjectStore)
Cursor key is: 1
Cursor value is: Record 1
Cursor primary key is: 1
Success iterating next cursor
Cursor is: [object IDBCursorWithValue]
Cursor direction is: next
Cursor source is: [object IDBObjectStore] (TestObjectStore)
Cursor key is: 2
Cursor value is: Record 2
Cursor primary key is: 2
Success iterating next cursor
Cursor is: [object IDBCursorWithValue]
Cursor direction is: next
Cursor source is: [object IDBObjectStore] (TestObjectStore)
Cursor key is: 3
Cursor value is: Record 3
Cursor primary key is: 3
Success iterating next cursor
Cursor is: [object IDBCursorWithValue]
Cursor direction is: next
Cursor source is: [object IDBObjectStore] (TestObjectStore)
Cursor key is: 4
Cursor value is: Record 4
Cursor primary key is: 4
Success iterating next cursor
Cursor is: [object IDBCursorWithValue]
Cursor direction is: next
Cursor source is: [object IDBObjectStore] (TestObjectStore)
Cursor key is: 5
Cursor value is: Record 5
Cursor primary key is: 5
Success iterating next cursor
Cursor is: [object IDBCursorWithValue]
Cursor direction is: next
Cursor source is: [object IDBObjectStore] (TestObjectStore)
Cursor key is: 6
Cursor value is: Record 6
Cursor primary key is: 6
Success iterating next cursor
Cursor is: [object IDBCursorWithValue]
Cursor direction is: next
Cursor source is: [object IDBObjectStore] (TestObjectStore)
Cursor key is: 7
Cursor value is: Record 7
Cursor primary key is: 7
Success iterating next cursor
Cursor is: [object IDBCursorWithValue]
Cursor direction is: next
Cursor source is: [object IDBObjectStore] (TestObjectStore)
Cursor key is: 8
Cursor value is: Record 8
Cursor primary key is: 8
Success iterating next cursor
Cursor is: [object IDBCursorWithValue]
Cursor direction is: next
Cursor source is: [object IDBObjectStore] (TestObjectStore)
Cursor key is: 9
Cursor value is: Record 9
Cursor primary key is: 9
Success iterating next cursor
Cursor is: [object IDBCursorWithValue]
Cursor direction is: next
Cursor source is: [object IDBObjectStore] (TestObjectStore)
Cursor key is: foo
Cursor value is: [object Object]
Cursor primary key is: foo
Success iterating next cursor
Cursor is: [object IDBCursorWithValue]
Cursor direction is: next
Cursor source is: [object IDBObjectStore] (TestObjectStore)
Cursor key is: undefined
Cursor value is: undefined
Cursor primary key is: undefined
Success iterating prev cursor
Cursor is: [object IDBCursorWithValue]
Cursor direction is: prev
Cursor source is: [object IDBObjectStore] (TestObjectStore)
Cursor key is: foo
Cursor value is: [object Object]
Cursor primary key is: foo
Success iterating prev cursor
Cursor is: [object IDBCursorWithValue]
Cursor direction is: prev
Cursor source is: [object IDBObjectStore] (TestObjectStore)
Cursor key is: 9
Cursor value is: Record 9
Cursor primary key is: 9
Success iterating prev cursor
Cursor is: [object IDBCursorWithValue]
Cursor direction is: prev
Cursor source is: [object IDBObjectStore] (TestObjectStore)
Cursor key is: 8
Cursor value is: Record 8
Cursor primary key is: 8
Success iterating prev cursor
Cursor is: [object IDBCursorWithValue]
Cursor direction is: prev
Cursor source is: [object IDBObjectStore] (TestObjectStore)
Cursor key is: 7
Cursor value is: Record 7
Cursor primary key is: 7
Success iterating prev cursor
Cursor is: [object IDBCursorWithValue]
Cursor direction is: prev
Cursor source is: [object IDBObjectStore] (TestObjectStore)
Cursor key is: 6
Cursor value is: Record 6
Cursor primary key is: 6
Success iterating prev cursor
Cursor is: [object IDBCursorWithValue]
Cursor direction is: prev
Cursor source is: [object IDBObjectStore] (TestObjectStore)
Cursor key is: 5
Cursor value is: Record 5
Cursor primary key is: 5
Success iterating prev cursor
Cursor is: [object IDBCursorWithValue]
Cursor direction is: prev
Cursor source is: [object IDBObjectStore] (TestObjectStore)
Cursor key is: 4
Cursor value is: Record 4
Cursor primary key is: 4
Success iterating prev cursor
Cursor is: [object IDBCursorWithValue]
Cursor direction is: prev
Cursor source is: [object IDBObjectStore] (TestObjectStore)
Cursor key is: 3
Cursor value is: Record 3
Cursor primary key is: 3
Success iterating prev cursor
Cursor is: [object IDBCursorWithValue]
Cursor direction is: prev
Cursor source is: [object IDBObjectStore] (TestObjectStore)
Cursor key is: 2
Cursor value is: Record 2
Cursor primary key is: 2
Success iterating prev cursor
Cursor is: [object IDBCursorWithValue]
Cursor direction is: prev
Cursor source is: [object IDBObjectStore] (TestObjectStore)
Cursor key is: 1
Cursor value is: Record 1
Cursor primary key is: 1
Success iterating prev cursor
Cursor is: [object IDBCursorWithValue]
Cursor direction is: prev
Cursor source is: [object IDBObjectStore] (TestObjectStore)
Cursor key is: 0
Cursor value is: Record 0
Cursor primary key is: 0
Success iterating prev cursor
Cursor is: [object IDBCursorWithValue]
Cursor direction is: prev
Cursor source is: [object IDBObjectStore] (TestObjectStore)
Cursor key is: undefined
Cursor value is: undefined
Cursor primary key is: undefined
Initial upgrade versionchange transaction complete
Done

@@ -0,0 +1,84 @@
This test checks basic functionality walking a "next" and "prev" cursor on an object store with some records.<br>
<div id="logger"></div>
<script>

if (window.testRunner) {
testRunner.waitUntilDone();
testRunner.dumpAsText();
}

function done()
{
log("Done");
if (window.testRunner)
testRunner.notifyDone();
}

function log(message)
{
document.getElementById("logger").innerHTML += message + "<br>";
}

var createRequest = window.indexedDB.open("Cursor2Database", 1);

function logCursor(cursor)
{
log("Cursor is: " + cursor);
log("Cursor direction is: " + cursor.direction);
log("Cursor source is: " + cursor.source + " (" + cursor.source.name + ")");
log("Cursor key is: " + cursor.key);
log("Cursor value is: " + cursor.value);
log("Cursor primary key is: " + cursor.primaryKey);
}

var objectStore;

function setupRequest(request)
{
request.onsuccess = function() {
log("Success iterating " + request.result.direction + " cursor");
logCursor(request.result);
if (request.result.key != undefined)
request.result.continue();
else if (request.result.direction == "next")
setupRequest(objectStore.openCursor(IDBKeyRange.lowerBound(-Infinity), "prev"));
// else
// log("OKAY how?");
}
request.onerror = function(e) {
log("Error iterating cursor");
done();
}
}

createRequest.onupgradeneeded = function(event) {
log("Initial upgrade needed: Old version - " + event.oldVersion + " New version - " + event.newVersion);

var versionTransaction = createRequest.transaction;
var database = event.target.result;
objectStore = database.createObjectStore("TestObjectStore");

for (var i = 0; i < 10; ++i) {
objectStore.put("Record " + i, i);
}
objectStore.put({ bar: "Hello" }, "foo");

setupRequest(objectStore.openCursor());

versionTransaction.onabort = function(event) {
log("Initial upgrade versionchange transaction unexpected aborted");
done();
}

versionTransaction.oncomplete = function(event) {
log("Initial upgrade versionchange transaction complete");
done();
}

versionTransaction.onerror = function(event) {
log("Initial upgrade versionchange transaction unexpected error" + event);
done();
}
}

</script>

0 comments on commit b1c2c2e

Please sign in to comment.