IDB: Cursor support - Messaging, IPC, Threading plumbing
authorbeidson@apple.com <beidson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 28 Jan 2014 05:03:45 +0000 (05:03 +0000)
committerbeidson@apple.com <beidson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 28 Jan 2014 05:03:45 +0000 (05:03 +0000)
https://bugs.webkit.org/show_bug.cgi?id=127736

Reviewed by Sam Weinig.

Source/WebCore:

* Modules/indexeddb/IDBCursorBackendOperations.h:
(WebCore::CursorIterationOperation::cursorID):
(WebCore::CursorAdvanceOperation::cursorID):

* Modules/indexeddb/IDBTransactionBackendOperations.h:
(WebCore::OpenCursorOperation::transactionID):

* WebCore.exp.in:

Source/WebKit2:

Pipe three cursor-related calls to the DatabaseProcess, and handle messages
from the database process when it is done handling them:
* WebProcess/Databases/IndexedDB/WebIDBServerConnection.cpp:
(WebKit::WebIDBServerConnection::didOpenCursor):
(WebKit::WebIDBServerConnection::didAdvanceCursor):
(WebKit::WebIDBServerConnection::didIterateCursor):
(WebKit::WebIDBServerConnection::openCursor):
(WebKit::WebIDBServerConnection::cursorAdvance):
(WebKit::WebIDBServerConnection::cursorIterate):
* WebProcess/Databases/IndexedDB/WebIDBServerConnection.h:
* WebProcess/Databases/IndexedDB/WebIDBServerConnection.messages.in:

Pipe the calls through to the appropriate UniqueIDBDatabase:
* DatabaseProcess/IndexedDB/DatabaseProcessIDBConnection.cpp:
(WebKit::DatabaseProcessIDBConnection::openCursor):
(WebKit::DatabaseProcessIDBConnection::cursorAdvance):
(WebKit::DatabaseProcessIDBConnection::cursorIterate):
* DatabaseProcess/IndexedDB/DatabaseProcessIDBConnection.h:
* DatabaseProcess/IndexedDB/DatabaseProcessIDBConnection.messages.in:

Pass the calls to the backing store thread, then message back to the WebProcess
when the requests are complete.
* DatabaseProcess/IndexedDB/UniqueIDBDatabase.cpp:
(WebKit::UniqueIDBDatabase::openCursor):
(WebKit::UniqueIDBDatabase::cursorAdvance):
(WebKit::UniqueIDBDatabase::cursorIterate):
(WebKit::UniqueIDBDatabase::openCursorInBackingStore):
(WebKit::UniqueIDBDatabase::didOpenCursorInBackingStore):
(WebKit::UniqueIDBDatabase::advanceCursorInBackingStore):
(WebKit::UniqueIDBDatabase::didAdvanceCursorInBackingStore):
(WebKit::UniqueIDBDatabase::iterateCursorInBackingStore):
(WebKit::UniqueIDBDatabase::didIterateCursorInBackingStore):
* DatabaseProcess/IndexedDB/UniqueIDBDatabase.h:

* Shared/WebCrossThreadCopier.cpp:
(WebCore::Vector<char>>::copy):
* Shared/WebCrossThreadCopier.h:

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

15 files changed:
Source/WebCore/ChangeLog
Source/WebCore/Modules/indexeddb/IDBCursorBackendOperations.h
Source/WebCore/Modules/indexeddb/IDBTransactionBackendOperations.h
Source/WebCore/WebCore.exp.in
Source/WebKit2/ChangeLog
Source/WebKit2/DatabaseProcess/IndexedDB/DatabaseProcessIDBConnection.cpp
Source/WebKit2/DatabaseProcess/IndexedDB/DatabaseProcessIDBConnection.h
Source/WebKit2/DatabaseProcess/IndexedDB/DatabaseProcessIDBConnection.messages.in
Source/WebKit2/DatabaseProcess/IndexedDB/UniqueIDBDatabase.cpp
Source/WebKit2/DatabaseProcess/IndexedDB/UniqueIDBDatabase.h
Source/WebKit2/Shared/WebCrossThreadCopier.cpp
Source/WebKit2/Shared/WebCrossThreadCopier.h
Source/WebKit2/WebProcess/Databases/IndexedDB/WebIDBServerConnection.cpp
Source/WebKit2/WebProcess/Databases/IndexedDB/WebIDBServerConnection.h
Source/WebKit2/WebProcess/Databases/IndexedDB/WebIDBServerConnection.messages.in

