IDB: Index cursors use wrong deserialization for the retrieved value
authorbeidson@apple.com <beidson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 1 Feb 2014 05:01:15 +0000 (05:01 +0000)
committerbeidson@apple.com <beidson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 1 Feb 2014 05:01:15 +0000 (05:01 +0000)
https://bugs.webkit.org/show_bug.cgi?id=128035

Reviewed by Dan Bernstein.

Source/WebCore:

For the cursor operations, add an IDBKey value result in the callbacks.
If an already deserialized IDBKey value exists it will be preferred over the serialized buffer.

Change some of the onSuccess() callback formats:
* Modules/indexeddb/IDBCallbacks.h:
* Modules/indexeddb/IDBRequest.cpp:
(WebCore::IDBRequest::onSuccess): Selectively choose between the IDBKey or the SharedBuffer value
  when choosed what to convert to the ScriptValue.
* Modules/indexeddb/IDBRequest.h:

Let the IDBCursorBackend hold both a value buffer and a value key:
* Modules/indexeddb/IDBCursorBackend.cpp:
(WebCore::IDBCursorBackend::updateCursorData):
(WebCore::IDBCursorBackend::clear):
* Modules/indexeddb/IDBCursorBackend.h:
(WebCore::IDBCursorBackend::valueBuffer):
(WebCore::IDBCursorBackend::valueKey):

* Modules/indexeddb/IDBCursorBackendOperations.cpp:
(WebCore::CursorAdvanceOperation::perform):
(WebCore::CursorIterationOperation::perform):

* Modules/indexeddb/IDBTransactionBackendOperations.cpp:
(WebCore::OpenCursorOperation::perform):

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

Add IDBKey/IDBKeyData debug logging utilities:
* Modules/indexeddb/IDBKey.cpp:
(WebCore::IDBKey::loggingString):
* Modules/indexeddb/IDBKey.h:
* Modules/indexeddb/IDBKeyData.cpp:
(WebCore::IDBKeyData::loggingString):
* Modules/indexeddb/IDBKeyData.h:

* WebCore.exp.in:

Source/WebKit2:

Most of this is updating everything related to the cursor operation callbacks
to support returning an IDBKey value in addition to a SharedBuffer value.

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

* 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:

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

* DatabaseProcess/IndexedDB/sqlite/SQLiteIDBCursor.cpp:
(WebKit::SQLiteIDBCursor::advance):
* DatabaseProcess/IndexedDB/sqlite/SQLiteIDBCursor.h:
(WebKit::SQLiteIDBCursor::currentValueBuffer):
(WebKit::SQLiteIDBCursor::currentValueKey):

* 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:

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

28 files changed:
Source/WebCore/ChangeLog
Source/WebCore/Modules/indexeddb/IDBCallbacks.h
Source/WebCore/Modules/indexeddb/IDBCursorBackend.cpp
Source/WebCore/Modules/indexeddb/IDBCursorBackend.h
Source/WebCore/Modules/indexeddb/IDBCursorBackendOperations.cpp
Source/WebCore/Modules/indexeddb/IDBKey.cpp
Source/WebCore/Modules/indexeddb/IDBKey.h
Source/WebCore/Modules/indexeddb/IDBKeyData.cpp
Source/WebCore/Modules/indexeddb/IDBKeyData.h
Source/WebCore/Modules/indexeddb/IDBRequest.cpp
Source/WebCore/Modules/indexeddb/IDBRequest.h
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/WebCore/WebCore.exp.in
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/SQLiteIDBCursor.h
Source/WebKit2/DatabaseProcess/IndexedDB/sqlite/UniqueIDBDatabaseBackingStoreSQLite.cpp
Source/WebKit2/DatabaseProcess/IndexedDB/sqlite/UniqueIDBDatabaseBackingStoreSQLite.h
Source/WebKit2/WebProcess/Databases/IndexedDB/WebIDBServerConnection.cpp
Source/WebKit2/WebProcess/Databases/IndexedDB/WebIDBServerConnection.h
Source/WebKit2/WebProcess/Databases/IndexedDB/WebIDBServerConnection.messages.in

index dfba325..48070fd 100644 (file)
@@ -1,3 +1,52 @@
+2014-01-31  Brady Eidson  <beidson@apple.com>
+
+        IDB: Index cursors use wrong deserialization for the retrieved value
+        https://bugs.webkit.org/show_bug.cgi?id=128035
+
+        Reviewed by Dan Bernstein.
+
+        For the cursor operations, add an IDBKey value result in the callbacks.
+        If an already deserialized IDBKey value exists it will be preferred over the serialized buffer.
+
+        Change some of the onSuccess() callback formats:
+        * Modules/indexeddb/IDBCallbacks.h:
+        * Modules/indexeddb/IDBRequest.cpp:
+        (WebCore::IDBRequest::onSuccess): Selectively choose between the IDBKey or the SharedBuffer value
+          when choosed what to convert to the ScriptValue.
+        * Modules/indexeddb/IDBRequest.h:
+
+        Let the IDBCursorBackend hold both a value buffer and a value key:
+        * Modules/indexeddb/IDBCursorBackend.cpp:
+        (WebCore::IDBCursorBackend::updateCursorData):
+        (WebCore::IDBCursorBackend::clear):
+        * Modules/indexeddb/IDBCursorBackend.h:
+        (WebCore::IDBCursorBackend::valueBuffer):
+        (WebCore::IDBCursorBackend::valueKey):
+
+        * Modules/indexeddb/IDBCursorBackendOperations.cpp:
+        (WebCore::CursorAdvanceOperation::perform):
+        (WebCore::CursorIterationOperation::perform):
+
+        * Modules/indexeddb/IDBTransactionBackendOperations.cpp:
+        (WebCore::OpenCursorOperation::perform):
+
+        * Modules/indexeddb/IDBServerConnection.h:
+        * Modules/indexeddb/leveldb/IDBServerConnectionLevelDB.cpp:
+        (WebCore::IDBServerConnectionLevelDB::openCursor):
+        (WebCore::IDBServerConnectionLevelDB::cursorAdvance):
+        (WebCore::IDBServerConnectionLevelDB::cursorIterate):
+        * Modules/indexeddb/leveldb/IDBServerConnectionLevelDB.h:
+
+        Add IDBKey/IDBKeyData debug logging utilities:
+        * Modules/indexeddb/IDBKey.cpp:
+        (WebCore::IDBKey::loggingString):
+        * Modules/indexeddb/IDBKey.h:
+        * Modules/indexeddb/IDBKeyData.cpp:
+        (WebCore::IDBKeyData::loggingString):
+        * Modules/indexeddb/IDBKeyData.h:
+
+        * WebCore.exp.in:
+
 2014-01-31  Ryosuke Niwa  <rniwa@webkit.org>
 
         Debug build fix after r163232. Call hasEditableStyle() instead of isContentEditable() which
index 15382bc..26a22db 100644 (file)
@@ -52,7 +52,7 @@ public:
     // From IDBFactory.webkitGetDatabaseNames()
     virtual void onSuccess(PassRefPtr<DOMStringList>) = 0;
     // From IDBObjectStore/IDBIndex.openCursor(), IDBIndex.openKeyCursor()
-    virtual void onSuccess(PassRefPtr<IDBCursorBackend>, PassRefPtr<IDBKey>, PassRefPtr<IDBKey> primaryKey, PassRefPtr<SharedBuffer>) = 0;
+    virtual void onSuccess(PassRefPtr<IDBCursorBackend>) = 0;
     // From IDBObjectStore.add()/put(), IDBIndex.getKey()
     virtual void onSuccess(PassRefPtr<IDBKey>) = 0;
     // From IDBObjectStore/IDBIndex.get()/count(), and various methods that yield null/undefined.
@@ -67,6 +67,8 @@ public:
 
     // From IDBCursor.advance()/continue()
     virtual void onSuccess(PassRefPtr<IDBKey>, PassRefPtr<IDBKey> primaryKey, PassRefPtr<SharedBuffer>) = 0;
+    virtual void onSuccess(PassRefPtr<IDBKey>, PassRefPtr<IDBKey> primaryKey, PassRefPtr<SharedBuffer>, PassRefPtr<IDBKey> valueKey) = 0;
+
     // From IDBCursor.advance()/continue()
     virtual void onSuccessWithPrefetch(const Vector<RefPtr<IDBKey>>& keys, const Vector<RefPtr<IDBKey>>& primaryKeys, const Vector<RefPtr<SharedBuffer>>& values) = 0;
     // From IDBFactory.open()/deleteDatabase()
