IDB: openCursor() needs to prime the cursor with first position values
authorbeidson@apple.com <beidson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 31 Jan 2014 20:50:57 +0000 (20:50 +0000)
committerbeidson@apple.com <beidson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 31 Jan 2014 20:50:57 +0000 (20:50 +0000)
https://bugs.webkit.org/show_bug.cgi?id=128008

Reviewed by Alexey Proskuryakov.

Source/WebCore:

* Modules/indexeddb/IDBTransactionBackendOperations.cpp:
(WebCore::OpenCursorOperation::perform): If the server connection returns initial keys/values
  for the cursor, store them.

* Modules/indexeddb/IDBServerConnection.h:

* Modules/indexeddb/leveldb/IDBServerConnectionLevelDB.cpp:
(WebCore::IDBServerConnectionLevelDB::openCursor):
* Modules/indexeddb/leveldb/IDBServerConnectionLevelDB.h:

Source/WebKit2:

Change openCursor() messaging to pass back the initial keys/values
* WebProcess/Databases/IndexedDB/WebIDBServerConnection.cpp:
(WebKit::WebIDBServerConnection::didOpenCursor):
(WebKit::WebIDBServerConnection::openCursor):
* WebProcess/Databases/IndexedDB/WebIDBServerConnection.h:
* WebProcess/Databases/IndexedDB/WebIDBServerConnection.messages.in:

* DatabaseProcess/IndexedDB/DatabaseProcessIDBConnection.cpp:
(WebKit::DatabaseProcessIDBConnection::openCursor):

* DatabaseProcess/IndexedDB/UniqueIDBDatabase.cpp:
(WebKit::UniqueIDBDatabase::openCursor):
(WebKit::UniqueIDBDatabase::cursorAdvance): Const and reference updates.
(WebKit::UniqueIDBDatabase::cursorIterate): Ditto.
(WebKit::UniqueIDBDatabase::openCursorInBackingStore):
(WebKit::UniqueIDBDatabase::didOpenCursorInBackingStore):
* DatabaseProcess/IndexedDB/UniqueIDBDatabase.h:

* DatabaseProcess/IndexedDB/UniqueIDBDatabaseBackingStore.h:
* DatabaseProcess/IndexedDB/sqlite/UniqueIDBDatabaseBackingStoreSQLite.cpp:
(WebKit::UniqueIDBDatabaseBackingStoreSQLite::openCursor):
* DatabaseProcess/IndexedDB/sqlite/UniqueIDBDatabaseBackingStoreSQLite.h:

* DatabaseProcess/IndexedDB/sqlite/SQLiteIDBCursor.cpp:
(WebKit::SQLiteIDBCursor::maybeCreate): After creating the cursor, advance(1) it.

* Shared/AsyncTask.h:
(WebKit::createAsyncTask):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@163187 268f45cc-cd09-0410-ab3c-d52691b4dbfc

17 files changed:
Source/WebCore/ChangeLog
Source/WebCore/Modules/indexeddb/IDBServerConnection.h
Source/WebCore/Modules/indexeddb/IDBTransactionBackendOperations.cpp
Source/WebCore/Modules/indexeddb/leveldb/IDBServerConnectionLevelDB.cpp
Source/WebCore/Modules/indexeddb/leveldb/IDBServerConnectionLevelDB.h
Source/WebKit2/ChangeLog
Source/WebKit2/DatabaseProcess/IndexedDB/DatabaseProcessIDBConnection.cpp
Source/WebKit2/DatabaseProcess/IndexedDB/UniqueIDBDatabase.cpp
Source/WebKit2/DatabaseProcess/IndexedDB/UniqueIDBDatabase.h
Source/WebKit2/DatabaseProcess/IndexedDB/UniqueIDBDatabaseBackingStore.h
Source/WebKit2/DatabaseProcess/IndexedDB/sqlite/SQLiteIDBCursor.cpp
Source/WebKit2/DatabaseProcess/IndexedDB/sqlite/UniqueIDBDatabaseBackingStoreSQLite.cpp
Source/WebKit2/DatabaseProcess/IndexedDB/sqlite/UniqueIDBDatabaseBackingStoreSQLite.h
Source/WebKit2/Shared/AsyncTask.h
Source/WebKit2/WebProcess/Databases/IndexedDB/WebIDBServerConnection.cpp
Source/WebKit2/WebProcess/Databases/IndexedDB/WebIDBServerConnection.h
Source/WebKit2/WebProcess/Databases/IndexedDB/WebIDBServerConnection.messages.in

index 3a3a173..bb13080 100644 (file)
@@ -1,3 +1,20 @@
+2014-01-31  Brady Eidson  <beidson@apple.com>
+
+        IDB: openCursor() needs to prime the cursor with first position values
+        https://bugs.webkit.org/show_bug.cgi?id=128008
+
+        Reviewed by Alexey Proskuryakov.
+
+        * Modules/indexeddb/IDBTransactionBackendOperations.cpp:
+        (WebCore::OpenCursorOperation::perform): If the server connection returns initial keys/values
+          for the cursor, store them.
+
+        * Modules/indexeddb/IDBServerConnection.h:
+
+        * Modules/indexeddb/leveldb/IDBServerConnectionLevelDB.cpp:
+        (WebCore::IDBServerConnectionLevelDB::openCursor):
+        * Modules/indexeddb/leveldb/IDBServerConnectionLevelDB.h:
+
 2014-01-31  Hans Muller  <hmuller@adobe.com>
 
         [CSS Shapes] Image valued shape can fail