index f6721e8..22cc3eb 100644 (file)
@@ -1,3 +1,19 @@
+2014-01-27  Brady Eidson  <beidson@apple.com>
+
+        IDB: Cursor support - Messaging, IPC, Threading plumbing
+        https://bugs.webkit.org/show_bug.cgi?id=127736
+
+        Reviewed by Sam Weinig.
+
+        * Modules/indexeddb/IDBCursorBackendOperations.h:
+        (WebCore::CursorIterationOperation::cursorID):
+        (WebCore::CursorAdvanceOperation::cursorID):
+
+        * Modules/indexeddb/IDBTransactionBackendOperations.h:
+        (WebCore::OpenCursorOperation::transactionID):
+
+        * WebCore.exp.in:
+
 2014-01-27  Joseph Pecoraro  <pecoraro@apple.com>
 
         WebCore: Enable -Wimplicit-fallthrough and add FALLTHROUGH annotation where needed
index 2dbad1c..467f1de 100644 (file)
@@ -42,6 +42,7 @@ public:
     }
     virtual void perform(std::function<void()> completionCallback) override final;
 
+    int64_t cursorID() const { return m_cursor->id(); }
     IDBKey* key() const { return m_key.get(); }
 
 private:
@@ -65,6 +66,7 @@ public:
     }
     virtual void perform(std::function<void()> completionCallback) override final;
 
+    int64_t cursorID() const { return m_cursor->id(); }
     unsigned long count() const { return m_count; }
 
 private:
index e4d9380..964cb85 100644 (file)
@@ -354,6 +354,7 @@ public:
     }
     virtual void perform(std::function<void()> successCallback) override final;
 
+    int64_t transactionID() const { return m_transaction->id(); }
     int64_t objectStoreID() const { return m_objectStoreID; }
     int64_t indexID() const { return m_indexID; }
     IndexedDB::CursorDirection direction() const { return m_direction; }
index 97fae63..1cf542b 100644 (file)
@@ -3089,6 +3089,7 @@ __ZN7WebCore21CrossThreadCopierBaseILb0ELb0ENS_15IDBKeyRangeDataEE4copyERKS1_
 __ZN7WebCore21CrossThreadCopierBaseILb0ELb0ENS_16IDBIndexMetadataEE4copyERKS1_
 __ZN7WebCore21CrossThreadCopierBaseILb0ELb0ENS_22IDBObjectStoreMetadataEE4copyERKS1_
 __ZN7WebCore21CrossThreadCopierBaseILb0ELb0ENS_9IndexedDB10CursorTypeEE4copyERKS2_
+__ZN7WebCore21CrossThreadCopierBaseILb0ELb0ENS_9IndexedDB15CursorDirectionEE4copyERKS2_
 __ZN7WebCore21CrossThreadCopierBaseILb0ELb0ENS_9IndexedDB15TransactionModeEE4copyERKS2_
 __ZN7WebCore6IDBKeyD1Ev
 #endif