index 7bb600b..7f9618a 100644 (file)
@@ -89,19 +89,21 @@ void IDBCursorBackend::close()
     m_savedCursorID = 0;
 }
 
-void IDBCursorBackend::updateCursorData(IDBKey* key, IDBKey* primaryKey, SharedBuffer* value)
+void IDBCursorBackend::updateCursorData(IDBKey* key, IDBKey* primaryKey, SharedBuffer* valueBuffer, IDBKey* valueKey)
 {
     m_currentKey = key;
     m_currentPrimaryKey = primaryKey;
-    m_currentValue = value;
+    m_currentValueBuffer = valueBuffer;
+    m_currentValueKey = valueKey;
 }
 
 void IDBCursorBackend::clear()
 {
     m_cursorID = 0;
-    m_currentKey = 0;
-    m_currentPrimaryKey = 0;
-    m_currentValue = 0;
+    m_currentKey = nullptr;
+    m_currentPrimaryKey = nullptr;
+    m_currentValueBuffer = nullptr;
+    m_currentValueKey = nullptr;
 }
 
 } // namespace WebCore
index 3ee5b94..7e00546 100644 (file)
@@ -59,8 +59,9 @@ public:
 
     IDBKey* key() const { return m_currentKey.get(); }
     IDBKey* primaryKey() const { return m_currentPrimaryKey.get(); }
-    SharedBuffer* value() const { return (m_cursorType == IndexedDB::CursorType::KeyOnly) ? 0 : m_currentValue.get(); }
-    void updateCursorData(IDBKey*, IDBKey* primaryKey, SharedBuffer* value);
+    SharedBuffer* valueBuffer() const { return (m_cursorType == IndexedDB::CursorType::KeyOnly) ? nullptr : m_currentValueBuffer.get(); }
+    IDBKey* valueKey() const { return (m_cursorType == IndexedDB::CursorType::KeyOnly) ? nullptr : m_currentValueKey.get(); }
+    void updateCursorData(IDBKey*, IDBKey* primaryKey, SharedBuffer* valueBuffer, IDBKey* valueKey);
 
     void close();
 
@@ -86,7 +87,8 @@ private:
 
     RefPtr<IDBKey> m_currentKey;
     RefPtr<IDBKey> m_currentPrimaryKey;
-    RefPtr<SharedBuffer> m_currentValue;
+    RefPtr<SharedBuffer> m_currentValueBuffer;
+    RefPtr<IDBKey> m_currentValueKey;
 
     bool m_closed;
 };
index 9860745..53f7869 100644 (file)
@@ -40,15 +40,15 @@ void CursorAdvanceOperation::perform(std::function<void()> completionCallback)
     LOG(StorageAPI, "CursorAdvanceOperation");
 
     RefPtr<CursorAdvanceOperation> operation(this);
-    auto callback = [this, operation, completionCallback](PassRefPtr<IDBKey> key, PassRefPtr<IDBKey> primaryKey, PassRefPtr<SharedBuffer> value, PassRefPtr<IDBDatabaseError> error) {
+    auto callback = [this, operation, completionCallback](PassRefPtr<IDBKey> key, PassRefPtr<IDBKey> primaryKey, PassRefPtr<SharedBuffer> valueBuffer, PassRefPtr<IDBKey> valueKey, PassRefPtr<IDBDatabaseError> error) {
         if (error) {
             m_cursor->clear();
             // FIXME: The LevelDB backend calls onSuccess even on failure.
             // This will probably have to change soon (for sanity) and will probably break LevelDB
             m_callbacks->onSuccess(static_cast<SharedBuffer*>(0));
         } else {
-            m_cursor->updateCursorData(key.get(), primaryKey.get(), value.get());
-            m_callbacks->onSuccess(key, primaryKey, value);
+            m_cursor->updateCursorData(key.get(), primaryKey.get(), valueBuffer.get(), valueKey.get());
+            m_callbacks->onSuccess(key, primaryKey, valueBuffer, valueKey);
         }
 
         // FIXME: Cursor operations should be able to pass along an error instead of success
@@ -63,15 +63,15 @@ void CursorIterationOperation::perform(std::function<void()> completionCallback)
     LOG(StorageAPI, "CursorIterationOperation");
 
     RefPtr<CursorIterationOperation> operation(this);
-    auto callback = [this, operation, completionCallback](PassRefPtr<IDBKey> key, PassRefPtr<IDBKey> primaryKey, PassRefPtr<SharedBuffer> value, PassRefPtr<IDBDatabaseError> error) {
+    auto callback = [this, operation, completionCallback](PassRefPtr<IDBKey> key, PassRefPtr<IDBKey> primaryKey, PassRefPtr<SharedBuffer> valueBuffer, PassRefPtr<IDBKey> valueKey, PassRefPtr<IDBDatabaseError> error) {
         if (error) {
             m_cursor->clear();
             // FIXME: The LevelDB backend calls onSuccess even on failure.
             // This will probably have to change soon (for sanity) and will probably break LevelDB
             m_callbacks->onSuccess(static_cast<SharedBuffer*>(0));
         } else {
-            m_cursor->updateCursorData(key.get(), primaryKey.get(), value.get());
-            m_callbacks->onSuccess(key, primaryKey, value);
+            m_cursor->updateCursorData(key.get(), primaryKey.get(), valueBuffer.get(), valueKey.get());
+            m_callbacks->onSuccess(key, primaryKey, valueBuffer, valueKey);
         }
 
         // FIXME: Cursor operations should be able to pass along an error instead of success
index 5196dec..3d2f92c 100644 (file)
@@ -98,6 +98,13 @@ bool IDBKey::isEqual(const IDBKey* other) const
     return !compare(other);
 }
 
+#ifndef NDEBUG
+String IDBKey::loggingString() const
+{
+    return IDBKeyData(this).loggingString();
+}
+#endif
+
 } // namespace WebCore
 
 #endif
index 90b62d5..f42f258 100644 (file)
@@ -147,6 +147,10 @@ public:
     using RefCounted<IDBKey>::ref;
     using RefCounted<IDBKey>::deref;
 
+#ifndef NDEBUG
+    String loggingString() const;
+#endif
+
 private:
     IDBKey() : m_type(InvalidType), m_number(0), m_sizeEstimate(OverheadSize) { }
     IDBKey(Type type, double number) : m_type(type), m_number(number), m_sizeEstimate(OverheadSize + sizeof(double)) { }
index c8883b9..ef6099b 100644 (file)
@@ -246,6 +246,38 @@ int IDBKeyData::compare(const IDBKeyData& other)
     return 0;
 }
 
+#ifndef NDEBUG
+String IDBKeyData::loggingString() const
+{
+    if (isNull)
+        return "<null>";
+
+    switch (type) {
+    case IDBKey::InvalidType:
+        return "<invalid>";
+    case IDBKey::ArrayType:
+        {
+            String result = "<array> - { ";
+            for (size_t i = 0; i < arrayValue.size(); ++i) {
+                result.append(arrayValue[i].loggingString());
+                if (i < arrayValue.size() - 1)
+                    result.append(", ");
+            }
+            result.append(" }");
+            return result;
+        }
+    case IDBKey::StringType:
+        return String("<string> - ") + stringValue;
+    case IDBKey::DateType:
+        return String::format("Date type - %f", numberValue);
+    case IDBKey::NumberType:
+        return String::format("<number> - %f", numberValue);
+    case IDBKey::MinType:
+        return "<minimum>";
+    }
+}
+#endif
+
 }
 
 #endif // ENABLE(INDEXED_DATABASE)
index ae83ef2..6ca3c71 100644 (file)
@@ -58,6 +58,10 @@ struct IDBKeyData {
     //   - Returns zero if this IDBKeyData is equal to other.
     int compare(const IDBKeyData& other);
 
+#ifndef NDEBUG
+    String loggingString() const;
+#endif
+
     IDBKey::Type type;
     Vector<IDBKeyData> arrayValue;
     String stringValue;
index 1bc1706..41a44f9 100644 (file)
@@ -275,27 +275,38 @@ void IDBRequest::onSuccess(PassRefPtr<DOMStringList> domStringList)
     enqueueEvent(createSuccessEvent());
 }
 