index 104a206..9323a2c 100644 (file)
@@ -81,7 +81,7 @@ public:
     virtual void deleteIndex(IDBTransactionBackend&, const DeleteIndexOperation&, std::function<void(PassRefPtr<IDBDatabaseError>)> completionCallback) = 0;
     virtual void get(IDBTransactionBackend&, const GetOperation&, std::function<void(const IDBGetResult&, PassRefPtr<IDBDatabaseError>)> completionCallback) = 0;
     virtual void put(IDBTransactionBackend&, const PutOperation&, std::function<void(PassRefPtr<IDBKey>, PassRefPtr<IDBDatabaseError>)> completionCallback) = 0;
-    virtual void openCursor(IDBTransactionBackend&, const OpenCursorOperation&, std::function<void(int64_t, PassRefPtr<IDBDatabaseError>)> completionCallback) = 0;
+    virtual void openCursor(IDBTransactionBackend&, const OpenCursorOperation&, std::function<void(int64_t, PassRefPtr<IDBKey>, PassRefPtr<IDBKey>, PassRefPtr<SharedBuffer>, PassRefPtr<IDBDatabaseError>)> completionCallback) = 0;
     virtual void count(IDBTransactionBackend&, const CountOperation&, std::function<void(int64_t, PassRefPtr<IDBDatabaseError>)> completionCallback) = 0;
     virtual void deleteRange(IDBTransactionBackend&, const DeleteRangeOperation&, std::function<void(PassRefPtr<IDBDatabaseError>)> completionCallback) = 0;
     virtual void clearObjectStore(IDBTransactionBackend&, const ClearObjectStoreOperation&, std::function<void(PassRefPtr<IDBDatabaseError>)> completionCallback) = 0;
index 4b6b0fc..4568f16 100644 (file)
@@ -154,13 +154,16 @@ void OpenCursorOperation::perform(std::function<void()> completionCallback)
     LOG(StorageAPI, "OpenCursorOperation");
 
     RefPtr<OpenCursorOperation> operation(this);
-    auto callback = [this, operation, completionCallback](int64_t cursorID, PassRefPtr<IDBDatabaseError>) {
+    auto callback = [this, operation, completionCallback](int64_t cursorID, PassRefPtr<IDBKey> key, PassRefPtr<IDBKey> primaryKey, PassRefPtr<SharedBuffer> value, PassRefPtr<IDBDatabaseError>) {
         // FIXME: When the LevelDB port fails to open a backing store cursor it calls onSuccess(nullptr);
         // This seems nonsensical and might have to change soon, breaking them.
         if (!cursorID)
             m_callbacks->onSuccess(static_cast<SharedBuffer*>(0));
         else {
             RefPtr<IDBCursorBackend> cursor = IDBCursorBackend::create(cursorID, m_cursorType, m_taskType, *m_transaction, m_objectStoreID);
+            if (key || primaryKey || value)
+                cursor->updateCursorData(key.get(), primaryKey.get(), value.get());
+
             m_callbacks->onSuccess(cursor, cursor->key(), cursor->primaryKey(), cursor->value());
         }
 
index b7333f9..d4b0048 100644 (file)
@@ -429,7 +429,7 @@ void IDBServerConnectionLevelDB::put(IDBTransactionBackend& transaction, const P
     });
 }
 
-void IDBServerConnectionLevelDB::openCursor(IDBTransactionBackend& transaction, const OpenCursorOperation& operation, std::function<void(int64_t, PassRefPtr<IDBDatabaseError>)> completionCallback)
+void IDBServerConnectionLevelDB::openCursor(IDBTransactionBackend& transaction, const OpenCursorOperation& operation, std::function<void(int64_t, PassRefPtr<IDBKey>, PassRefPtr<IDBKey>, PassRefPtr<SharedBuffer>, PassRefPtr<IDBDatabaseError>)> completionCallback)
 {
     IDBBackingStoreTransactionLevelDB* backingStoreTransaction = m_backingStoreTransactions.get(transaction.id());
     ASSERT(backingStoreTransaction);
@@ -461,7 +461,8 @@ void IDBServerConnectionLevelDB::openCursor(IDBTransactionBackend& transaction,
     }
 
     callOnMainThread([completionCallback, cursorID]() {
-        completionCallback(cursorID, nullptr);
+        // FIXME: Need to actually pass the initial key, primaryKey, and value to the callback.
+        completionCallback(cursorID, nullptr, nullptr, nullptr, nullptr);
     });
 }
 
index e574f38..978bcd2 100644 (file)
@@ -68,7 +68,7 @@ public:
     virtual void deleteIndex(IDBTransactionBackend&, const DeleteIndexOperation&, std::function<void(PassRefPtr<IDBDatabaseError>)> completionCallback) override;
     virtual void get(IDBTransactionBackend&, const GetOperation&, std::function<void(const IDBGetResult&, PassRefPtr<IDBDatabaseError>)> completionCallback) override;
     virtual void put(IDBTransactionBackend&, const PutOperation&, std::function<void(PassRefPtr<IDBKey>, PassRefPtr<IDBDatabaseError>)> completionCallback)  override;
-    virtual void openCursor(IDBTransactionBackend&, const OpenCursorOperation&, std::function<void(int64_t, PassRefPtr<IDBDatabaseError>)> completionCallback) override;
+    virtual void openCursor(IDBTransactionBackend&, const OpenCursorOperation&, std::function<void(int64_t, PassRefPtr<IDBKey>, PassRefPtr<IDBKey>, PassRefPtr<SharedBuffer>, PassRefPtr<IDBDatabaseError>)> completionCallback) override;
     virtual void count(IDBTransactionBackend&, const CountOperation&, std::function<void(int64_t, PassRefPtr<IDBDatabaseError>)> completionCallback) override;
     virtual void deleteRange(IDBTransactionBackend&, const DeleteRangeOperation&, std::function<void(PassRefPtr<IDBDatabaseError>)> completionCallback) override;
     virtual void clearObjectStore(IDBTransactionBackend&, const ClearObjectStoreOperation&, std::function<void(PassRefPtr<IDBDatabaseError>)> completionCallback) override;
