IDB: Index writing
authorbeidson@apple.com <beidson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 31 Jan 2014 15:55:28 +0000 (15:55 +0000)
committerbeidson@apple.com <beidson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 31 Jan 2014 15:55:28 +0000 (15:55 +0000)
<rdar://problem/15899973> and https://bugs.webkit.org/show_bug.cgi?id=127868

Reviewed by Anders Carlsson.

Source/WebCore:

* Modules/indexeddb/IDBDatabaseBackend.cpp:
(WebCore::IDBDatabaseBackend::openConnectionInternal): Remove outdated comment and ASSERT.

* Modules/indexeddb/IDBObjectStore.cpp:
(WebCore::IDBObjectStore::createIndex): Conditionalize a block of code that is LevelDB-only.

Remove getColumnBlob().  Nobody used it, and it was dangerous because it reset the statement:
* platform/sql/SQLiteStatement.cpp:
* platform/sql/SQLiteStatement.h:
* WebCore.exp.in:

Source/WebKit2:

* DatabaseProcess/IndexedDB/UniqueIDBDatabase.cpp:
(WebKit::UniqueIDBDatabase::putRecordInBackingStore): Handle writing index records, as well.

* DatabaseProcess/IndexedDB/UniqueIDBDatabaseBackingStore.h:
* DatabaseProcess/IndexedDB/sqlite/UniqueIDBDatabaseBackingStoreSQLite.cpp:
(WebKit::UniqueIDBDatabaseBackingStoreSQLite::createAndPopulateInitialMetadata): Create a table
  for index records
(WebKit::UniqueIDBDatabaseBackingStoreSQLite::extractExistingMetadata): Extract IDBIndexMetadata
(WebKit::UniqueIDBDatabaseBackingStoreSQLite::deleteObjectStore):
(WebKit::UniqueIDBDatabaseBackingStoreSQLite::deleteIndex):
(WebKit::UniqueIDBDatabaseBackingStoreSQLite::putIndexRecord): Store in the IndexRecords table.
* DatabaseProcess/IndexedDB/sqlite/UniqueIDBDatabaseBackingStoreSQLite.h:

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

Source/WebCore/ChangeLog
Source/WebCore/Modules/indexeddb/IDBDatabaseBackend.cpp
Source/WebCore/Modules/indexeddb/IDBObjectStore.cpp
Source/WebCore/WebCore.exp.in
Source/WebCore/platform/sql/SQLiteStatement.cpp
Source/WebCore/platform/sql/SQLiteStatement.h
Source/WebKit2/ChangeLog
Source/WebKit2/DatabaseProcess/IndexedDB/UniqueIDBDatabase.cpp
Source/WebKit2/DatabaseProcess/IndexedDB/UniqueIDBDatabaseBackingStore.h
Source/WebKit2/DatabaseProcess/IndexedDB/sqlite/UniqueIDBDatabaseBackingStoreSQLite.cpp
Source/WebKit2/DatabaseProcess/IndexedDB/sqlite/UniqueIDBDatabaseBackingStoreSQLite.h

index e91326e..3558d45 100644 (file)
@@ -1,3 +1,21 @@
+2014-01-31  Brady Eidson  <beidson@apple.com>
+
+        IDB: Index writing
+        <rdar://problem/15899973> and https://bugs.webkit.org/show_bug.cgi?id=127868
+
+        Reviewed by Anders Carlsson.
+
+        * Modules/indexeddb/IDBDatabaseBackend.cpp:
+        (WebCore::IDBDatabaseBackend::openConnectionInternal): Remove outdated comment and ASSERT.
+
+        * Modules/indexeddb/IDBObjectStore.cpp:
+        (WebCore::IDBObjectStore::createIndex): Conditionalize a block of code that is LevelDB-only.
+
+        Remove getColumnBlob().  Nobody used it, and it was dangerous because it reset the statement:
+        * platform/sql/SQLiteStatement.cpp:
+        * platform/sql/SQLiteStatement.h:
+        * WebCore.exp.in:
+
 2014-01-30  László Langó  <lango@inf.u-szeged.hu>
 
         [CSS Grid Layout] Do log(n) search in the named line vectors when positioning named line spans.