-void IDBRequest::onSuccess(PassRefPtr<IDBCursorBackend> backend, PassRefPtr<IDBKey> key, PassRefPtr<IDBKey> primaryKey, PassRefPtr<SharedBuffer> buffer)
+void IDBRequest::onSuccess(PassRefPtr<IDBCursorBackend> prpBackend)
 {
     LOG(StorageAPI, "IDBRequest::onSuccess(IDBCursor)");
     if (!shouldEnqueueEvent())
         return;
 
     DOMRequestState::Scope scope(m_requestState);
-    Deprecated::ScriptValue value = deserializeIDBValueBuffer(requestState(), buffer);
+
+    RefPtr<IDBCursorBackend> backend = prpBackend;
+    RefPtr<IDBKey> key = backend->key();
+    RefPtr<IDBKey> primaryKey = backend->primaryKey();
+
+    Deprecated::ScriptValue value;
+
+    if (backend->valueKey())
+        value = idbKeyToScriptValue(requestState(), backend->valueKey());
+    else
+        value = deserializeIDBValueBuffer(requestState(), backend->valueBuffer());
+
     ASSERT(!m_pendingCursor);
     RefPtr<IDBCursor> cursor;
     switch (m_cursorType) {
     case IndexedDB::CursorType::KeyOnly:
-        cursor = IDBCursor::create(backend, m_cursorDirection, this, m_source.get(), m_transaction.get());
+        cursor = IDBCursor::create(backend.release(), m_cursorDirection, this, m_source.get(), m_transaction.get());
         break;
     case IndexedDB::CursorType::KeyAndValue:
-        cursor = IDBCursorWithValue::create(backend, m_cursorDirection, this, m_source.get(), m_transaction.get());
+        cursor = IDBCursorWithValue::create(backend.release(), m_cursorDirection, this, m_source.get(), m_transaction.get());
         break;
     default:
         ASSERT_NOT_REACHED();
     }
-    setResultCursor(cursor, key, primaryKey, value);
+    setResultCursor(cursor, key.release(), primaryKey.release(), value);
 
     enqueueEvent(createSuccessEvent());
 }
@@ -395,12 +406,23 @@ void IDBRequest::onSuccessInternal(const Deprecated::ScriptValue& value)
 
 void IDBRequest::onSuccess(PassRefPtr<IDBKey> key, PassRefPtr<IDBKey> primaryKey, PassRefPtr<SharedBuffer> buffer)
 {
-    LOG(StorageAPI, "IDBRequest::onSuccess(key, primaryKey, value)");
+    onSuccess(key, primaryKey, buffer, nullptr);
+}
+
+void IDBRequest::onSuccess(PassRefPtr<IDBKey> key, PassRefPtr<IDBKey> primaryKey, PassRefPtr<SharedBuffer> buffer, PassRefPtr<IDBKey> valueKey)
+{
+    LOG(StorageAPI, "IDBRequest::onSuccess(key, primaryKey, valueBuffer, valueKey)");
     if (!shouldEnqueueEvent())
         return;
 
     DOMRequestState::Scope scope(m_requestState);
-    Deprecated::ScriptValue value = deserializeIDBValueBuffer(requestState(), buffer);
+
+    Deprecated::ScriptValue value;
+    if (valueKey)
+        value = idbKeyToScriptValue(requestState(), valueKey);
+    else
+        value = deserializeIDBValueBuffer(requestState(), buffer);
+
     ASSERT(m_pendingCursor);
     setResultCursor(m_pendingCursor.release(), key, primaryKey, value);
     enqueueEvent(createSuccessEvent());
index 0b5a4be..9b71f09 100644 (file)
@@ -86,13 +86,14 @@ public:
     // IDBCallbacks
     virtual void onError(PassRefPtr<IDBDatabaseError>);
     virtual void onSuccess(PassRefPtr<DOMStringList>);
-    virtual void onSuccess(PassRefPtr<IDBCursorBackend>, PassRefPtr<IDBKey>, PassRefPtr<IDBKey> primaryKey, PassRefPtr<SharedBuffer>);
+    virtual void onSuccess(PassRefPtr<IDBCursorBackend>);
     virtual void onSuccess(PassRefPtr<IDBKey>);
     virtual void onSuccess(PassRefPtr<SharedBuffer>);
     virtual void onSuccess(PassRefPtr<SharedBuffer>, PassRefPtr<IDBKey>, const IDBKeyPath&);
     virtual void onSuccess(int64_t);
     virtual void onSuccess();
     virtual void onSuccess(PassRefPtr<IDBKey>, PassRefPtr<IDBKey> primaryKey, PassRefPtr<SharedBuffer>);
+    virtual void onSuccess(PassRefPtr<IDBKey>, PassRefPtr<IDBKey> primaryKey, PassRefPtr<SharedBuffer>, PassRefPtr<IDBKey> valueKey);
     virtual void onSuccessWithPrefetch(const Vector<RefPtr<IDBKey>>&, const Vector<RefPtr<IDBKey>>&, const Vector<RefPtr<SharedBuffer>>&) { ASSERT_NOT_REACHED(); } // Not implemented. Callback should not reach the renderer side.
 
     // ActiveDOMObject
index 9323a2c..0c21b62 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<IDBKey>, PassRefPtr<IDBKey>, PassRefPtr<SharedBuffer>, PassRefPtr<IDBDatabaseError>)> completionCallback) = 0;
+    virtual void openCursor(IDBTransactionBackend&, const OpenCursorOperation&, std::function<void(int64_t, PassRefPtr<IDBKey>, PassRefPtr<IDBKey>, PassRefPtr<SharedBuffer>, PassRefPtr<IDBKey>, 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;
@@ -89,8 +89,8 @@ public:
     virtual void changeDatabaseVersion(IDBTransactionBackend&, const IDBDatabaseBackend::VersionChangeOperation&, std::function<void(PassRefPtr<IDBDatabaseError>)> completionCallback) = 0;
 
     // Cursor-level operations
-    virtual void cursorAdvance(IDBCursorBackend&, const CursorAdvanceOperation&, std::function<void(PassRefPtr<IDBKey>, PassRefPtr<IDBKey>, PassRefPtr<SharedBuffer>, PassRefPtr<IDBDatabaseError>)> completionCallback) = 0;
-    virtual void cursorIterate(IDBCursorBackend&, const CursorIterationOperation&, std::function<void(PassRefPtr<IDBKey>, PassRefPtr<IDBKey>, PassRefPtr<SharedBuffer>, PassRefPtr<IDBDatabaseError>)> completionCallback) = 0;
+    virtual void cursorAdvance(IDBCursorBackend&, const CursorAdvanceOperation&, std::function<void(PassRefPtr<IDBKey>, PassRefPtr<IDBKey>, PassRefPtr<SharedBuffer>, PassRefPtr<IDBKey>, PassRefPtr<IDBDatabaseError>)> completionCallback) = 0;
+    virtual void cursorIterate(IDBCursorBackend&, const CursorIterationOperation&, std::function<void(PassRefPtr<IDBKey>, PassRefPtr<IDBKey>, PassRefPtr<SharedBuffer>, PassRefPtr<IDBKey>, PassRefPtr<IDBDatabaseError>)> completionCallback) = 0;
 };
 
 } // namespace WebCore
index 4568f16..4a757ef 100644 (file)
@@ -154,17 +154,17 @@ void OpenCursorOperation::perform(std::function<void()> completionCallback)
     LOG(StorageAPI, "OpenCursorOperation");
 
     RefPtr<OpenCursorOperation> operation(this);
-    auto callback = [this, operation, completionCallback](int64_t cursorID, PassRefPtr<IDBKey> key, PassRefPtr<IDBKey> primaryKey, PassRefPtr<SharedBuffer> value, PassRefPtr<IDBDatabaseError>) {
+    auto callback = [this, operation, completionCallback](int64_t cursorID, PassRefPtr<IDBKey> key, PassRefPtr<IDBKey> primaryKey, PassRefPtr<SharedBuffer> valueBuffer, PassRefPtr<IDBKey> valueKey, 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());
+            if (key || primaryKey || valueBuffer || valueKey)
+                cursor->updateCursorData(key.get(), primaryKey.get(), valueBuffer.get(), valueKey.get());
 
-            m_callbacks->onSuccess(cursor, cursor->key(), cursor->primaryKey(), cursor->value());
+            m_callbacks->onSuccess(cursor.release());
         }
 
         completionCallback();