index 98be160..7bac41c 100644 (file)
@@ -1,3 +1,39 @@
+2014-01-31  Brady Eidson  <beidson@apple.com>
+
+        IDB: openCursor() needs to prime the cursor with first position values
+        https://bugs.webkit.org/show_bug.cgi?id=128008
+
+        Reviewed by Alexey Proskuryakov.
+
+        Change openCursor() messaging to pass back the initial keys/values
+        * WebProcess/Databases/IndexedDB/WebIDBServerConnection.cpp:
+        (WebKit::WebIDBServerConnection::didOpenCursor):
+        (WebKit::WebIDBServerConnection::openCursor):
+        * WebProcess/Databases/IndexedDB/WebIDBServerConnection.h:
+        * WebProcess/Databases/IndexedDB/WebIDBServerConnection.messages.in:
+
+        * DatabaseProcess/IndexedDB/DatabaseProcessIDBConnection.cpp:
+        (WebKit::DatabaseProcessIDBConnection::openCursor):
+
+        * DatabaseProcess/IndexedDB/UniqueIDBDatabase.cpp:
+        (WebKit::UniqueIDBDatabase::openCursor):
+        (WebKit::UniqueIDBDatabase::cursorAdvance): Const and reference updates.
+        (WebKit::UniqueIDBDatabase::cursorIterate): Ditto.
+        (WebKit::UniqueIDBDatabase::openCursorInBackingStore):
+        (WebKit::UniqueIDBDatabase::didOpenCursorInBackingStore):
+        * DatabaseProcess/IndexedDB/UniqueIDBDatabase.h:
+
+        * DatabaseProcess/IndexedDB/UniqueIDBDatabaseBackingStore.h:
+        * DatabaseProcess/IndexedDB/sqlite/UniqueIDBDatabaseBackingStoreSQLite.cpp:
+        (WebKit::UniqueIDBDatabaseBackingStoreSQLite::openCursor):
+        * DatabaseProcess/IndexedDB/sqlite/UniqueIDBDatabaseBackingStoreSQLite.h:
+
+        * DatabaseProcess/IndexedDB/sqlite/SQLiteIDBCursor.cpp:
+        (WebKit::SQLiteIDBCursor::maybeCreate): After creating the cursor, advance(1) it.
+
+        * Shared/AsyncTask.h:
+        (WebKit::createAsyncTask):
+
 2014-01-31  Beth Dakin  <bdakin@apple.com>
 
         Sideways 'wobble' when scrolling with trackpad on Mavericks\r