index d3da2db..13ed9e5 100644 (file)
@@ -467,9 +467,6 @@ void IDBDatabaseBackend::openConnectionInternal(PassRefPtr<IDBCallbacks> prpCall
     bool isNewDatabase = m_metadata.version == IDBDatabaseMetadata::NoIntVersion;
 
     if (version == IDBDatabaseMetadata::DefaultIntVersion) {
-        // FIXME: this comments was related to Chromium code. It may be incorrect
-        // For unit tests only - skip upgrade steps. Calling from script with DefaultIntVersion throws exception.
-        ASSERT(isNewDatabase);
         m_databaseCallbacksSet.add(databaseCallbacks);
         callbacks->onSuccess(this, this->metadata());
         return;
index d42896f..d3ba5e8 100644 (file)
@@ -415,6 +415,7 @@ PassRefPtr<IDBIndex> IDBObjectStore::createIndex(ScriptExecutionContext* context
     if (ec)
         return 0;
 
+#if USE(LEVELDB)
     RefPtr<IDBRequest> indexRequest = openCursor(context, static_cast<IDBKeyRange*>(0), IDBCursor::directionNext(), IDBDatabaseBackend::PreemptiveTask, ec);
     ASSERT(!ec);
     if (ec)
@@ -424,6 +425,9 @@ PassRefPtr<IDBIndex> IDBObjectStore::createIndex(ScriptExecutionContext* context
     // This is kept alive by being the success handler of the request, which is in turn kept alive by the owning transaction.
     RefPtr<IndexPopulator> indexPopulator = IndexPopulator::create(backendDB(), m_transaction->id(), id(), metadata);
     indexRequest->setOnsuccess(indexPopulator);
+#else
+    ASSERT_UNUSED(context, context);
+#endif
 
     return index.release();
 }
index cfe4231..d408da4 100644 (file)
@@ -82,7 +82,6 @@ __ZN7WebCore10MouseEvent6createERKN3WTF12AtomicStringEbbdNS1_10PassRefPtrINS_9DO
 __ZN7WebCore10Pasteboard14writePlainTextERKN3WTF6StringENS0_18SmartReplaceOptionE
 __ZN7WebCore10RenderView10compositorEv
 __ZN7WebCore10RenderView7hitTestERKNS_14HitTestRequestERNS_13HitTestResultE
-__ZN7WebCore15SQLiteStatement13getColumnBlobEiRi
 __ZN7WebCore15SQLiteStatement14getColumnInt64Ei
 __ZN7WebCore15SQLiteStatement21getColumnBlobAsVectorEiRN3WTF6VectorIcLm0ENS1_15CrashOnOverflowEEE
 __ZN7WebCore10ScrollView16setParentVisibleEb
index 3486b2b..526c023 100644 (file)
@@ -428,34 +428,6 @@ void SQLiteStatement::getColumnBlobAsVector(int col, Vector<char>& result)
         result[i] = (static_cast<const unsigned char*>(blob))[i];
 }
 
-const void* SQLiteStatement::getColumnBlob(int col, int& size)
-{
-    ASSERT(col >= 0);
-
-    size = 0;
-
-    if (finalize() != SQLITE_OK)
-        LOG(SQLDatabase, "Finalize failed");
-    if (prepare() != SQLITE_OK) {
-        LOG(SQLDatabase, "Prepare failed");
-        return 0;
-    }
-    if (step() != SQLITE_ROW) {
-        LOG(SQLDatabase, "Step wasn't a row");
-        return 0;
-    }
-
-    if (columnCount() <= col)
-        return 0;
-        
-    const void* blob = sqlite3_column_blob(m_statement, col);
-    if (!blob)
-        return 0;
-
-    size = sqlite3_column_bytes(m_statement, col);
-    return blob;
-}
-
 bool SQLiteStatement::returnTextResults(int col, Vector<String>& v)
 {
     ASSERT(col >= 0);
index 8a9e4ac..0feb57c 100644 (file)
@@ -81,7 +81,6 @@ public:
     double getColumnDouble(int col);
     int getColumnInt(int col);
     int64_t getColumnInt64(int col);
-    const void* getColumnBlob(int col, int& size);
     String getColumnBlobAsString(int col);
     void getColumnBlobAsVector(int col, Vector<char>&);
 
index 6e5531c..32bba6d 100644 (file)
@@ -1,3 +1,23 @@
+2014-01-31  Brady Eidson  <beidson@apple.com>
+
+        IDB: Index writing
+        <rdar://problem/15899973> and https://bugs.webkit.org/show_bug.cgi?id=127868
+
+        Reviewed by Anders Carlsson.
+
+        * DatabaseProcess/IndexedDB/UniqueIDBDatabase.cpp:
+        (WebKit::UniqueIDBDatabase::putRecordInBackingStore): Handle writing index records, as well.
+
+        * DatabaseProcess/IndexedDB/UniqueIDBDatabaseBackingStore.h:
+        * DatabaseProcess/IndexedDB/sqlite/UniqueIDBDatabaseBackingStoreSQLite.cpp:
+        (WebKit::UniqueIDBDatabaseBackingStoreSQLite::createAndPopulateInitialMetadata): Create a table
+          for index records
+        (WebKit::UniqueIDBDatabaseBackingStoreSQLite::extractExistingMetadata): Extract IDBIndexMetadata
+        (WebKit::UniqueIDBDatabaseBackingStoreSQLite::deleteObjectStore):
+        (WebKit::UniqueIDBDatabaseBackingStoreSQLite::deleteIndex):
+        (WebKit::UniqueIDBDatabaseBackingStoreSQLite::putIndexRecord): Store in the IndexRecords table.
+        * DatabaseProcess/IndexedDB/sqlite/UniqueIDBDatabaseBackingStoreSQLite.h:
+
 2014-01-30  Jinwoo Song  <jinwoo7.song@samsung.com>
 
         [EFL][WK2] Unreviewed EFL WebKit2 build fix after r163116.
index 3f91094..c49574e 100644 (file)
@@ -800,14 +800,20 @@ void UniqueIDBDatabase::putRecordInBackingStore(uint64_t requestID, const IDBIde
         }
     }
 
-    // FIXME: The LevelDB port performs "makeIndexWriters" here. Necessary?
-
     if (!m_backingStore->putRecord(transaction, objectStoreMetadata.id, *key, value.data(), value.size())) {
         postMainThreadTask(createAsyncTask(*this, &UniqueIDBDatabase::didPutRecordInBackingStore, requestID, IDBKeyData(), IDBDatabaseException::UnknownError, ASCIILiteral("Internal backing store error putting a record")));
         return;
     }
 
-    // FIXME: The LevelDB port updates index keys here. Necessary?
+    ASSERT(indexIDs.size() == indexKeys.size());
+    for (size_t i = 0; i < indexIDs.size(); ++i) {
+        for (size_t j = 0; j < indexKeys[i].size(); ++j) {
+            if (!m_backingStore->putIndexRecord(transaction, objectStoreMetadata.id, indexIDs[i], keyData, indexKeys[i][j])) {
+                postMainThreadTask(createAsyncTask(*this, &UniqueIDBDatabase::didPutRecordInBackingStore, requestID, IDBKeyData(), IDBDatabaseException::UnknownError, ASCIILiteral("Internal backing store error writing index key")));
+                return;
+            }
+        }
+    }
 
     if (putMode != IDBDatabaseBackend::CursorUpdate && objectStoreMetadata.autoIncrement && key->type() == IDBKey::NumberType) {
         if (!m_backingStore->updateKeyGeneratorNumber(transaction, objectStoreMetadata.id, keyNumber, keyWasGenerated)) {
index 631e1a8..a5c9af9 100644 (file)
@@ -68,6 +68,7 @@ public:
 
     virtual bool keyExistsInObjectStore(const IDBIdentifier& transactionIdentifier, int64_t objectStoreID, const WebCore::IDBKey&, bool& keyExists) = 0;
     virtual bool putRecord(const IDBIdentifier& transactionIdentifier, int64_t objectStoreID, const WebCore::IDBKey&, const uint8_t* valueBuffer, size_t valueSize) = 0;
+    virtual bool putIndexRecord(const IDBIdentifier& transactionIdentifier, int64_t objectStoreID, int64_t indexID, const WebCore::IDBKeyData&, const WebCore::IDBKeyData& indexKey) = 0;
 
     virtual bool getKeyRecordFromObjectStore(const IDBIdentifier& transactionIdentifier, int64_t objectStoreID, const WebCore::IDBKey&, RefPtr<WebCore::SharedBuffer>& result) = 0;
     virtual bool getKeyRangeRecordFromObjectStore(const IDBIdentifier& transactionIdentifier, int64_t objectStoreID, const WebCore::IDBKeyRange&, RefPtr<WebCore::SharedBuffer>& result, RefPtr<WebCore::IDBKey>& resultKey) = 0;
index 673f9b2..b640044 100644 (file)
@@ -99,6 +99,12 @@ std::unique_ptr<IDBDatabaseMetadata> UniqueIDBDatabaseBackingStoreSQLite::create
         return nullptr;
     }
 
+    if (!m_sqliteDB->executeCommand("CREATE TABLE IndexRecords (indexID INTEGER NOT NULL ON CONFLICT FAIL, objectStoreID INTEGER NOT NULL ON CONFLICT FAIL, key TEXT COLLATE IDBKEY NOT NULL ON CONFLICT FAIL UNIQUE ON CONFLICT REPLACE, value NOT NULL ON CONFLICT FAIL);")) {
+        LOG_ERROR("Could not create Records table in database (%i) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
+        m_sqliteDB = nullptr;
+        return nullptr;
+    }
+
     if (!m_sqliteDB->executeCommand("CREATE TABLE KeyGenerators (objectStoreID INTEGER NOT NULL ON CONFLICT FAIL UNIQUE ON CONFLICT REPLACE, currentKey INTEGER NOT NULL ON CONFLICT FAIL);")) {
         LOG_ERROR("Could not create KeyGenerators table in database (%i) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
         m_sqliteDB = nullptr;
@@ -202,11 +208,10 @@ std::unique_ptr<IDBDatabaseMetadata> UniqueIDBDatabaseBackingStoreSQLite::extrac
             osMetadata.id = sql.getColumnInt64(0);
             osMetadata.name = sql.getColumnText(1);
 
-            int keyPathSize;
-            const uint8_t* keyPathBuffer = static_cast<const uint8_t*>(sql.getColumnBlob(2, keyPathSize));
-
+            Vector<char> keyPathBuffer;
+            sql.getColumnBlobAsVector(2, keyPathBuffer);
 
-            if (!deserializeIDBKeyPath(keyPathBuffer, keyPathSize, osMetadata.keyPath)) {
+            if (!deserializeIDBKeyPath(reinterpret_cast<const uint8_t*>(keyPathBuffer.data()), keyPathBuffer.size(), osMetadata.keyPath)) {
                 LOG_ERROR("Unable to extract key path metadata from database");
                 return nullptr;
             }
@@ -224,7 +229,46 @@ std::unique_ptr<IDBDatabaseMetadata> UniqueIDBDatabaseBackingStoreSQLite::extrac
         }
     }
 
-    // FIXME: Once we save indexes we need to extract their metadata, also.
+    {
+        SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("SELECT id, name, objectStoreID, keyPath, isUnique, multiEntry FROM IndexInfo;"));
+        if (sql.prepare() != SQLResultOk)
+            return nullptr;
+
+        int result = sql.step();
+        while (result == SQLResultRow) {
+            IDBIndexMetadata indexMetadata;
+
+            indexMetadata.id = sql.getColumnInt64(0);
+            indexMetadata.name = sql.getColumnText(1);
+            int64_t objectStoreID = sql.getColumnInt64(2);
+
+            Vector<char> keyPathBuffer;
+            sql.getColumnBlobAsVector(3, keyPathBuffer);
+
+            if (!deserializeIDBKeyPath(reinterpret_cast<const uint8_t*>(keyPathBuffer.data()), keyPathBuffer.size(), indexMetadata.keyPath)) {
+                LOG_ERROR("Unable to extract key path metadata from database");
+                return nullptr;
+            }
+
+            indexMetadata.unique = sql.getColumnInt(4);
+            indexMetadata.multiEntry = sql.getColumnInt(5);
+
+            auto objectStoreMetadataIt = metadata->objectStores.find(objectStoreID);
+            if (objectStoreMetadataIt == metadata->objectStores.end()) {
+                LOG_ERROR("Found index referring to a non-existant object store");
+                return nullptr;
+            }
+
+            objectStoreMetadataIt->value.indexes.set(indexMetadata.id, indexMetadata);
+
+            result = sql.step();
+        }
+
+        if (result != SQLResultDone) {
+            LOG_ERROR("Error fetching index metadata from database on disk");
+            return nullptr;
+        }
+    }
 
     return metadata;
 }
@@ -452,33 +496,37 @@ bool UniqueIDBDatabaseBackingStoreSQLite::deleteObjectStore(const IDBIdentifier&
         }
     }
 
-    // Delete all associated Index records
+    // Delete all associated records
     {
-        Vector<int64_t> indexIDs;
-        SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("SELECT id FROM IndexInfo WHERE objectStoreID = ?;"));
+        SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("DELETE FROM Records WHERE objectStoreID = ?;"));
         if (sql.prepare() != SQLResultOk
-            || sql.bindInt64(1, objectStoreID) != SQLResultOk) {
-            LOG_ERROR("Error fetching index ID records for object store id %lli from IndexInfo table (%i) - %s", objectStoreID, m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
+            || sql.bindInt64(1, objectStoreID) != SQLResultOk
+            || sql.step() != SQLResultDone) {
+            LOG_ERROR("Could not delete records for object store %lli (%i) - %s", objectStoreID, m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
             return false;
         }
+    }
 
-        int resultCode;
-        while ((resultCode = sql.step()) == SQLResultRow)
-            indexIDs.append(sql.getColumnInt64(0));
-
-        if (resultCode != SQLResultDone) {
-            LOG_ERROR("Error fetching index ID records for object store id %lli from IndexInfo table (%i) - %s", objectStoreID, m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
+    // Delete all associated Indexes
+    {
+        SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("DELETE FROM IndexInfo WHERE objectStoreID = ?;"));
+        if (sql.prepare() != SQLResultOk
+            || sql.bindInt64(1, objectStoreID) != SQLResultOk
+            || sql.step() != SQLResultDone) {
+            LOG_ERROR("Could not delete index from IndexInfo table (%i) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
             return false;
         }
-
-        for (auto indexID : indexIDs) {
-            if (!deleteIndex(transactionIdentifier, objectStoreID, indexID))
-                return false;
-        }
     }
 
+    // Delete all associated Index records
     {
-        // FIXME: Execute SQL here to drop all records related to this object store.
+        SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("DELETE FROM IndexRecords WHERE objectStoreID = ?;"));
+        if (sql.prepare() != SQLResultOk
+            || sql.bindInt64(1, objectStoreID) != SQLResultOk
+            || sql.step() != SQLResultDone) {
+            LOG_ERROR("Could not delete index records(%i) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
+            return false;
+        }
     }
 
     return true;
@@ -579,7 +627,17 @@ bool UniqueIDBDatabaseBackingStoreSQLite::deleteIndex(const IDBIdentifier& trans
         }
     }
 
-    // FIXME (<rdar://problem/15905293>) - Once we store records against indexes, delete them here.
+    {
+        SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("DELETE FROM IndexRecords WHERE indexID = ? AND objectStoreID = ?;"));
+        if (sql.prepare() != SQLResultOk
+            || sql.bindInt64(1, indexID) != SQLResultOk
+            || sql.bindInt64(2, objectStoreID) != SQLResultOk
+            || sql.step() != SQLResultDone) {
+            LOG_ERROR("Could not delete index records for index id %lli from IndexRecords table (%i) - %s", indexID, m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
+            return false;
+        }
+    }
+
     return true;
 }
 
@@ -698,6 +756,49 @@ bool UniqueIDBDatabaseBackingStoreSQLite::putRecord(const IDBIdentifier& transac
     return true;
 }
 
+bool UniqueIDBDatabaseBackingStoreSQLite::putIndexRecord(const IDBIdentifier& transactionIdentifier, int64_t objectStoreID, int64_t indexID, const IDBKeyData& keyValue, const IDBKeyData& indexKey)
+{
+    ASSERT(!isMainThread());
+    ASSERT(m_sqliteDB);
+    ASSERT(m_sqliteDB->isOpen());
+
+    SQLiteIDBTransaction* transaction = m_transactions.get(transactionIdentifier);
+    if (!transaction || !transaction->inProgress()) {
+        LOG_ERROR("Attempt to put index record into database without an established, in-progress transaction");
+        return false;
+    }
+    if (transaction->mode() == IndexedDB::TransactionMode::ReadOnly) {
+        LOG_ERROR("Attempt to put index record into database during read-only transaction");
+        return false;
+    }
+
+    RefPtr<SharedBuffer> indexKeyBuffer = serializeIDBKeyData(indexKey);
+    if (!indexKeyBuffer) {
+        LOG_ERROR("Unable to serialize index key to be stored in the database");
+        return false;
+    }
+
+    RefPtr<SharedBuffer> valueBuffer = serializeIDBKeyData(keyValue);
+    if (!valueBuffer) {
+        LOG_ERROR("Unable to serialize the value to be stored in the database");
+        return false;
+    }
+    {
+        SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("INSERT INTO IndexRecords VALUES (?, ?, CAST(? AS TEXT), ?);"));
+        if (sql.prepare() != SQLResultOk
+            || sql.bindInt64(1, indexID) != SQLResultOk
+            || sql.bindInt64(2, objectStoreID) != SQLResultOk
+            || sql.bindBlob(3, indexKeyBuffer->data(), indexKeyBuffer->size()) != SQLResultOk
+            || sql.bindBlob(4, valueBuffer->data(), valueBuffer->size()) != SQLResultOk
+            || sql.step() != SQLResultDone) {
+            LOG_ERROR("Could not put index record for index %lli in object store %lli in Records table (%i) - %s", indexID, objectStoreID, m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
+            return false;
+        }
+    }
+
+    return true;
+}
+
 bool UniqueIDBDatabaseBackingStoreSQLite::getKeyRecordFromObjectStore(const IDBIdentifier& transactionIdentifier, int64_t objectStoreID, const IDBKey& key, RefPtr<SharedBuffer>& result)
 {
     ASSERT(!isMainThread());
index 2ffbe48..742e0a7 100644 (file)
@@ -73,6 +73,8 @@ public:
 
     virtual bool keyExistsInObjectStore(const IDBIdentifier& transactionIdentifier, int64_t objectStoreID, const WebCore::IDBKey&, bool& keyExists) override;
     virtual bool putRecord(const IDBIdentifier& transactionIdentifier, int64_t objectStoreID, const WebCore::IDBKey&, const uint8_t* valueBuffer, size_t valueSize) override;
+    virtual bool putIndexRecord(const IDBIdentifier& transactionIdentifier, int64_t objectStoreID, int64_t indexID, const WebCore::IDBKeyData& keyValue, const WebCore::IDBKeyData& indexKey) override;
+
 
     virtual bool getKeyRecordFromObjectStore(const IDBIdentifier& transactionIdentifier, int64_t objectStoreID, const WebCore::IDBKey&, RefPtr<WebCore::SharedBuffer>& result) override;
     virtual bool getKeyRangeRecordFromObjectStore(const IDBIdentifier& transactionIdentifier, int64_t objectStoreID, const WebCore::IDBKeyRange&, RefPtr<WebCore::SharedBuffer>& result, RefPtr<WebCore::IDBKey>& resultKey) override;