index e8e2848..247675d 100644 (file)
@@ -1,3 +1,48 @@
+2014-01-27  Brady Eidson  <beidson@apple.com>
+
+        IDB: Cursor support - Messaging, IPC, Threading plumbing
+        https://bugs.webkit.org/show_bug.cgi?id=127736
+
+        Reviewed by Sam Weinig.
+
+        Pipe three cursor-related calls to the DatabaseProcess, and handle messages
+        from the database process when it is done handling them:
+        * WebProcess/Databases/IndexedDB/WebIDBServerConnection.cpp:
+        (WebKit::WebIDBServerConnection::didOpenCursor):
+        (WebKit::WebIDBServerConnection::didAdvanceCursor):
+        (WebKit::WebIDBServerConnection::didIterateCursor):
+        (WebKit::WebIDBServerConnection::openCursor):
+        (WebKit::WebIDBServerConnection::cursorAdvance):
+        (WebKit::WebIDBServerConnection::cursorIterate):
+        * WebProcess/Databases/IndexedDB/WebIDBServerConnection.h:
+        * WebProcess/Databases/IndexedDB/WebIDBServerConnection.messages.in:
+
+        Pipe the calls through to the appropriate UniqueIDBDatabase:
+        * DatabaseProcess/IndexedDB/DatabaseProcessIDBConnection.cpp:
+        (WebKit::DatabaseProcessIDBConnection::openCursor):
+        (WebKit::DatabaseProcessIDBConnection::cursorAdvance):
+        (WebKit::DatabaseProcessIDBConnection::cursorIterate):
+        * DatabaseProcess/IndexedDB/DatabaseProcessIDBConnection.h:
+        * DatabaseProcess/IndexedDB/DatabaseProcessIDBConnection.messages.in:
+
+        Pass the calls to the backing store thread, then message back to the WebProcess
+        when the requests are complete.
+        * DatabaseProcess/IndexedDB/UniqueIDBDatabase.cpp:
+        (WebKit::UniqueIDBDatabase::openCursor):
+        (WebKit::UniqueIDBDatabase::cursorAdvance):
+        (WebKit::UniqueIDBDatabase::cursorIterate):
+        (WebKit::UniqueIDBDatabase::openCursorInBackingStore):
+        (WebKit::UniqueIDBDatabase::didOpenCursorInBackingStore):
+        (WebKit::UniqueIDBDatabase::advanceCursorInBackingStore):
+        (WebKit::UniqueIDBDatabase::didAdvanceCursorInBackingStore):
+        (WebKit::UniqueIDBDatabase::iterateCursorInBackingStore):
+        (WebKit::UniqueIDBDatabase::didIterateCursorInBackingStore):
+        * DatabaseProcess/IndexedDB/UniqueIDBDatabase.h:
+
+        * Shared/WebCrossThreadCopier.cpp:
+        (WebCore::Vector<char>>::copy):
+        * Shared/WebCrossThreadCopier.h:
+
 2014-01-27  Joseph Pecoraro  <pecoraro@apple.com>
 
         WebKit2: Enable -Wimplicit-fallthrough and add FALLTHROUGH annotation where needed
index 1505dfb..ab2db76 100644 (file)
@@ -28,6 +28,7 @@
 
 #if ENABLE(INDEXED_DATABASE) && ENABLE(DATABASE_PROCESS)
 
+#include "DataReference.h"
 #include "DatabaseProcess.h"
 #include "DatabaseToWebProcessConnection.h"
 #include "IDBIdentifier.h"
@@ -233,6 +234,41 @@ void DatabaseProcessIDBConnection::getRecord(uint64_t requestID, int64_t transac
     });
 }
 