index 260f18c..2a64e33 100644 (file)
@@ -272,8 +272,9 @@ void DatabaseProcessIDBConnection::openCursor(uint64_t requestID, int64_t transa
 
     LOG(IDB, "DatabaseProcess openCursor request ID %llu, object store id %lli", requestID, objectStoreID);
     RefPtr<DatabaseProcessIDBConnection> connection(this);
-    m_uniqueIDBDatabase->openCursor(IDBIdentifier(*this, transactionID), objectStoreID, indexID, static_cast<IndexedDB::CursorDirection>(cursorDirection), static_cast<IndexedDB::CursorType>(cursorType), static_cast<IDBDatabaseBackend::TaskType>(taskType), keyRangeData, [connection, requestID](int64_t cursorID, uint32_t errorCode, const String& errorMessage) {
-        connection->send(Messages::WebIDBServerConnection::DidOpenCursor(requestID, cursorID, errorCode, errorMessage));
+    m_uniqueIDBDatabase->openCursor(IDBIdentifier(*this, transactionID), objectStoreID, indexID, static_cast<IndexedDB::CursorDirection>(cursorDirection), static_cast<IndexedDB::CursorType>(cursorType), static_cast<IDBDatabaseBackend::TaskType>(taskType), keyRangeData, [connection, requestID](int64_t cursorID, const IDBKeyData& resultKey, const IDBKeyData& primaryKey, PassRefPtr<SharedBuffer> value, uint32_t errorCode, const String& errorMessage) {
+        IPC::DataReference data = value ? IPC::DataReference(reinterpret_cast<const uint8_t*>(value->data()), value->size()) : IPC::DataReference();
+        connection->send(Messages::WebIDBServerConnection::DidOpenCursor(requestID, cursorID, resultKey, primaryKey, data, errorCode, errorMessage));
     });
 }
 
index c49574e..85c3f3b 100644 (file)
@@ -549,21 +549,21 @@ void UniqueIDBDatabase::getRecord(const IDBIdentifier& transactionIdentifier, in
     postDatabaseTask(createAsyncTask(*this, &UniqueIDBDatabase::getRecordFromBackingStore, requestID, transactionIdentifier, m_metadata->objectStores.get(objectStoreID), indexID, keyRangeData, cursorType));
 }
 
-void UniqueIDBDatabase::openCursor(const IDBIdentifier& transactionIdentifier, int64_t objectStoreID, int64_t indexID, IndexedDB::CursorDirection cursorDirection, IndexedDB::CursorType cursorType, IDBDatabaseBackend::TaskType taskType, const IDBKeyRangeData& keyRangeData, std::function<void(int64_t, uint32_t, const String&)> callback)
+void UniqueIDBDatabase::openCursor(const IDBIdentifier& transactionIdentifier, int64_t objectStoreID, int64_t indexID, IndexedDB::CursorDirection cursorDirection, IndexedDB::CursorType cursorType, IDBDatabaseBackend::TaskType taskType, const IDBKeyRangeData& keyRangeData, std::function<void(int64_t, const IDBKeyData&, const IDBKeyData&, PassRefPtr<SharedBuffer>, uint32_t, const String&)> callback)
 {
     ASSERT(isMainThread());
 
     if (!m_acceptingNewRequests) {
-        callback(0, INVALID_STATE_ERR, "Unable to open cursor in database because it has shut down");
+        callback(0, nullptr, nullptr, nullptr, INVALID_STATE_ERR, "Unable to open cursor in database because it has shut down");
         return;
     }
 
     ASSERT(m_metadata->objectStores.contains(objectStoreID));
 
-    RefPtr<AsyncRequest> request = AsyncRequestImpl<int64_t, uint32_t, const String&>::create([this, callback](int64_t cursorID, uint32_t errorCode, const String& errorMessage) {
-        callback(cursorID, errorCode, errorMessage);
+    RefPtr<AsyncRequest> request = AsyncRequestImpl<int64_t, const IDBKeyData&, const IDBKeyData&, PassRefPtr<SharedBuffer>, uint32_t, const String&>::create([this, callback](int64_t cursorID, const IDBKeyData& key, const IDBKeyData& primaryKey, PassRefPtr<SharedBuffer> value, uint32_t errorCode, const String& errorMessage) {
+        callback(cursorID, key, primaryKey, value, errorCode, errorMessage);
     }, [this, callback]() {
-        callback(0, INVALID_STATE_ERR, "Unable to get record from database");
+        callback(0, nullptr, nullptr, nullptr, INVALID_STATE_ERR, "Unable to get record from database");
     });
 
     uint64_t requestID = request->requestID();
@@ -572,7 +572,7 @@ void UniqueIDBDatabase::openCursor(const IDBIdentifier& transactionIdentifier, i
     postDatabaseTask(createAsyncTask(*this, &UniqueIDBDatabase::openCursorInBackingStore, requestID, transactionIdentifier, objectStoreID, indexID, cursorDirection, cursorType, taskType, keyRangeData));
 }
 
-void UniqueIDBDatabase::cursorAdvance(const IDBIdentifier& cursorIdentifier, uint64_t count, std::function<void(IDBKeyData, IDBKeyData, PassRefPtr<SharedBuffer>, uint32_t, const String&)> callback)
+void UniqueIDBDatabase::cursorAdvance(const IDBIdentifier& cursorIdentifier, uint64_t count, std::function<void(const IDBKeyData&, const IDBKeyData&, PassRefPtr<SharedBuffer>, uint32_t, const String&)> callback)
 {
     ASSERT(isMainThread());
 
@@ -581,7 +581,7 @@ void UniqueIDBDatabase::cursorAdvance(const IDBIdentifier& cursorIdentifier, uin
         return;
     }
 
-    RefPtr<AsyncRequest> request = AsyncRequestImpl<IDBKeyData, IDBKeyData, PassRefPtr<SharedBuffer>, uint32_t, const String&>::create([this, callback](IDBKeyData key, IDBKeyData primaryKey, PassRefPtr<SharedBuffer> value, uint32_t errorCode, const String& errorMessage) {
+    RefPtr<AsyncRequest> request = AsyncRequestImpl<const IDBKeyData&, const IDBKeyData&, PassRefPtr<SharedBuffer>, uint32_t, const String&>::create([this, callback](const IDBKeyData& key, const IDBKeyData& primaryKey, PassRefPtr<SharedBuffer> value, uint32_t errorCode, const String& errorMessage) {
         callback(key, primaryKey, value, errorCode, errorMessage);
     }, [this, callback]() {
         callback(nullptr, nullptr, nullptr, INVALID_STATE_ERR, "Unable to advance cursor in database");
@@ -593,7 +593,7 @@ void UniqueIDBDatabase::cursorAdvance(const IDBIdentifier& cursorIdentifier, uin
     postDatabaseTask(createAsyncTask(*this, &UniqueIDBDatabase::advanceCursorInBackingStore, requestID, cursorIdentifier, count));
 }
 
-void UniqueIDBDatabase::cursorIterate(const IDBIdentifier& cursorIdentifier, const IDBKeyData& key, std::function<void(IDBKeyData, IDBKeyData, PassRefPtr<SharedBuffer>, uint32_t, const String&)> callback)
+void UniqueIDBDatabase::cursorIterate(const IDBIdentifier& cursorIdentifier, const IDBKeyData& key, std::function<void(const IDBKeyData&, const IDBKeyData&, PassRefPtr<SharedBuffer>, uint32_t, const String&)> callback)
 {
     ASSERT(isMainThread());
 
@@ -602,7 +602,7 @@ void UniqueIDBDatabase::cursorIterate(const IDBIdentifier& cursorIdentifier, con
         return;
     }
 
-    RefPtr<AsyncRequest> request = AsyncRequestImpl<IDBKeyData, IDBKeyData, PassRefPtr<SharedBuffer>, uint32_t, const String&>::create([this, callback](IDBKeyData key, IDBKeyData primaryKey, PassRefPtr<SharedBuffer> value, uint32_t errorCode, const String& errorMessage) {
+    RefPtr<AsyncRequest> request = AsyncRequestImpl<const IDBKeyData&, const IDBKeyData&, PassRefPtr<SharedBuffer>, uint32_t, const String&>::create([this, callback](const IDBKeyData& key, const IDBKeyData& primaryKey, PassRefPtr<SharedBuffer> value, uint32_t errorCode, const String& errorMessage) {
         callback(key, primaryKey, value, errorCode, errorMessage);
     }, [this, callback]() {
         callback(nullptr, nullptr, nullptr, INVALID_STATE_ERR, "Unable to iterate cursor in database");
@@ -888,24 +888,27 @@ void UniqueIDBDatabase::openCursorInBackingStore(uint64_t requestID, const IDBId
     ASSERT(m_backingStore);
 
     int64_t cursorID = 0;
+    IDBKeyData key;
+    IDBKeyData primaryKey;
+    Vector<char> value;
     int32_t errorCode = 0;
     String errorMessage;
-    bool success = m_backingStore->openCursor(transactionIdentifier, objectStoreID, indexID, cursorDirection, cursorType, taskType, keyRange, cursorID);
+    bool success = m_backingStore->openCursor(transactionIdentifier, objectStoreID, indexID, cursorDirection, cursorType, taskType, keyRange, cursorID, key, primaryKey, value);
 
     if (!success) {
         errorCode = IDBDatabaseException::UnknownError;
         errorMessage = ASCIILiteral("Unknown error opening cursor in backing store");
     }
 
-    postMainThreadTask(createAsyncTask(*this, &UniqueIDBDatabase::didOpenCursorInBackingStore, requestID, cursorID, errorCode, errorMessage));
+    postMainThreadTask(createAsyncTask(*this, &UniqueIDBDatabase::didOpenCursorInBackingStore, requestID, cursorID, key, primaryKey, value, errorCode, errorMessage));
 }
 
-void UniqueIDBDatabase::didOpenCursorInBackingStore(uint64_t requestID, int64_t cursorID, uint32_t errorCode, const String& errorMessage)
+void UniqueIDBDatabase::didOpenCursorInBackingStore(uint64_t requestID, int64_t cursorID, const IDBKeyData& key, const IDBKeyData& primaryKey, const Vector<char>& value, uint32_t errorCode, const String& errorMessage)
 {
     RefPtr<AsyncRequest> request = m_pendingDatabaseTasks.take(requestID);
     ASSERT(request);
 
-    request->completeRequest(cursorID, errorCode, errorMessage);
+    request->completeRequest(cursorID, key, primaryKey, SharedBuffer::create(value.data(), value.size()), errorCode, errorMessage);
 }
 
 void UniqueIDBDatabase::advanceCursorInBackingStore(uint64_t requestID, const IDBIdentifier& cursorIdentifier, uint64_t count)
index 1f3aa4c..b534c8f 100644 (file)
@@ -87,9 +87,9 @@ public:
     void putRecord(const IDBIdentifier& transactionIdentifier, int64_t objectStoreID, const WebCore::IDBKeyData&, const IPC::DataReference& value, int64_t putMode, const Vector<int64_t>& indexIDs, const Vector<Vector<WebCore::IDBKeyData>>& indexKeys, std::function<void(const WebCore::IDBKeyData&, uint32_t, const String&)> callback);
     void getRecord(const IDBIdentifier& transactionIdentifier, int64_t objectStoreID, int64_t indexID, const WebCore::IDBKeyRangeData&, WebCore::IndexedDB::CursorType, std::function<void(const WebCore::IDBGetResult&, uint32_t, const String&)> callback);
 
-    void openCursor(const IDBIdentifier& transactionIdentifier, int64_t objectStoreID, int64_t indexID, WebCore::IndexedDB::CursorDirection, WebCore::IndexedDB::CursorType, WebCore::IDBDatabaseBackend::TaskType, const WebCore::IDBKeyRangeData&, std::function<void(int64_t, uint32_t, const String&)> callback);
-    void cursorAdvance(const IDBIdentifier& cursorIdentifier, uint64_t count, std::function<void(WebCore::IDBKeyData, WebCore::IDBKeyData, PassRefPtr<WebCore::SharedBuffer>, uint32_t, const String&)> callback);
-    void cursorIterate(const IDBIdentifier& cursorIdentifier, const WebCore::IDBKeyData&, std::function<void(WebCore::IDBKeyData, WebCore::IDBKeyData, PassRefPtr<WebCore::SharedBuffer>, uint32_t, const String&)> callback);
+    void openCursor(const IDBIdentifier& transactionIdentifier, int64_t objectStoreID, int64_t indexID, WebCore::IndexedDB::CursorDirection, WebCore::IndexedDB::CursorType, WebCore::IDBDatabaseBackend::TaskType, const WebCore::IDBKeyRangeData&, std::function<void(int64_t, const WebCore::IDBKeyData&, const WebCore::IDBKeyData&, PassRefPtr<WebCore::SharedBuffer>, uint32_t, const String&)> callback);
+    void cursorAdvance(const IDBIdentifier& cursorIdentifier, uint64_t count, std::function<void(const WebCore::IDBKeyData&, const WebCore::IDBKeyData&, PassRefPtr<WebCore::SharedBuffer>, uint32_t, const String&)> callback);
+    void cursorIterate(const IDBIdentifier& cursorIdentifier, const WebCore::IDBKeyData&, std::function<void(const WebCore::IDBKeyData&, const WebCore::IDBKeyData&, PassRefPtr<WebCore::SharedBuffer>, uint32_t, const String&)> callback);
 
     void count(const IDBIdentifier& transactionIdentifier, int64_t objectStoreID, int64_t indexID, const WebCore::IDBKeyRangeData&, std::function<void(int64_t, uint32_t, const String&)> callback);
     void deleteRange(const IDBIdentifier& transactionIdentifier, int64_t objectStoreID, const WebCore::IDBKeyRangeData&, std::function<void(uint32_t, const String&)> callback);
@@ -159,7 +159,7 @@ private:
     void didDeleteIndex(uint64_t requestID, bool success);
     void didPutRecordInBackingStore(uint64_t requestID, const WebCore::IDBKeyData&, uint32_t errorCode, const String& errorMessage);
     void didGetRecordFromBackingStore(uint64_t requestID, const WebCore::IDBGetResult&, uint32_t errorCode, const String& errorMessage);
-    void didOpenCursorInBackingStore(uint64_t requestID, int64_t cursorID, uint32_t errorCode, const String& errorMessage);
+    void didOpenCursorInBackingStore(uint64_t requestID, int64_t cursorID, const WebCore::IDBKeyData&, const WebCore::IDBKeyData&, const Vector<char>&, uint32_t errorCode, const String& errorMessage);
     void didAdvanceCursorInBackingStore(uint64_t requestID, const WebCore::IDBKeyData&, const WebCore::IDBKeyData&, const Vector<char>&, uint32_t errorCode, const String& errorMessage);
     void didIterateCursorInBackingStore(uint64_t requestID, const WebCore::IDBKeyData&, const WebCore::IDBKeyData&, const Vector<char>&, uint32_t errorCode, const String& errorMessage);
     void didCountInBackingStore(uint64_t requestID, int64_t count, uint32_t errorCode, const String& errorMessage);
index a5c9af9..4a0b8c4 100644 (file)
@@ -74,7 +74,7 @@ public:
     virtual bool getKeyRangeRecordFromObjectStore(const IDBIdentifier& transactionIdentifier, int64_t objectStoreID, const WebCore::IDBKeyRange&, RefPtr<WebCore::SharedBuffer>& result, RefPtr<WebCore::IDBKey>& resultKey) = 0;
     virtual bool count(const IDBIdentifier& transactionIdentifier, int64_t objectStoreID, int64_t indexID, const WebCore::IDBKeyRangeData&, int64_t& count) = 0;
 
-    virtual bool openCursor(const IDBIdentifier& transactionIdentifier, int64_t objectStoreID, int64_t indexID, WebCore::IndexedDB::CursorDirection, WebCore::IndexedDB::CursorType, WebCore::IDBDatabaseBackend::TaskType, const WebCore::IDBKeyRangeData&, int64_t& cursorID) = 0;
+    virtual bool openCursor(const IDBIdentifier& transactionIdentifier, int64_t objectStoreID, int64_t indexID, WebCore::IndexedDB::CursorDirection, WebCore::IndexedDB::CursorType, WebCore::IDBDatabaseBackend::TaskType, const WebCore::IDBKeyRangeData&, int64_t& cursorID, WebCore::IDBKeyData&, WebCore::IDBKeyData&, Vector<char>&) = 0;
     virtual bool advanceCursor(const IDBIdentifier& cursorIdentifier, uint64_t count, WebCore::IDBKeyData&, WebCore::IDBKeyData&, Vector<char>&) = 0;
     virtual bool iterateCursor(const IDBIdentifier& cursorIdentifier, const WebCore::IDBKeyData&, WebCore::IDBKeyData&, WebCore::IDBKeyData&, Vector<char>&) = 0;
 };
index d699da8..2104821 100644 (file)
@@ -45,6 +45,9 @@ std::unique_ptr<SQLiteIDBCursor> SQLiteIDBCursor::maybeCreate(SQLiteIDBTransacti
     if (!cursor->establishStatement())
         return nullptr;
 
+    if (!cursor->advance(1))
+        return nullptr;
+
     return cursor;
 }
 
index 3ae9b03..34d9baa 100644 (file)
@@ -938,7 +938,7 @@ bool UniqueIDBDatabaseBackingStoreSQLite::count(const IDBIdentifier& transaction
     return true;
 }
 
-bool UniqueIDBDatabaseBackingStoreSQLite::openCursor(const IDBIdentifier& transactionIdentifier, int64_t objectStoreID, int64_t indexID, IndexedDB::CursorDirection cursorDirection, IndexedDB::CursorType cursorType, IDBDatabaseBackend::TaskType taskType, const IDBKeyRangeData& keyRange, int64_t& cursorID)
+bool UniqueIDBDatabaseBackingStoreSQLite::openCursor(const IDBIdentifier& transactionIdentifier, int64_t objectStoreID, int64_t indexID, IndexedDB::CursorDirection cursorDirection, IndexedDB::CursorType cursorType, IDBDatabaseBackend::TaskType taskType, const IDBKeyRangeData& keyRange, int64_t& cursorID, IDBKeyData& key, IDBKeyData& primaryKey, Vector<char>& value)
 {
     ASSERT(!isMainThread());
     ASSERT(m_sqliteDB);
@@ -956,6 +956,9 @@ bool UniqueIDBDatabaseBackingStoreSQLite::openCursor(const IDBIdentifier& transa
 
     m_cursors.set(cursor->identifier(), cursor);
     cursorID = cursor->identifier().id();
+    key = cursor->currentKey();
+    primaryKey = cursor->currentPrimaryKey();
+    value = cursor->currentValue();
 
     return true;
 }
index 742e0a7..7c27b94 100644 (file)
@@ -80,7 +80,7 @@ public:
     virtual bool getKeyRangeRecordFromObjectStore(const IDBIdentifier& transactionIdentifier, int64_t objectStoreID, const WebCore::IDBKeyRange&, RefPtr<WebCore::SharedBuffer>& result, RefPtr<WebCore::IDBKey>& resultKey) override;
     virtual bool count(const IDBIdentifier& transactionIdentifier, int64_t objectStoreID, int64_t indexID, const WebCore::IDBKeyRangeData&, int64_t& count) override;
 
-    virtual bool openCursor(const IDBIdentifier& transactionIdentifier, int64_t objectStoreID, int64_t indexID, WebCore::IndexedDB::CursorDirection, WebCore::IndexedDB::CursorType, WebCore::IDBDatabaseBackend::TaskType, const WebCore::IDBKeyRangeData&, int64_t& cursorID) override;
+    virtual bool openCursor(const IDBIdentifier& transactionIdentifier, int64_t objectStoreID, int64_t indexID, WebCore::IndexedDB::CursorDirection, WebCore::IndexedDB::CursorType, WebCore::IDBDatabaseBackend::TaskType, const WebCore::IDBKeyRangeData&, int64_t& cursorID, WebCore::IDBKeyData&, WebCore::IDBKeyData&, Vector<char>&) override;
     virtual bool advanceCursor(const IDBIdentifier& cursorIdentifier, uint64_t count, WebCore::IDBKeyData&, WebCore::IDBKeyData&, Vector<char>&) override;
     virtual bool iterateCursor(const IDBIdentifier& cursorIdentifier, const WebCore::IDBKeyData&, WebCore::IDBKeyData&, WebCore::IDBKeyData&, Vector<char>&) override;
 
index 1449ced..a028091 100644 (file)
@@ -176,6 +176,30 @@ std::unique_ptr<AsyncTask> createAsyncTask(
         WebCore::CrossThreadCopier<P6>::copy(parameter6));
 }
 
+template<typename T, typename P1, typename MP1, typename P2, typename MP2, typename P3, typename MP3, typename P4, typename MP4, typename P5, typename MP5, typename P6, typename MP6, typename P7, typename MP7>
+std::unique_ptr<AsyncTask> createAsyncTask(
+    T& callee,
+    void (T::*method)(MP1, MP2, MP3, MP4, MP5, MP6, MP7),
+    const P1& parameter1,
+    const P2& parameter2,
+    const P3& parameter3,
+    const P4& parameter4,
+    const P5& parameter5,
+    const P6& parameter6,
+    const P7& parameter7)
+{
+    return std::make_unique<AsyncTaskImpl<T, MP1, MP2, MP3, MP4, MP5, MP6, MP7>>(
+        &callee,
+        method,
+        WebCore::CrossThreadCopier<P1>::copy(parameter1),
+        WebCore::CrossThreadCopier<P2>::copy(parameter2),
+        WebCore::CrossThreadCopier<P3>::copy(parameter3),
+        WebCore::CrossThreadCopier<P4>::copy(parameter4),
+        WebCore::CrossThreadCopier<P5>::copy(parameter5),
+        WebCore::CrossThreadCopier<P6>::copy(parameter6),
+        WebCore::CrossThreadCopier<P7>::copy(parameter7));
+}
+
 template<typename T, typename P1, typename MP1, typename P2, typename MP2, typename P3, typename MP3, typename P4, typename MP4, typename P5, typename MP5, typename P6, typename MP6, typename P7, typename MP7, typename P8, typename MP8>
 std::unique_ptr<AsyncTask> createAsyncTask(
     T& callee,
index aedd690..8f1298a 100644 (file)
@@ -444,7 +444,7 @@ void WebIDBServerConnection::didGetRecord(uint64_t requestID, const WebCore::IDB
     serverRequest->completeRequest(getResult, errorCode ? IDBDatabaseError::create(errorCode, errorMessage) : nullptr);
 }
 
-void WebIDBServerConnection::didOpenCursor(uint64_t requestID, int64_t cursorID, uint32_t errorCode, const String& errorMessage)
+void WebIDBServerConnection::didOpenCursor(uint64_t requestID, int64_t cursorID, WebCore::IDBKeyData& key, WebCore::IDBKeyData& primaryKey, const IPC::DataReference& valueData, uint32_t errorCode, const String& errorMessage)
 {
     LOG(IDB, "WebProcess didOpenCursor request ID %llu (error - %s)", requestID, errorMessage.utf8().data());
 
@@ -453,7 +453,8 @@ void WebIDBServerConnection::didOpenCursor(uint64_t requestID, int64_t cursorID,
     if (!serverRequest)
         return;
 
-    serverRequest->completeRequest(cursorID, errorCode ? IDBDatabaseError::create(errorCode, errorMessage) : nullptr);
+    RefPtr<SharedBuffer> value = SharedBuffer::create(valueData.data(), valueData.size());
+    serverRequest->completeRequest(cursorID, key.maybeCreateIDBKey(), primaryKey.maybeCreateIDBKey(), value.release(), errorCode ? IDBDatabaseError::create(errorCode, errorMessage) : nullptr);
 }
 
 void WebIDBServerConnection::didAdvanceCursor(uint64_t requestID, WebCore::IDBKeyData& key, WebCore::IDBKeyData& primaryKey, const IPC::DataReference& valueData, uint32_t errorCode, const String& errorMessage)
@@ -627,12 +628,12 @@ void WebIDBServerConnection::didChangeDatabaseVersion(uint64_t requestID, bool s
     serverRequest->completeRequest(success ? nullptr : IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Unknown error occured changing database version"));
 }
 
-void WebIDBServerConnection::openCursor(IDBTransactionBackend&, const OpenCursorOperation& operation, std::function<void(int64_t, PassRefPtr<IDBDatabaseError>)> completionCallback)
+void WebIDBServerConnection::openCursor(IDBTransactionBackend&, const OpenCursorOperation& operation, std::function<void(int64_t, PassRefPtr<IDBKey>, PassRefPtr<IDBKey>, PassRefPtr<SharedBuffer>, PassRefPtr<IDBDatabaseError>)> completionCallback)
 {
-    RefPtr<AsyncRequest> serverRequest = AsyncRequestImpl<int64_t, PassRefPtr<IDBDatabaseError>>::create(completionCallback);
+    RefPtr<AsyncRequest> serverRequest = AsyncRequestImpl<int64_t, PassRefPtr<IDBKey>, PassRefPtr<IDBKey>, PassRefPtr<SharedBuffer>, PassRefPtr<IDBDatabaseError>>::create(completionCallback);
 
     serverRequest->setAbortHandler([completionCallback]() {
-        completionCallback(0, IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Unknown error occured opening database cursor"));
+        completionCallback(0, nullptr, nullptr, nullptr, IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Unknown error occured opening database cursor"));
     });
 
     uint64_t requestID = serverRequest->requestID();
index f5e2096..0d50360 100644 (file)
@@ -72,7 +72,7 @@ public:
     virtual void deleteIndex(WebCore::IDBTransactionBackend&, const WebCore::DeleteIndexOperation&, std::function<void(PassRefPtr<WebCore::IDBDatabaseError>)> completionCallback) override;
     virtual void get(WebCore::IDBTransactionBackend&, const WebCore::GetOperation&, std::function<void(const WebCore::IDBGetResult&, PassRefPtr<WebCore::IDBDatabaseError>)> completionCallback) override;
     virtual void put(WebCore::IDBTransactionBackend&, const WebCore::PutOperation&, std::function<void(PassRefPtr<WebCore::IDBKey>, PassRefPtr<WebCore::IDBDatabaseError>)> completionCallback) override;
-    virtual void openCursor(WebCore::IDBTransactionBackend&, const WebCore::OpenCursorOperation&, std::function<void(int64_t, PassRefPtr<WebCore::IDBDatabaseError>)> completionCallback) override;
+    virtual void openCursor(WebCore::IDBTransactionBackend&, const WebCore::OpenCursorOperation&, std::function<void(int64_t, PassRefPtr<WebCore::IDBKey>, PassRefPtr<WebCore::IDBKey>, PassRefPtr<WebCore::SharedBuffer>, PassRefPtr<WebCore::IDBDatabaseError>)> completionCallback) override;
     virtual void count(WebCore::IDBTransactionBackend&, const WebCore::CountOperation&, std::function<void(int64_t, PassRefPtr<WebCore::IDBDatabaseError>)> completionCallback) override;
     virtual void deleteRange(WebCore::IDBTransactionBackend&, const WebCore::DeleteRangeOperation&, std::function<void(PassRefPtr<WebCore::IDBDatabaseError>)> completionCallback) override;
     virtual void clearObjectStore(WebCore::IDBTransactionBackend&, const WebCore::ClearObjectStoreOperation&, std::function<void(PassRefPtr<WebCore::IDBDatabaseError>)> completionCallback) override;
@@ -110,7 +110,7 @@ private:
     void didDeleteIndex(uint64_t requestID, bool success);
     void didPutRecord(uint64_t requestID, const WebCore::IDBKeyData&, uint32_t errorCode, const String& errorMessage);
     void didGetRecord(uint64_t requestID, const WebCore::IDBGetResult&, uint32_t errorCode, const String& errorMessage);
-    void didOpenCursor(uint64_t requestID, int64_t cursorID, uint32_t errorCode, const String& errorMessage);
+    void didOpenCursor(uint64_t requestID, int64_t cursorID, WebCore::IDBKeyData&, WebCore::IDBKeyData&, const IPC::DataReference&, uint32_t errorCode, const String& errorMessage);
     void didAdvanceCursor(uint64_t requestID, WebCore::IDBKeyData&, WebCore::IDBKeyData&, const IPC::DataReference&, uint32_t errorCode, const String& errorMessage);
     void didIterateCursor(uint64_t requestID, WebCore::IDBKeyData&, WebCore::IDBKeyData&, const IPC::DataReference&, uint32_t errorCode, const String& errorMessage);
     void didCount(uint64_t requestID, int64_t count, uint32_t errorCode, const String& errorMessage);
index 9ff3d8b..cba850d 100644 (file)
@@ -40,7 +40,7 @@ messages -> WebIDBServerConnection LegacyReceiver {
     DidDeleteIndex(uint64_t requestID, bool success)
     DidPutRecord(uint64_t requestID, WebCore::IDBKeyData resultKey, uint32_t errorCode, String errorMessage)
     DidGetRecord(uint64_t requestID, WebCore::IDBGetResult getResult, uint32_t errorCode, String errorMessage)
-    DidOpenCursor(uint64_t requestID, int64_t cursorID, uint32_t errorCode, String errorMessage)
+    DidOpenCursor(uint64_t requestID, int64_t cursorID, WebCore::IDBKeyData key, WebCore::IDBKeyData primaryKey, IPC::DataReference value, uint32_t errorCode, String errorMessage)
     DidAdvanceCursor(uint64_t requestID, WebCore::IDBKeyData key, WebCore::IDBKeyData primaryKey, IPC::DataReference value, uint32_t errorCode, String errorMessage)
     DidIterateCursor(uint64_t requestID, WebCore::IDBKeyData key, WebCore::IDBKeyData primaryKey, IPC::DataReference value, uint32_t errorCode, String errorMessage)
     DidCount(uint64_t requestID, int64_t count, uint32_t errorCode, String errorMessage)