index d4b0048..ee2c31a 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<IDBKey>, PassRefPtr<IDBKey>, PassRefPtr<SharedBuffer>, PassRefPtr<IDBDatabaseError>)> completionCallback)
+void IDBServerConnectionLevelDB::openCursor(IDBTransactionBackend& transaction, const OpenCursorOperation& operation, std::function<void(int64_t, PassRefPtr<IDBKey>, PassRefPtr<IDBKey>, PassRefPtr<SharedBuffer>, PassRefPtr<IDBKey>, PassRefPtr<IDBDatabaseError>)> completionCallback)
 {
     IDBBackingStoreTransactionLevelDB* backingStoreTransaction = m_backingStoreTransactions.get(transaction.id());
     ASSERT(backingStoreTransaction);
@@ -462,7 +462,7 @@ void IDBServerConnectionLevelDB::openCursor(IDBTransactionBackend& transaction,
 
     callOnMainThread([completionCallback, cursorID]() {
         // FIXME: Need to actually pass the initial key, primaryKey, and value to the callback.
-        completionCallback(cursorID, nullptr, nullptr, nullptr, nullptr);
+        completionCallback(cursorID, nullptr, nullptr, nullptr, nullptr, nullptr);
     });
 }
 
@@ -569,7 +569,7 @@ void IDBServerConnectionLevelDB::changeDatabaseVersion(IDBTransactionBackend& tr
     ASYNC_COMPLETION_CALLBACK_WITH_NULL_ARG(completionCallback);
 }
 
-void IDBServerConnectionLevelDB::cursorAdvance(IDBCursorBackend& cursor, const CursorAdvanceOperation& operation, std::function<void(PassRefPtr<IDBKey>, PassRefPtr<IDBKey>, PassRefPtr<SharedBuffer>, PassRefPtr<IDBDatabaseError>)> completionCallback)
+void IDBServerConnectionLevelDB::cursorAdvance(IDBCursorBackend& cursor, const CursorAdvanceOperation& operation, std::function<void(PassRefPtr<IDBKey>, PassRefPtr<IDBKey>, PassRefPtr<SharedBuffer>, PassRefPtr<IDBKey>, PassRefPtr<IDBDatabaseError>)> completionCallback)
 {
     IDBBackingStoreCursorLevelDB* backingStoreCursor = cursor.id() ? m_backingStoreCursors.get(cursor.id()) : 0;
 #ifndef NDEBUG
@@ -581,7 +581,7 @@ void IDBServerConnectionLevelDB::cursorAdvance(IDBCursorBackend& cursor, const C
         m_backingStoreCursors.remove(cursor.id());
 
         callOnMainThread([completionCallback]() {
-            completionCallback(nullptr, nullptr, nullptr, IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Unknown error advancing cursor"));
+            completionCallback(nullptr, nullptr, nullptr, nullptr, IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Unknown error advancing cursor"));
         });
 
         return;
@@ -591,11 +591,11 @@ void IDBServerConnectionLevelDB::cursorAdvance(IDBCursorBackend& cursor, const C
     RefPtr<SharedBuffer> value = backingStoreCursor->value();
 
     callOnMainThread([completionCallback, key, primaryKey, value]() {
-        completionCallback(key, primaryKey, value, IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Unknown error advancing cursor"));
+        completionCallback(key, primaryKey, value, nullptr, IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Unknown error advancing cursor"));
     });
 }
 
-void IDBServerConnectionLevelDB::cursorIterate(IDBCursorBackend& cursor, const CursorIterationOperation& operation, std::function<void(PassRefPtr<IDBKey>, PassRefPtr<IDBKey>, PassRefPtr<SharedBuffer>, PassRefPtr<IDBDatabaseError>)> completionCallback)
+void IDBServerConnectionLevelDB::cursorIterate(IDBCursorBackend& cursor, const CursorIterationOperation& operation, std::function<void(PassRefPtr<IDBKey>, PassRefPtr<IDBKey>, PassRefPtr<SharedBuffer>, PassRefPtr<IDBKey>, PassRefPtr<IDBDatabaseError>)> completionCallback)
 {
     IDBBackingStoreCursorLevelDB* backingStoreCursor = cursor.id() ? m_backingStoreCursors.get(cursor.id()) : 0;
 #ifndef NDEBUG
@@ -607,7 +607,7 @@ void IDBServerConnectionLevelDB::cursorIterate(IDBCursorBackend& cursor, const C
         m_backingStoreCursors.remove(cursor.id());
 
         callOnMainThread([completionCallback]() {
-            completionCallback(nullptr, nullptr, nullptr, IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Unknown error advancing cursor"));
+            completionCallback(nullptr, nullptr, nullptr, nullptr, IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Unknown error advancing cursor"));
         });
 
         return;
@@ -617,7 +617,7 @@ void IDBServerConnectionLevelDB::cursorIterate(IDBCursorBackend& cursor, const C
     RefPtr<SharedBuffer> value = backingStoreCursor->value();
 
     callOnMainThread([completionCallback, key, primaryKey, value]() {
-        completionCallback(key, primaryKey, value, IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Unknown error advancing cursor"));
+        completionCallback(key, primaryKey, value, nullptr, IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Unknown error advancing cursor"));
     });
 }
 
index 978bcd2..69df779 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<IDBKey>, PassRefPtr<IDBKey>, PassRefPtr<SharedBuffer>, PassRefPtr<IDBDatabaseError>)> completionCallback) override;
+    virtual void openCursor(IDBTransactionBackend&, const OpenCursorOperation&, std::function<void(int64_t, PassRefPtr<IDBKey>, PassRefPtr<IDBKey>, PassRefPtr<SharedBuffer>, PassRefPtr<IDBKey>, 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;
@@ -76,8 +76,8 @@ public:
     virtual void changeDatabaseVersion(IDBTransactionBackend&, const IDBDatabaseBackend::VersionChangeOperation&, std::function<void(PassRefPtr<IDBDatabaseError>)> completionCallback) override;
 
     // Cursor-level operations
-    virtual void cursorAdvance(IDBCursorBackend&, const CursorAdvanceOperation&, std::function<void(PassRefPtr<IDBKey>, PassRefPtr<IDBKey>, PassRefPtr<SharedBuffer>, PassRefPtr<IDBDatabaseError>)> completionCallback) override;
-    virtual void cursorIterate(IDBCursorBackend&, const CursorIterationOperation&, std::function<void(PassRefPtr<IDBKey>, PassRefPtr<IDBKey>, PassRefPtr<SharedBuffer>, PassRefPtr<IDBDatabaseError>)> completionCallback) override;
+    virtual void cursorAdvance(IDBCursorBackend&, const CursorAdvanceOperation&, std::function<void(PassRefPtr<IDBKey>, PassRefPtr<IDBKey>, PassRefPtr<SharedBuffer>, PassRefPtr<IDBKey>, PassRefPtr<IDBDatabaseError>)> completionCallback) override;
+    virtual void cursorIterate(IDBCursorBackend&, const CursorIterationOperation&, std::function<void(PassRefPtr<IDBKey>, PassRefPtr<IDBKey>, PassRefPtr<SharedBuffer>, PassRefPtr<IDBKey>, PassRefPtr<IDBDatabaseError>)> completionCallback) override;
 
 private:
     IDBServerConnectionLevelDB(const String& databaseName, IDBBackingStoreLevelDB*);
index e782496..276e9f7 100644 (file)
@@ -3087,6 +3087,7 @@ __ZN7WebCore26MockMediaPlayerMediaSource19registerMediaEngineEPFvPFN3WTF10PassOw
 #endif
 
 #if ENABLE(INDEXED_DATABASE)
+__ZNK7WebCore10IDBKeyData13loggingStringEv
 __ZNK7WebCore10IDBKeyData17maybeCreateIDBKeyEv
 __ZNK7WebCore10IDBKeyData6encodeERNS_12KeyedEncoderE
 __ZNK7WebCore10IDBKeyPath6encodeERNS_12KeyedEncoderE
index a292ebe..93eebec 100644 (file)
@@ -1,3 +1,53 @@
+2014-01-31  Brady Eidson  <beidson@apple.com>
+
+        IDB: Index cursors use wrong deserialization for the retrieved value
+        https://bugs.webkit.org/show_bug.cgi?id=128035
+
+        Reviewed by Dan Bernstein.
+
+        Most of this is updating everything related to the cursor operation callbacks 
+        to support returning an IDBKey value in addition to a SharedBuffer value.
+
+        * DatabaseProcess/IndexedDB/DatabaseProcessIDBConnection.cpp:
+        (WebKit::DatabaseProcessIDBConnection::openCursor):
+        (WebKit::DatabaseProcessIDBConnection::cursorAdvance):
+        (WebKit::DatabaseProcessIDBConnection::cursorIterate):
+
+        * 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:
+
+        * DatabaseProcess/IndexedDB/UniqueIDBDatabaseBackingStore.h:
+        * DatabaseProcess/IndexedDB/sqlite/UniqueIDBDatabaseBackingStoreSQLite.cpp:
+        (WebKit::UniqueIDBDatabaseBackingStoreSQLite::openCursor):
+        (WebKit::UniqueIDBDatabaseBackingStoreSQLite::advanceCursor):
+        (WebKit::UniqueIDBDatabaseBackingStoreSQLite::iterateCursor):
+        * DatabaseProcess/IndexedDB/sqlite/UniqueIDBDatabaseBackingStoreSQLite.h:
+
+        * DatabaseProcess/IndexedDB/sqlite/SQLiteIDBCursor.cpp:
+        (WebKit::SQLiteIDBCursor::advance):
+        * DatabaseProcess/IndexedDB/sqlite/SQLiteIDBCursor.h:
+        (WebKit::SQLiteIDBCursor::currentValueBuffer):
+        (WebKit::SQLiteIDBCursor::currentValueKey):
+
+        * 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:
+
 2014-01-31  Ryosuke Niwa  <rniwa@webkit.org>
 
         Remove inline member functions of FrameSelection that access m_selection
index 2a64e33..2dbfeef 100644 (file)
@@ -272,9 +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, const IDBKeyData& resultKey, const IDBKeyData& primaryKey, PassRefPtr<SharedBuffer> value, uint32_t errorCode, const String& 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, const IDBKeyData& valueKey, 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));
+        connection->send(Messages::WebIDBServerConnection::DidOpenCursor(requestID, cursorID, resultKey, primaryKey, data, valueKey, errorCode, errorMessage));
     });
 }
 
@@ -284,9 +284,9 @@ void DatabaseProcessIDBConnection::cursorAdvance(uint64_t requestID, int64_t cur
 
     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) {
+    m_uniqueIDBDatabase->cursorAdvance(IDBIdentifier(*this, cursorID), count, [connection, requestID](const IDBKeyData& resultKey, const IDBKeyData& primaryKey, PassRefPtr<SharedBuffer> value, const IDBKeyData& valueKey, 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));
+        connection->send(Messages::WebIDBServerConnection::DidAdvanceCursor(requestID, resultKey, primaryKey, data, valueKey, errorCode, errorMessage));
     });
 }
 
@@ -296,9 +296,9 @@ void DatabaseProcessIDBConnection::cursorIterate(uint64_t requestID, int64_t cur
 
     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) {
+    m_uniqueIDBDatabase->cursorIterate(IDBIdentifier(*this, cursorID), key, [connection, requestID](const IDBKeyData& resultKey, const IDBKeyData& primaryKey, PassRefPtr<SharedBuffer> value, const IDBKeyData& valueKey, 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));
+        connection->send(Messages::WebIDBServerConnection::DidIterateCursor(requestID, resultKey, primaryKey, data, valueKey, errorCode, errorMessage));
     });
 }
 
index 85c3f3b..c21e51e 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, const IDBKeyData&, const IDBKeyData&, PassRefPtr<SharedBuffer>, 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>, const IDBKeyData&, uint32_t, const String&)> callback)
 {
     ASSERT(isMainThread());
 
     if (!m_acceptingNewRequests) {
-        callback(0, nullptr, nullptr, nullptr, INVALID_STATE_ERR, "Unable to open cursor in database because it has shut down");
+        callback(0, nullptr, 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, 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);
+    RefPtr<AsyncRequest> request = AsyncRequestImpl<int64_t, const IDBKeyData&, const IDBKeyData&, PassRefPtr<SharedBuffer>, const IDBKeyData&, uint32_t, const String&>::create([this, callback](int64_t cursorID, const IDBKeyData& key, const IDBKeyData& primaryKey, PassRefPtr<SharedBuffer> value, const IDBKeyData& valueKey, uint32_t errorCode, const String& errorMessage) {
+        callback(cursorID, key, primaryKey, value, valueKey, errorCode, errorMessage);
     }, [this, callback]() {
-        callback(0, nullptr, nullptr, nullptr, INVALID_STATE_ERR, "Unable to get record from database");
+        callback(0, nullptr, nullptr, nullptr, nullptr, INVALID_STATE_ERR, "Unable to get record from database");
     });
 
     uint64_t requestID = request->requestID();
@@ -572,19 +572,19 @@ 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(const IDBKeyData&, const 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>, const IDBKeyData&, 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");
+        callback(nullptr, nullptr, nullptr, nullptr, INVALID_STATE_ERR, "Unable to advance cursor in database because it has shut down");
         return;
     }
 
-    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);
+    RefPtr<AsyncRequest> request = AsyncRequestImpl<const IDBKeyData&, const IDBKeyData&, PassRefPtr<SharedBuffer>, const IDBKeyData&, uint32_t, const String&>::create([this, callback](const IDBKeyData& key, const IDBKeyData& primaryKey, PassRefPtr<SharedBuffer> value, const IDBKeyData& valueKey, uint32_t errorCode, const String& errorMessage) {
+        callback(key, primaryKey, value, valueKey, errorCode, errorMessage);
     }, [this, callback]() {
-        callback(nullptr, nullptr, nullptr, INVALID_STATE_ERR, "Unable to advance cursor in database");
+        callback(nullptr, nullptr, nullptr, nullptr, INVALID_STATE_ERR, "Unable to advance cursor in database");
     });
 
     uint64_t requestID = request->requestID();
@@ -593,19 +593,19 @@ 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(const IDBKeyData&, const 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>, const IDBKeyData&, 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");
+        callback(nullptr, nullptr, nullptr, nullptr, INVALID_STATE_ERR, "Unable to iterate cursor in database because it has shut down");
         return;
     }
 
-    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);
+    RefPtr<AsyncRequest> request = AsyncRequestImpl<const IDBKeyData&, const IDBKeyData&, PassRefPtr<SharedBuffer>, const IDBKeyData&, uint32_t, const String&>::create([this, callback](const IDBKeyData& key, const IDBKeyData& primaryKey, PassRefPtr<SharedBuffer> value, const IDBKeyData& valueKey, uint32_t errorCode, const String& errorMessage) {
+        callback(key, primaryKey, value, valueKey, errorCode, errorMessage);
     }, [this, callback]() {
-        callback(nullptr, nullptr, nullptr, INVALID_STATE_ERR, "Unable to iterate cursor in database");
+        callback(nullptr, nullptr, nullptr, nullptr, INVALID_STATE_ERR, "Unable to iterate cursor in database");
     });
 
     uint64_t requestID = request->requestID();
@@ -890,75 +890,78 @@ void UniqueIDBDatabase::openCursorInBackingStore(uint64_t requestID, const IDBId
     int64_t cursorID = 0;
     IDBKeyData key;
     IDBKeyData primaryKey;
-    Vector<char> value;
+    Vector<char> valueBuffer;
+    IDBKeyData valueKey;
     int32_t errorCode = 0;
     String errorMessage;
-    bool success = m_backingStore->openCursor(transactionIdentifier, objectStoreID, indexID, cursorDirection, cursorType, taskType, keyRange, cursorID, key, primaryKey, value);
+    bool success = m_backingStore->openCursor(transactionIdentifier, objectStoreID, indexID, cursorDirection, cursorType, taskType, keyRange, cursorID, key, primaryKey, valueBuffer, valueKey);
 
     if (!success) {
         errorCode = IDBDatabaseException::UnknownError;
         errorMessage = ASCIILiteral("Unknown error opening cursor in backing store");
     }
 
-    postMainThreadTask(createAsyncTask(*this, &UniqueIDBDatabase::didOpenCursorInBackingStore, requestID, cursorID, key, primaryKey, value, errorCode, errorMessage));
+    postMainThreadTask(createAsyncTask(*this, &UniqueIDBDatabase::didOpenCursorInBackingStore, requestID, cursorID, key, primaryKey, valueBuffer, valueKey, errorCode, 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)
+void UniqueIDBDatabase::didOpenCursorInBackingStore(uint64_t requestID, int64_t cursorID, const IDBKeyData& key, const IDBKeyData& primaryKey, const Vector<char>& valueBuffer, const IDBKeyData& valueKey, uint32_t errorCode, const String& errorMessage)
 {
     RefPtr<AsyncRequest> request = m_pendingDatabaseTasks.take(requestID);
     ASSERT(request);
 
-    request->completeRequest(cursorID, key, primaryKey, SharedBuffer::create(value.data(), value.size()), errorCode, errorMessage);
+    request->completeRequest(cursorID, key, primaryKey, SharedBuffer::create(valueBuffer.data(), valueBuffer.size()), valueKey, errorCode, errorMessage);
 }
 
 void UniqueIDBDatabase::advanceCursorInBackingStore(uint64_t requestID, const IDBIdentifier& cursorIdentifier, uint64_t count)
 {
     IDBKeyData key;
     IDBKeyData primaryKey;
-    Vector<char> value;
+    Vector<char> valueBuffer;
+    IDBKeyData valueKey;
     int32_t errorCode = 0;
     String errorMessage;
-    bool success = m_backingStore->advanceCursor(cursorIdentifier, count, key, primaryKey, value);
+    bool success = m_backingStore->advanceCursor(cursorIdentifier, count, key, primaryKey, valueBuffer, valueKey);
 
     if (!success) {
         errorCode = IDBDatabaseException::UnknownError;
         errorMessage = ASCIILiteral("Unknown error advancing cursor in backing store");
     }
 
-    postMainThreadTask(createAsyncTask(*this, &UniqueIDBDatabase::didAdvanceCursorInBackingStore, requestID, key, primaryKey, value, errorCode, errorMessage));
+    postMainThreadTask(createAsyncTask(*this, &UniqueIDBDatabase::didAdvanceCursorInBackingStore, requestID, key, primaryKey, valueBuffer, valueKey, errorCode, errorMessage));
 }
 
-void UniqueIDBDatabase::didAdvanceCursorInBackingStore(uint64_t requestID, const IDBKeyData& key, const IDBKeyData& primaryKey, const Vector<char>& value, uint32_t errorCode, const String& errorMessage)
+void UniqueIDBDatabase::didAdvanceCursorInBackingStore(uint64_t requestID, const IDBKeyData& key, const IDBKeyData& primaryKey, const Vector<char>& valueBuffer, const IDBKeyData& valueKey, 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);
+    request->completeRequest(key, primaryKey, SharedBuffer::create(valueBuffer.data(), valueBuffer.size()), valueKey, errorCode, errorMessage);
 }
 
 void UniqueIDBDatabase::iterateCursorInBackingStore(uint64_t requestID, const IDBIdentifier& cursorIdentifier, const IDBKeyData& iterateKey)
 {
     IDBKeyData key;
     IDBKeyData primaryKey;
-    Vector<char> value;
+    Vector<char> valueBuffer;
+    IDBKeyData valueKey;
     int32_t errorCode = 0;
     String errorMessage;
-    bool success = m_backingStore->iterateCursor(cursorIdentifier, iterateKey, key, primaryKey, value);
+    bool success = m_backingStore->iterateCursor(cursorIdentifier, iterateKey, key, primaryKey, valueBuffer, valueKey);
 
     if (!success) {
         errorCode = IDBDatabaseException::UnknownError;
         errorMessage = ASCIILiteral("Unknown error iterating cursor in backing store");
     }
 
-    postMainThreadTask(createAsyncTask(*this, &UniqueIDBDatabase::didIterateCursorInBackingStore, requestID, key, primaryKey, value, errorCode, errorMessage));
+    postMainThreadTask(createAsyncTask(*this, &UniqueIDBDatabase::didIterateCursorInBackingStore, requestID, key, primaryKey, valueBuffer, valueKey, errorCode, errorMessage));
 }
 
-void UniqueIDBDatabase::didIterateCursorInBackingStore(uint64_t requestID, const IDBKeyData& key, const IDBKeyData& primaryKey, const Vector<char>& value, uint32_t errorCode, const String& errorMessage)
+void UniqueIDBDatabase::didIterateCursorInBackingStore(uint64_t requestID, const IDBKeyData& key, const IDBKeyData& primaryKey, const Vector<char>& valueBuffer, const IDBKeyData& valueKey, 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);
+    request->completeRequest(key, primaryKey, SharedBuffer::create(valueBuffer.data(), valueBuffer.size()), valueKey, errorCode, errorMessage);
 }
 
 void UniqueIDBDatabase::countInBackingStore(uint64_t requestID, const IDBIdentifier& transactionIdentifier, int64_t objectStoreID, int64_t indexID, const IDBKeyRangeData& keyRangeData)
index b534c8f..ee48e54 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, 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 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>, const WebCore::IDBKeyData&, 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>, const WebCore::IDBKeyData&, 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>, const WebCore::IDBKeyData&, 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,9 +159,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, 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 didOpenCursorInBackingStore(uint64_t requestID, int64_t cursorID, const WebCore::IDBKeyData&, const WebCore::IDBKeyData&, const Vector<char>&, const WebCore::IDBKeyData&, uint32_t errorCode, const String& errorMessage);
+    void didAdvanceCursorInBackingStore(uint64_t requestID, const WebCore::IDBKeyData&, const WebCore::IDBKeyData&, const Vector<char>&, const WebCore::IDBKeyData&, uint32_t errorCode, const String& errorMessage);
+    void didIterateCursorInBackingStore(uint64_t requestID, const WebCore::IDBKeyData&, const WebCore::IDBKeyData&, const Vector<char>&, const WebCore::IDBKeyData&, uint32_t errorCode, const String& errorMessage);
     void didCountInBackingStore(uint64_t requestID, int64_t count, uint32_t errorCode, const String& errorMessage);
     void didDeleteRangeInBackingStore(uint64_t requestID, uint32_t errorCode, const String& errorMessage);
 
index 4a0b8c4..0ca0fcf 100644 (file)
@@ -74,9 +74,9 @@ 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, 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;
+    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>&, WebCore::IDBKeyData&) = 0;
+    virtual bool advanceCursor(const IDBIdentifier& cursorIdentifier, uint64_t count, WebCore::IDBKeyData&, WebCore::IDBKeyData&, Vector<char>&, WebCore::IDBKeyData&) = 0;
+    virtual bool iterateCursor(const IDBIdentifier& cursorIdentifier, const WebCore::IDBKeyData&, WebCore::IDBKeyData&, WebCore::IDBKeyData&, Vector<char>&, WebCore::IDBKeyData&) = 0;
 };
 
 } // namespace WebKit