+void DatabaseProcessIDBConnection::openCursor(uint64_t requestID, int64_t transactionID, int64_t objectStoreID, int64_t indexID, int64_t cursorDirection, int64_t cursorType, int64_t taskType, const WebCore::IDBKeyRangeData& keyRangeData)
+{
+    ASSERT(m_uniqueIDBDatabase);
+
+    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));
+    });
+}
+
+void DatabaseProcessIDBConnection::cursorAdvance(uint64_t requestID, int64_t cursorID, uint64_t count)
+{
+    ASSERT(m_uniqueIDBDatabase);
+
+    LOG(IDB, "DatabaseProcess cursorAdvance request ID %llu, cursor id %lli", requestID, cursorID);
+    RefPtr<DatabaseProcessIDBConnection> connection(this);
+    m_uniqueIDBDatabase->cursorAdvance(IDBIdentifier(*this, cursorID), count, [connection, requestID](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::DidAdvanceCursor(requestID, resultKey, primaryKey, data, errorCode, errorMessage));
+    });
+}
+
+void DatabaseProcessIDBConnection::cursorIterate(uint64_t requestID, int64_t cursorID, const IDBKeyData& key)
+{
+    ASSERT(m_uniqueIDBDatabase);
+
+    LOG(IDB, "DatabaseProcess cursorIterate request ID %llu, cursor id %lli", requestID, cursorID);
+    RefPtr<DatabaseProcessIDBConnection> connection(this);
+    m_uniqueIDBDatabase->cursorIterate(IDBIdentifier(*this, cursorID), key, [connection, requestID](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::DidIterateCursor(requestID, resultKey, primaryKey, data, errorCode, errorMessage));
+    });
+}
+
 IPC::Connection* DatabaseProcessIDBConnection::messageSenderConnection()
 {
     return m_connection->connection();
index 5a7adae..eb72460 100644 (file)
@@ -82,6 +82,10 @@ private:
     void putRecord(uint64_t requestID, int64_t transactionID, int64_t objectStoreID, const WebCore::IDBKeyData&, const IPC::DataReference& value, int64_t putMode, const Vector<int64_t>& indexIDs, const Vector<Vector<WebCore::IDBKeyData>>& indexKeys);
     void getRecord(uint64_t requestID, int64_t transactionID, int64_t objectStoreID, int64_t indexID, const WebCore::IDBKeyRangeData&, int64_t cursorType);
 
+    void openCursor(uint64_t requestID, int64_t transactionID, int64_t objectStoreID, int64_t indexID, int64_t cursorDirection, int64_t cursorType, int64_t taskType, const WebCore::IDBKeyRangeData&);
+    void cursorAdvance(uint64_t requestID, int64_t cursorID, uint64_t count);
+    void cursorIterate(uint64_t requestID, int64_t cursorID, const WebCore::IDBKeyData&);
+
     Ref<DatabaseToWebProcessConnection> m_connection;
     uint64_t m_serverConnectionIdentifier;
 
index 81b1a64..18903a4 100644 (file)
@@ -40,7 +40,11 @@ messages -> DatabaseProcessIDBConnection LegacyReceiver {
     DeleteIndex(uint64_t requestID, int64_t transactionID, int64_t objectStoreID, int64_t indexID)
 
     PutRecord(uint64_t requestID, int64_t transactionID, int64_t objectStoreID, WebCore::IDBKeyData key, IPC::DataReference value, int64_t putMode, Vector<int64_t> indexIDs, Vector<Vector<WebCore::IDBKeyData>> indexKeys)
-    GetRecord(uint64_t requestID, int64_t transactionID, int64_t objectStoreID, int64_t indexID, WebCore::IDBKeyRangeData keyRange, int64_t cursorType);
+    GetRecord(uint64_t requestID, int64_t transactionID, int64_t objectStoreID, int64_t indexID, WebCore::IDBKeyRangeData keyRange, int64_t cursorType)
+    
+    OpenCursor(uint64_t requestID, int64_t transactionID, int64_t objectStoreID, int64_t indexID, int64_t cursorDirection, int64_t cursorType, int64_t taskType, WebCore::IDBKeyRangeData keyRange)
+    CursorAdvance(uint64_t requestID, int64_t cursorID, uint64_t count)
+    CursorIterate(uint64_t requestID, int64_t cursorID, WebCore::IDBKeyData key)
 }
 
 #endif // ENABLE(INDEXED_DATABASE) && ENABLE(DATABASE_PROCESS)
index 34f9330..d527e81 100644 (file)
@@ -547,6 +547,71 @@ 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, WebCore::IndexedDB::CursorDirection cursorDirection, WebCore::IndexedDB::CursorType cursorType, WebCore::IDBDatabaseBackend::TaskType taskType, const WebCore::IDBKeyRangeData& keyRangeData, std::function<void(int64_t, 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");
+        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);
+    }, [this, callback]() {
+        callback(0, INVALID_STATE_ERR, "Unable to get record from database");
+    });
+
+    uint64_t requestID = request->requestID();
+    m_pendingDatabaseTasks.add(requestID, request.release());
+
+    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(WebCore::IDBKeyData, WebCore::IDBKeyData, PassRefPtr<WebCore::SharedBuffer>, uint32_t, const String&)> callback)
+{
+    ASSERT(isMainThread());
+
+    if (!m_acceptingNewRequests) {
+        callback(nullptr, nullptr, nullptr, INVALID_STATE_ERR, "Unable to advance cursor in database because it has shut down");
+        return;
+    }
+
+    RefPtr<AsyncRequest> request = AsyncRequestImpl<WebCore::IDBKeyData, WebCore::IDBKeyData, PassRefPtr<WebCore::SharedBuffer>, uint32_t, const String&>::create([this, callback](WebCore::IDBKeyData key, WebCore::IDBKeyData primaryKey, PassRefPtr<WebCore::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");
+    });
+
+    uint64_t requestID = request->requestID();
+    m_pendingDatabaseTasks.add(requestID, request.release());
+
+    postDatabaseTask(createAsyncTask(*this, &UniqueIDBDatabase::advanceCursorInBackingStore, requestID, cursorIdentifier, count));
+}
+
+void UniqueIDBDatabase::cursorIterate(const IDBIdentifier& cursorIdentifier, const WebCore::IDBKeyData& key, std::function<void(WebCore::IDBKeyData, WebCore::IDBKeyData, PassRefPtr<WebCore::SharedBuffer>, uint32_t, const String&)> callback)
+{
+    ASSERT(isMainThread());
+
+    if (!m_acceptingNewRequests) {
+        callback(nullptr, nullptr, nullptr, INVALID_STATE_ERR, "Unable to iterate cursor in database because it has shut down");
+        return;
+    }
+
+    RefPtr<AsyncRequest> request = AsyncRequestImpl<WebCore::IDBKeyData, WebCore::IDBKeyData, PassRefPtr<WebCore::SharedBuffer>, uint32_t, const String&>::create([this, callback](WebCore::IDBKeyData key, WebCore::IDBKeyData primaryKey, PassRefPtr<WebCore::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");
+    });
+
+    uint64_t requestID = request->requestID();
+    m_pendingDatabaseTasks.add(requestID, request.release());
+
+    postDatabaseTask(createAsyncTask(*this, &UniqueIDBDatabase::iterateCursorInBackingStore, requestID, cursorIdentifier, key));
+}
+
 void UniqueIDBDatabase::openBackingStoreTransaction(const IDBIdentifier& transactionIdentifier, const Vector<int64_t>& objectStoreIDs, IndexedDB::TransactionMode mode)
 {
     ASSERT(!isMainThread());
@@ -762,6 +827,51 @@ void UniqueIDBDatabase::didGetRecordFromBackingStore(uint64_t requestID, const I
     request->completeRequest(result, errorCode, errorMessage);
 }
 
+void UniqueIDBDatabase::openCursorInBackingStore(uint64_t requestID, const IDBIdentifier& transactionIdentifier, int64_t objectStoreID, int64_t indexID, WebCore::IndexedDB::CursorDirection, WebCore::IndexedDB::CursorType, WebCore::IDBDatabaseBackend::TaskType, const WebCore::IDBKeyRangeData&)
+{
+    // FIXME: Implement
+
+    postMainThreadTask(createAsyncTask(*this, &UniqueIDBDatabase::didOpenCursorInBackingStore, requestID, 0, IDBDatabaseException::UnknownError, ASCIILiteral("advancing cursors in backing store not supported yet")));
+}
+
+void UniqueIDBDatabase::didOpenCursorInBackingStore(uint64_t requestID, int64_t cursorID, uint32_t errorCode, const String& errorMessage)
+{
+    RefPtr<AsyncRequest> request = m_pendingDatabaseTasks.take(requestID);
+    ASSERT(request);
+
+    request->completeRequest(cursorID, errorCode, errorMessage);
+}
+
+void UniqueIDBDatabase::advanceCursorInBackingStore(uint64_t requestID, const IDBIdentifier& cursorIdentifier, uint64_t count)
+{
+    // FIXME: Implement
+
+    postMainThreadTask(createAsyncTask(*this, &UniqueIDBDatabase::didAdvanceCursorInBackingStore, requestID, IDBKeyData(), IDBKeyData(), Vector<char>(), IDBDatabaseException::UnknownError, ASCIILiteral("advancing cursors in backing store not supported yet")));
+}
+
+void UniqueIDBDatabase::didAdvanceCursorInBackingStore(uint64_t requestID, const WebCore::IDBKeyData& key, const WebCore::IDBKeyData& primaryKey, const Vector<char>& value, uint32_t errorCode, const String& errorMessage)
+{
+    RefPtr<AsyncRequest> request = m_pendingDatabaseTasks.take(requestID);
+    ASSERT(request);
+
+    request->completeRequest(key, primaryKey, SharedBuffer::create(value.data(), value.size()), errorCode, errorMessage);
+}
+
+void UniqueIDBDatabase::iterateCursorInBackingStore(uint64_t requestID, const IDBIdentifier& cursorIdentifier, const WebCore::IDBKeyData&)
+{
+    // FIXME: Implement
+
+    postMainThreadTask(createAsyncTask(*this, &UniqueIDBDatabase::didIterateCursorInBackingStore, requestID, IDBKeyData(), IDBKeyData(), Vector<char>(), IDBDatabaseException::UnknownError, ASCIILiteral("iterating cursors in backing store not supported yet")));
+}
+
+void UniqueIDBDatabase::didIterateCursorInBackingStore(uint64_t requestID, const WebCore::IDBKeyData& key, const WebCore::IDBKeyData& primaryKey, const Vector<char>& value, uint32_t errorCode, const String& errorMessage)
+{
+    RefPtr<AsyncRequest> request = m_pendingDatabaseTasks.take(requestID);
+    ASSERT(request);
+
+    request->completeRequest(key, primaryKey, SharedBuffer::create(value.data(), value.size()), errorCode, errorMessage);
+}
+
 String UniqueIDBDatabase::absoluteDatabaseDirectory() const
 {
     ASSERT(isMainThread());
index 5de975d..58b97b6 100644 (file)
@@ -30,6 +30,7 @@
 
 #include "IDBIdentifier.h"
 #include "UniqueIDBDatabaseIdentifier.h"
+#include <WebCore/IDBDatabaseBackend.h>
 #include <WebCore/IndexedDB.h>
 #include <functional>
 #include <wtf/Deque.h>
@@ -39,6 +40,8 @@
 #include <wtf/text/WTFString.h>
 
 namespace WebCore {
+class SharedBuffer;
+
 struct IDBDatabaseMetadata;
 struct IDBKeyData;
 }
@@ -84,6 +87,10 @@ 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);
+
 private:
     UniqueIDBDatabase(const UniqueIDBDatabaseIdentifier&);
 
@@ -129,6 +136,9 @@ private:
     void deleteIndexInBackingStore(uint64_t requestID, const IDBIdentifier& transactionIdentifier, int64_t objectStoreID, int64_t indexID);
     void putRecordInBackingStore(uint64_t requestID, const IDBIdentifier& transactionIdentifier, const WebCore::IDBObjectStoreMetadata&, const WebCore::IDBKeyData&, const Vector<uint8_t>& value, int64_t putMode, const Vector<int64_t>& indexIDs, const Vector<Vector<WebCore::IDBKeyData>>& indexKeys);
     void getRecordFromBackingStore(uint64_t requestID, const IDBIdentifier& transactionIdentifier, const WebCore::IDBObjectStoreMetadata&, int64_t indexID, const WebCore::IDBKeyRangeData&, WebCore::IndexedDB::CursorType);
+    void openCursorInBackingStore(uint64_t requestID, const IDBIdentifier& transactionIdentifier, int64_t objectStoreID, int64_t indexID, WebCore::IndexedDB::CursorDirection, WebCore::IndexedDB::CursorType, WebCore::IDBDatabaseBackend::TaskType, const WebCore::IDBKeyRangeData&);
+    void advanceCursorInBackingStore(uint64_t requestID, const IDBIdentifier& cursorIdentifier, uint64_t count);
+    void iterateCursorInBackingStore(uint64_t requestID, const IDBIdentifier& cursorIdentifier, const WebCore::IDBKeyData&);
 
     void shutdownBackingStore();
 
@@ -144,6 +154,9 @@ 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 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 didShutdownBackingStore();
     void didCompleteBoolRequest(uint64_t requestID, bool success);
 
index e135447..8749328 100644 (file)
@@ -45,6 +45,13 @@ IDBIdentifier CrossThreadCopierBase<false, false, IDBIdentifier>::copy(const IDB
     return transactionIdentifier.isolatedCopy();
 }
 
+Vector<char> CrossThreadCopierBase<false, false, Vector<char>>::copy(const Vector<char>& vector)
+{
+    Vector<char> result;
+    result.appendVector(vector);
+    return result;
+}
+
 Vector<int64_t> CrossThreadCopierBase<false, false, Vector<int64_t>>::copy(const Vector<int64_t>& vector)
 {
     Vector<int64_t> result;
index fd40e14..7dc5e3d 100644 (file)
@@ -50,6 +50,10 @@ template<> struct CrossThreadCopierBase<false, false, WebKit::IDBIdentifier> {
     static WebKit::IDBIdentifier copy(const WebKit::IDBIdentifier&);
 };
 
+template<> struct CrossThreadCopierBase<false, false, Vector<char>> {
+    static Vector<char> copy(const Vector<char>&);
+};
+
 template<> struct CrossThreadCopierBase<false, false, Vector<int64_t>> {
     static Vector<int64_t> copy(const Vector<int64_t>&);
 };
index fe2d8cc..d006ce5 100644 (file)
@@ -420,8 +420,42 @@ void WebIDBServerConnection::didGetRecord(uint64_t requestID, const WebCore::IDB
     serverRequest->completeRequest(getResult, errorCode ? IDBDatabaseError::create(errorCode, errorMessage) : nullptr);
 }
 
-void WebIDBServerConnection::openCursor(IDBTransactionBackend&, const OpenCursorOperation&, std::function<void(int64_t, PassRefPtr<IDBDatabaseError>)> completionCallback)
+void WebIDBServerConnection::didOpenCursor(uint64_t requestID, int64_t cursorID, uint32_t errorCode, const String& errorMessage)
 {
+    LOG(IDB, "WebProcess didOpenCursor request ID %llu (error - %s)", requestID, errorMessage.utf8().data());
+
+    RefPtr<AsyncRequest> serverRequest = m_serverRequests.take(requestID);
+
+    if (!serverRequest)
+        return;
+
+    serverRequest->completeRequest(cursorID, 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)
+{
+    LOG(IDB, "WebProcess didAdvanceCursor request ID %llu (error - %s)", requestID, errorMessage.utf8().data());
+
+    RefPtr<AsyncRequest> serverRequest = m_serverRequests.take(requestID);
+
+    if (!serverRequest)
+        return;
+
+    RefPtr<SharedBuffer> value = SharedBuffer::create(valueData.data(), valueData.size());
+    serverRequest->completeRequest(key.maybeCreateIDBKey(), primaryKey.maybeCreateIDBKey(), value.release(), errorCode ? IDBDatabaseError::create(errorCode, errorMessage) : nullptr);
+}
+
+void WebIDBServerConnection::didIterateCursor(uint64_t requestID, WebCore::IDBKeyData& key, WebCore::IDBKeyData& primaryKey, const IPC::DataReference& valueData, uint32_t errorCode, const String& errorMessage)
+{
+    LOG(IDB, "WebProcess didIterateCursor request ID %llu (error - %s)", requestID, errorMessage.utf8().data());
+
+    RefPtr<AsyncRequest> serverRequest = m_serverRequests.take(requestID);
+
+    if (!serverRequest)
+        return;
+
+    RefPtr<SharedBuffer> value = SharedBuffer::create(valueData.data(), valueData.size());
+    serverRequest->completeRequest(key.maybeCreateIDBKey(), primaryKey.maybeCreateIDBKey(), value.release(), errorCode ? IDBDatabaseError::create(errorCode, errorMessage) : nullptr);
 }
 
 void WebIDBServerConnection::count(IDBTransactionBackend&, const CountOperation&, std::function<void(int64_t, PassRefPtr<IDBDatabaseError>)> completionCallback)
@@ -519,12 +553,55 @@ void WebIDBServerConnection::didChangeDatabaseVersion(uint64_t requestID, bool s
     serverRequest->completeRequest(success ? nullptr : IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Unknown error occured changing database version"));
 }
 
-void WebIDBServerConnection::cursorAdvance(IDBCursorBackend&, const CursorAdvanceOperation&, std::function<void(PassRefPtr<IDBKey>, PassRefPtr<IDBKey>, PassRefPtr<SharedBuffer>, PassRefPtr<IDBDatabaseError>)> completionCallback)
+void WebIDBServerConnection::openCursor(IDBTransactionBackend&, const OpenCursorOperation& operation, std::function<void(int64_t, PassRefPtr<IDBDatabaseError>)> completionCallback)
+{
+    RefPtr<AsyncRequest> serverRequest = AsyncRequestImpl<int64_t, PassRefPtr<IDBDatabaseError>>::create(completionCallback);
+
+    serverRequest->setAbortHandler([completionCallback]() {
+        completionCallback(0, IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Unknown error occured opening database cursor"));
+    });
+
+    uint64_t requestID = serverRequest->requestID();
+    ASSERT(!m_serverRequests.contains(requestID));
+    m_serverRequests.add(requestID, serverRequest.release());
+
+    LOG(IDB, "WebProcess openCursor request ID %llu", requestID);
+
+    send(Messages::DatabaseProcessIDBConnection::OpenCursor(requestID, operation.transactionID(), operation.objectStoreID(), operation.indexID(), static_cast<int64_t>(operation.direction()), static_cast<int64_t>(operation.cursorType()), static_cast<int64_t>(operation.taskType()), operation.keyRange()));
+}
+
+void WebIDBServerConnection::cursorAdvance(IDBCursorBackend&, const CursorAdvanceOperation& operation, std::function<void(PassRefPtr<IDBKey>, PassRefPtr<IDBKey>, PassRefPtr<SharedBuffer>, PassRefPtr<IDBDatabaseError>)> completionCallback)
 {
+    RefPtr<AsyncRequest> serverRequest = AsyncRequestImpl<PassRefPtr<IDBKey>, PassRefPtr<IDBKey>, PassRefPtr<SharedBuffer>, PassRefPtr<IDBDatabaseError>>::create(completionCallback);
+
+    serverRequest->setAbortHandler([completionCallback]() {
+        completionCallback(nullptr, nullptr, nullptr, IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Unknown error occured advancing database cursor"));
+    });
+
+    uint64_t requestID = serverRequest->requestID();
+    ASSERT(!m_serverRequests.contains(requestID));
+    m_serverRequests.add(requestID, serverRequest.release());
+
+    LOG(IDB, "WebProcess cursorAdvance request ID %llu", requestID);
+
+    send(Messages::DatabaseProcessIDBConnection::CursorAdvance(requestID, operation.cursorID(), operation.count()));
 }
 
-void WebIDBServerConnection::cursorIterate(IDBCursorBackend&, const CursorIterationOperation&, std::function<void(PassRefPtr<IDBKey>, PassRefPtr<IDBKey>, PassRefPtr<SharedBuffer>, PassRefPtr<IDBDatabaseError>)> completionCallback)
+void WebIDBServerConnection::cursorIterate(IDBCursorBackend&, const CursorIterationOperation& operation, std::function<void(PassRefPtr<IDBKey>, PassRefPtr<IDBKey>, PassRefPtr<SharedBuffer>, PassRefPtr<IDBDatabaseError>)> completionCallback)
 {
+    RefPtr<AsyncRequest> serverRequest = AsyncRequestImpl<PassRefPtr<IDBKey>, PassRefPtr<IDBKey>, PassRefPtr<SharedBuffer>, PassRefPtr<IDBDatabaseError>>::create(completionCallback);
+
+    serverRequest->setAbortHandler([completionCallback]() {
+        completionCallback(nullptr, nullptr, nullptr, IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Unknown error occured iterating database cursor"));
+    });
+
+    uint64_t requestID = serverRequest->requestID();
+    ASSERT(!m_serverRequests.contains(requestID));
+    m_serverRequests.add(requestID, serverRequest.release());
+
+    LOG(IDB, "WebProcess cursorIterate request ID %llu", requestID);
+
+    send(Messages::DatabaseProcessIDBConnection::CursorIterate(requestID, operation.cursorID(), operation.key()));
 }
 
 IPC::Connection* WebIDBServerConnection::messageSenderConnection()
index e42cb30..3b27a2b 100644 (file)
@@ -109,6 +109,9 @@ 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 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);
 
     uint64_t m_serverConnectionIdentifier;
 
index 8ccf08b..837e6b8 100644 (file)
@@ -39,6 +39,9 @@ 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)
+    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);
 }
 
 #endif // ENABLE(INDEXED_DATABASE) && ENABLE(DATABASE_PROCESS)