index cfd8fe9..e465182 100644 (file)
@@ -244,7 +244,18 @@ bool SQLiteIDBCursor::advance(uint64_t count)
 
     m_currentKey = key;
     m_currentPrimaryKey = key;
-    m_currentValue = keyData;
+    m_currentValueBuffer = keyData;
+
+    if (m_indexID != IDBIndexMetadata::InvalidId) {
+        if (!deserializeIDBKeyData(reinterpret_cast<const uint8_t*>(keyData.data()), keyData.size(), m_currentValueKey)) {
+            LOG_ERROR("Unable to deserialize value data from database while advancing cursor");
+            m_completed = true;
+            return false;
+        }
+
+        // Index cursors should only have a m_currentValueKey, and not m_currentValueBuffer
+        m_currentValueBuffer.clear();
+    }
 
     return true;
 }
index d6896dc..c5bd3b2 100644 (file)
@@ -58,7 +58,8 @@ public:
 
     const WebCore::IDBKeyData& currentKey() const { return m_currentKey; }
     const WebCore::IDBKeyData& currentPrimaryKey() const { return m_currentPrimaryKey; }
-    const Vector<char>& currentValue() const { return m_currentValue; }
+    const Vector<char>& currentValueBuffer() const { return m_currentValueBuffer; }
+    const WebCore::IDBKeyData& currentValueKey() const { return m_currentValueKey; }
 
     bool advance(uint64_t count);
     bool iterate(const WebCore::IDBKeyData& targetKey);
@@ -78,7 +79,8 @@ private:
 
     WebCore::IDBKeyData m_currentKey;
     WebCore::IDBKeyData m_currentPrimaryKey;
-    Vector<char> m_currentValue;
+    Vector<char> m_currentValueBuffer;
+    WebCore::IDBKeyData m_currentValueKey;
 
     std::unique_ptr<WebCore::SQLiteStatement> m_statement;
 
index 34d9baa..6e80b16 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, IDBKeyData& key, IDBKeyData& primaryKey, Vector<char>& value)
+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>& valueBuffer, IDBKeyData& valueKey)
 {
     ASSERT(!isMainThread());
     ASSERT(m_sqliteDB);
@@ -958,12 +958,13 @@ bool UniqueIDBDatabaseBackingStoreSQLite::openCursor(const IDBIdentifier& transa
     cursorID = cursor->identifier().id();
     key = cursor->currentKey();
     primaryKey = cursor->currentPrimaryKey();
-    value = cursor->currentValue();
+    valueBuffer = cursor->currentValueBuffer();
+    valueKey = cursor->currentValueKey();
 
     return true;
 }
 
-bool UniqueIDBDatabaseBackingStoreSQLite::advanceCursor(const IDBIdentifier& cursorIdentifier, uint64_t count, IDBKeyData& key, IDBKeyData& primaryKey, Vector<char>& value)
+bool UniqueIDBDatabaseBackingStoreSQLite::advanceCursor(const IDBIdentifier& cursorIdentifier, uint64_t count, IDBKeyData& key, IDBKeyData& primaryKey, Vector<char>& valueBuffer, IDBKeyData& valueKey)
 {
     ASSERT(!isMainThread());
     ASSERT(m_sqliteDB);
@@ -986,12 +987,13 @@ bool UniqueIDBDatabaseBackingStoreSQLite::advanceCursor(const IDBIdentifier& cur
 
     key = cursor->currentKey();
     primaryKey = cursor->currentPrimaryKey();
-    value = cursor->currentValue();
+    valueBuffer = cursor->currentValueBuffer();
+    valueKey = cursor->currentValueKey();
 
     return true;
 }
 
-bool UniqueIDBDatabaseBackingStoreSQLite::iterateCursor(const IDBIdentifier& cursorIdentifier, const IDBKeyData& targetKey, IDBKeyData& key, IDBKeyData& primaryKey, Vector<char>& value)
+bool UniqueIDBDatabaseBackingStoreSQLite::iterateCursor(const IDBIdentifier& cursorIdentifier, const IDBKeyData& targetKey, IDBKeyData& key, IDBKeyData& primaryKey, Vector<char>& valueBuffer, IDBKeyData& valueKey)
 {
     ASSERT(!isMainThread());
     ASSERT(m_sqliteDB);
@@ -1014,7 +1016,8 @@ bool UniqueIDBDatabaseBackingStoreSQLite::iterateCursor(const IDBIdentifier& cur
 
     key = cursor->currentKey();
     primaryKey = cursor->currentPrimaryKey();
-    value = cursor->currentValue();
+    valueBuffer = cursor->currentValueBuffer();
+    valueKey = cursor->currentValueKey();
 
     return true;
 }
index 7c27b94..8280db2 100644 (file)
@@ -80,9 +80,9 @@ 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, 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;
+    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>&, WebCore::IDBKeyData&) override;
+    virtual bool advanceCursor(const IDBIdentifier& cursorIdentifier, uint64_t count, WebCore::IDBKeyData&, WebCore::IDBKeyData&, Vector<char>&, WebCore::IDBKeyData&) override;
+    virtual bool iterateCursor(const IDBIdentifier& cursorIdentifier, const WebCore::IDBKeyData&, WebCore::IDBKeyData&, WebCore::IDBKeyData&, Vector<char>&, WebCore::IDBKeyData&) override;
 
     void unregisterCursor(SQLiteIDBCursor*);
 
index 8f1298a..74e92f0 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, WebCore::IDBKeyData& key, WebCore::IDBKeyData& primaryKey, const IPC::DataReference& valueData, uint32_t errorCode, const String& errorMessage)
+void WebIDBServerConnection::didOpenCursor(uint64_t requestID, int64_t cursorID, const IDBKeyData& key, const IDBKeyData& primaryKey, const IPC::DataReference& valueData, const IDBKeyData& valueKey, uint32_t errorCode, const String& errorMessage)
 {
     LOG(IDB, "WebProcess didOpenCursor request ID %llu (error - %s)", requestID, errorMessage.utf8().data());
 
@@ -454,10 +454,10 @@ void WebIDBServerConnection::didOpenCursor(uint64_t requestID, int64_t cursorID,
         return;
 
     RefPtr<SharedBuffer> value = SharedBuffer::create(valueData.data(), valueData.size());
-    serverRequest->completeRequest(cursorID, key.maybeCreateIDBKey(), primaryKey.maybeCreateIDBKey(), value.release(), errorCode ? IDBDatabaseError::create(errorCode, errorMessage) : nullptr);
+    serverRequest->completeRequest(cursorID, key.maybeCreateIDBKey(), primaryKey.maybeCreateIDBKey(), value.release(), valueKey.maybeCreateIDBKey(), 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)
+void WebIDBServerConnection::didAdvanceCursor(uint64_t requestID, const IDBKeyData& key, const IDBKeyData& primaryKey, const IPC::DataReference& valueData, const IDBKeyData& valueKey, uint32_t errorCode, const String& errorMessage)
 {
     LOG(IDB, "WebProcess didAdvanceCursor request ID %llu (error - %s)", requestID, errorMessage.utf8().data());
 
@@ -467,10 +467,10 @@ void WebIDBServerConnection::didAdvanceCursor(uint64_t requestID, WebCore::IDBKe
         return;
 
     RefPtr<SharedBuffer> value = SharedBuffer::create(valueData.data(), valueData.size());
-    serverRequest->completeRequest(key.maybeCreateIDBKey(), primaryKey.maybeCreateIDBKey(), value.release(), errorCode ? IDBDatabaseError::create(errorCode, errorMessage) : nullptr);
+    serverRequest->completeRequest(key.maybeCreateIDBKey(), primaryKey.maybeCreateIDBKey(), value.release(), valueKey.maybeCreateIDBKey(), 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)
+void WebIDBServerConnection::didIterateCursor(uint64_t requestID, const IDBKeyData& key, const IDBKeyData& primaryKey, const IPC::DataReference& valueData, const IDBKeyData& valueKey, uint32_t errorCode, const String& errorMessage)
 {
     LOG(IDB, "WebProcess didIterateCursor request ID %llu (error - %s)", requestID, errorMessage.utf8().data());
 
@@ -480,7 +480,7 @@ void WebIDBServerConnection::didIterateCursor(uint64_t requestID, WebCore::IDBKe
         return;
 
     RefPtr<SharedBuffer> value = SharedBuffer::create(valueData.data(), valueData.size());
-    serverRequest->completeRequest(key.maybeCreateIDBKey(), primaryKey.maybeCreateIDBKey(), value.release(), errorCode ? IDBDatabaseError::create(errorCode, errorMessage) : nullptr);
+    serverRequest->completeRequest(key.maybeCreateIDBKey(), primaryKey.maybeCreateIDBKey(), value.release(), valueKey.maybeCreateIDBKey(), errorCode ? IDBDatabaseError::create(errorCode, errorMessage) : nullptr);
 }
 
 void WebIDBServerConnection::count(IDBTransactionBackend& transaction, const CountOperation& operation, std::function<void(int64_t, PassRefPtr<IDBDatabaseError>)> completionCallback)
@@ -628,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<IDBKey>, PassRefPtr<IDBKey>, PassRefPtr<SharedBuffer>, PassRefPtr<IDBDatabaseError>)> completionCallback)
+void WebIDBServerConnection::openCursor(IDBTransactionBackend&, const OpenCursorOperation& operation, std::function<void(int64_t, PassRefPtr<IDBKey>, PassRefPtr<IDBKey>, PassRefPtr<SharedBuffer>, PassRefPtr<IDBKey>, PassRefPtr<IDBDatabaseError>)> completionCallback)
 {
-    RefPtr<AsyncRequest> serverRequest = AsyncRequestImpl<int64_t, PassRefPtr<IDBKey>, PassRefPtr<IDBKey>, PassRefPtr<SharedBuffer>, PassRefPtr<IDBDatabaseError>>::create(completionCallback);
+    RefPtr<AsyncRequest> serverRequest = AsyncRequestImpl<int64_t, PassRefPtr<IDBKey>, PassRefPtr<IDBKey>, PassRefPtr<SharedBuffer>, PassRefPtr<IDBKey>, PassRefPtr<IDBDatabaseError>>::create(completionCallback);
 
     serverRequest->setAbortHandler([completionCallback]() {
-        completionCallback(0, nullptr, nullptr, nullptr, IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Unknown error occured opening database cursor"));
+        completionCallback(0, nullptr, nullptr, nullptr, nullptr, IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Unknown error occured opening database cursor"));
     });
 
     uint64_t requestID = serverRequest->requestID();
@@ -645,12 +645,12 @@ void WebIDBServerConnection::openCursor(IDBTransactionBackend&, const OpenCursor
     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)
+void WebIDBServerConnection::cursorAdvance(IDBCursorBackend&, const CursorAdvanceOperation& operation, std::function<void(PassRefPtr<IDBKey>, PassRefPtr<IDBKey>, PassRefPtr<SharedBuffer>, PassRefPtr<IDBKey>, PassRefPtr<IDBDatabaseError>)> completionCallback)
 {
-    RefPtr<AsyncRequest> serverRequest = AsyncRequestImpl<PassRefPtr<IDBKey>, PassRefPtr<IDBKey>, PassRefPtr<SharedBuffer>, PassRefPtr<IDBDatabaseError>>::create(completionCallback);
+    RefPtr<AsyncRequest> serverRequest = AsyncRequestImpl<PassRefPtr<IDBKey>, PassRefPtr<IDBKey>, PassRefPtr<SharedBuffer>, PassRefPtr<IDBKey>, PassRefPtr<IDBDatabaseError>>::create(completionCallback);
 
     serverRequest->setAbortHandler([completionCallback]() {
-        completionCallback(nullptr, nullptr, nullptr, IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Unknown error occured advancing database cursor"));
+        completionCallback(nullptr, nullptr, nullptr, nullptr, IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Unknown error occured advancing database cursor"));
     });
 
     uint64_t requestID = serverRequest->requestID();
@@ -662,12 +662,12 @@ void WebIDBServerConnection::cursorAdvance(IDBCursorBackend&, const CursorAdvanc
     send(Messages::DatabaseProcessIDBConnection::CursorAdvance(requestID, operation.cursorID(), operation.count()));
 }
 
-void WebIDBServerConnection::cursorIterate(IDBCursorBackend&, const CursorIterationOperation& operation, 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<IDBKey>, PassRefPtr<IDBDatabaseError>)> completionCallback)
 {
-    RefPtr<AsyncRequest> serverRequest = AsyncRequestImpl<PassRefPtr<IDBKey>, PassRefPtr<IDBKey>, PassRefPtr<SharedBuffer>, PassRefPtr<IDBDatabaseError>>::create(completionCallback);
+    RefPtr<AsyncRequest> serverRequest = AsyncRequestImpl<PassRefPtr<IDBKey>, PassRefPtr<IDBKey>, PassRefPtr<SharedBuffer>, PassRefPtr<IDBKey>, PassRefPtr<IDBDatabaseError>>::create(completionCallback);
 
     serverRequest->setAbortHandler([completionCallback]() {
-        completionCallback(nullptr, nullptr, nullptr, IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Unknown error occured iterating database cursor"));
+        completionCallback(nullptr, nullptr, nullptr, nullptr, IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Unknown error occured iterating database cursor"));
     });
 
     uint64_t requestID = serverRequest->requestID();
index 0d50360..2b219d4 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::IDBKey>, PassRefPtr<WebCore::IDBKey>, PassRefPtr<WebCore::SharedBuffer>, 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::IDBKey>, 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;
@@ -80,8 +80,8 @@ public:
     virtual void changeDatabaseVersion(WebCore::IDBTransactionBackend&, const WebCore::IDBDatabaseBackend::VersionChangeOperation&, std::function<void(PassRefPtr<WebCore::IDBDatabaseError>)> completionCallback) override;
 
     // Cursor-level operations
-    virtual void cursorAdvance(WebCore::IDBCursorBackend&, const WebCore::CursorAdvanceOperation&, std::function<void(PassRefPtr<WebCore::IDBKey>, PassRefPtr<WebCore::IDBKey>, PassRefPtr<WebCore::SharedBuffer>, PassRefPtr<WebCore::IDBDatabaseError>)> completionCallback) override;
-    virtual void cursorIterate(WebCore::IDBCursorBackend&, const WebCore::CursorIterationOperation&, std::function<void(PassRefPtr<WebCore::IDBKey>, PassRefPtr<WebCore::IDBKey>, PassRefPtr<WebCore::SharedBuffer>, PassRefPtr<WebCore::IDBDatabaseError>)> completionCallback) override;
+    virtual void cursorAdvance(WebCore::IDBCursorBackend&, const WebCore::CursorAdvanceOperation&, std::function<void(PassRefPtr<WebCore::IDBKey>, PassRefPtr<WebCore::IDBKey>, PassRefPtr<WebCore::SharedBuffer>, PassRefPtr<WebCore::IDBKey>, PassRefPtr<WebCore::IDBDatabaseError>)> completionCallback) override;
+    virtual void cursorIterate(WebCore::IDBCursorBackend&, const WebCore::CursorIterationOperation&, std::function<void(PassRefPtr<WebCore::IDBKey>, PassRefPtr<WebCore::IDBKey>, PassRefPtr<WebCore::SharedBuffer>, PassRefPtr<WebCore::IDBKey>, PassRefPtr<WebCore::IDBDatabaseError>)> completionCallback) override;
 
     // Message handlers.
     void didReceiveWebIDBServerConnectionMessage(IPC::Connection*, IPC::MessageDecoder&);
@@ -110,9 +110,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, 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 didOpenCursor(uint64_t requestID, int64_t cursorID, const WebCore::IDBKeyData&, const WebCore::IDBKeyData&, const IPC::DataReference&, const WebCore::IDBKeyData&, uint32_t errorCode, const String& errorMessage);
+    void didAdvanceCursor(uint64_t requestID, const WebCore::IDBKeyData&, const WebCore::IDBKeyData&, const IPC::DataReference&, const WebCore::IDBKeyData&, uint32_t errorCode, const String& errorMessage);
+    void didIterateCursor(uint64_t requestID, const WebCore::IDBKeyData&, const WebCore::IDBKeyData&, const IPC::DataReference&, const WebCore::IDBKeyData&, uint32_t errorCode, const String& errorMessage);
     void didCount(uint64_t requestID, int64_t count, uint32_t errorCode, const String& errorMessage);
     void didDeleteRange(uint64_t requestID, uint32_t errorCode, const String& errorMessage);
 
index cba850d..92710b1 100644 (file)
@@ -40,9 +40,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, 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)
+    DidOpenCursor(uint64_t requestID, int64_t cursorID, WebCore::IDBKeyData key, WebCore::IDBKeyData primaryKey, IPC::DataReference value, WebCore::IDBKeyData valueKey, uint32_t errorCode, String errorMessage)
+    DidAdvanceCursor(uint64_t requestID, WebCore::IDBKeyData key, WebCore::IDBKeyData primaryKey, IPC::DataReference value, WebCore::IDBKeyData valueKey, uint32_t errorCode, String errorMessage)
+    DidIterateCursor(uint64_t requestID, WebCore::IDBKeyData key, WebCore::IDBKeyData primaryKey, IPC::DataReference value, WebCore::IDBKeyData valueKey, uint32_t errorCode, String errorMessage)
     DidCount(uint64_t requestID, int64_t count, uint32_t errorCode, String errorMessage)
     DidDeleteRange(uint64_t requestID, uint32_t errorCode, String errorMessage)
 }