Diff
Modified: trunk/LayoutTests/ChangeLog (243806 => 243807)
--- trunk/LayoutTests/ChangeLog 2019-04-03 17:00:36 UTC (rev 243806)
+++ trunk/LayoutTests/ChangeLog 2019-04-03 17:03:59 UTC (rev 243807)
@@ -1,3 +1,19 @@
+2019-04-03 Sihui Liu <[email protected]>
+
+ Blob type cannot be stored correctly in IDB when IDBObjectStore has autoIncrement and keyPath options
+ https://bugs.webkit.org/show_bug.cgi?id=196128
+
+ Reviewed by Geoffrey Garen.
+
+ * TestExpectations:
+ * storage/indexeddb/modern/objectstore-autoincrement-types-expected.txt: Added.
+ * storage/indexeddb/modern/objectstore-autoincrement-types.html: Added.
+ * storage/indexeddb/modern/resources/objectstore-autoincrement-types.js: Added.
+ (next):
+ (prepareDatabase.event.target.onsuccess):
+ (prepareDatabase):
+ (testSteps):
+
2019-04-03 Youenn Fablet <[email protected]>
Resetting quota should take into account third party origins
Modified: trunk/LayoutTests/TestExpectations (243806 => 243807)
--- trunk/LayoutTests/TestExpectations 2019-04-03 17:00:36 UTC (rev 243806)
+++ trunk/LayoutTests/TestExpectations 2019-04-03 17:03:59 UTC (rev 243807)
@@ -358,8 +358,6 @@
webkit.org/b/179608 imported/w3c/web-platform-tests/xhr/send-conditional-cors.htm [ Failure ]
webkit.org/b/179611 imported/w3c/web-platform-tests/xhr/send-entity-body-document.htm [ Pass Failure ]
imported/w3c/web-platform-tests/IndexedDB/nested-cloning-large-multiple.html [ Skip ]
-imported/w3c/web-platform-tests/IndexedDB/nested-cloning-large.html [ Skip ]
-imported/w3c/web-platform-tests/IndexedDB/nested-cloning-small.html [ Skip ]
imported/w3c/web-platform-tests/css/cssom/interfaces.html [ Pass Timeout ]
[ Debug ] imported/w3c/web-platform-tests/css/cssom-view/interfaces.html [ Skip ]
webkit.org/b/182292 imported/w3c/web-platform-tests/css/cssom-view/scrollingElement-quirks-dynamic-001.html [ ImageOnlyFailure ]
Modified: trunk/LayoutTests/imported/w3c/ChangeLog (243806 => 243807)
--- trunk/LayoutTests/imported/w3c/ChangeLog 2019-04-03 17:00:36 UTC (rev 243806)
+++ trunk/LayoutTests/imported/w3c/ChangeLog 2019-04-03 17:03:59 UTC (rev 243807)
@@ -1,3 +1,16 @@
+2019-04-03 Sihui Liu <[email protected]>
+
+ Blob type cannot be stored correctly in IDB when IDBObjectStore has autoIncrement and keyPath options
+ https://bugs.webkit.org/show_bug.cgi?id=196128
+
+ Reviewed by Geoffrey Garen.
+
+ Updated test expectations to PASS.
+
+ * web-platform-tests/IndexedDB/nested-cloning-large-expected.txt:
+ * web-platform-tests/IndexedDB/nested-cloning-large-multiple-expected.txt:
+ * web-platform-tests/IndexedDB/nested-cloning-small-expected.txt:
+
2019-04-02 Chris Dumez <[email protected]>
HTML Parser: Remove conditional parsing of <noembed> content
Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/IndexedDB/nested-cloning-large-expected.txt (243806 => 243807)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/IndexedDB/nested-cloning-large-expected.txt 2019-04-03 17:00:36 UTC (rev 243806)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/IndexedDB/nested-cloning-large-expected.txt 2019-04-03 17:03:59 UTC (rev 243807)
@@ -1,9 +1,9 @@
PASS large typed array
PASS blob with large typed array
-FAIL blob with large typed array with key generator assert_equals: IndexedDB result class should match put() argument expected "[object Blob]" but got "[object Null]"
+PASS blob with large typed array with key generator
PASS array of blobs and large typed arrays
-FAIL array of blobs and large typed arrays with key generator assert_equals: IndexedDB result class should match put() argument expected "[object Blob]" but got "[object Null]"
+PASS array of blobs and large typed arrays with key generator
PASS object with blobs and large typed arrays
-FAIL object with blobs and large typed arrays with key generator assert_equals: IndexedDB result class should match put() argument expected "[object Blob]" but got "[object Null]"
+PASS object with blobs and large typed arrays with key generator
Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/IndexedDB/nested-cloning-large-multiple-expected.txt (243806 => 243807)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/IndexedDB/nested-cloning-large-multiple-expected.txt 2019-04-03 17:00:36 UTC (rev 243806)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/IndexedDB/nested-cloning-large-multiple-expected.txt 2019-04-03 17:03:59 UTC (rev 243807)
@@ -1,4 +1,4 @@
PASS multiple requests of objects with blobs and large typed arrays
-FAIL multiple requests of objects with blobs and large typed arrays with key generator assert_equals: IndexedDB result class should match put() argument expected "[object Blob]" but got "[object Null]"
+PASS multiple requests of objects with blobs and large typed arrays with key generator
Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/IndexedDB/nested-cloning-small-expected.txt (243806 => 243807)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/IndexedDB/nested-cloning-small-expected.txt 2019-04-03 17:00:36 UTC (rev 243806)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/IndexedDB/nested-cloning-small-expected.txt 2019-04-03 17:03:59 UTC (rev 243807)
@@ -2,9 +2,9 @@
PASS small typed array
PASS blob
PASS blob with small typed array
-FAIL blob with small typed array with key generator assert_equals: IndexedDB result class should match put() argument expected "[object Blob]" but got "[object Null]"
+PASS blob with small typed array with key generator
PASS blob array
-FAIL blob array with key generator assert_equals: IndexedDB result class should match put() argument expected "[object Blob]" but got "[object Null]"
+PASS blob array with key generator
PASS array of blobs and small typed arrays
-FAIL array of blobs and small typed arrays with key generator assert_equals: IndexedDB result class should match put() argument expected "[object Blob]" but got "[object Null]"
+PASS array of blobs and small typed arrays with key generator
Added: trunk/LayoutTests/storage/indexeddb/modern/objectstore-autoincrement-types-expected.txt (0 => 243807)
--- trunk/LayoutTests/storage/indexeddb/modern/objectstore-autoincrement-types-expected.txt (rev 0)
+++ trunk/LayoutTests/storage/indexeddb/modern/objectstore-autoincrement-types-expected.txt 2019-04-03 17:03:59 UTC (rev 243807)
@@ -0,0 +1,27 @@
+Test IndexedDB's IDBObjectStore auto-increment feature with more types.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+indexedDB = self.indexedDB || self.webkitIndexedDB || self.mozIndexedDB || self.msIndexedDB || self.OIndexedDB;
+
+indexedDB.deleteDatabase(dbname)
+indexedDB.open(dbname)
+createObjectStore():
+store = db.createObjectStore('Store', {keyPath: 'primaryKey', autoIncrement: true})
+PASS request.result.size is blob.size
+PASS request.result.type is blob.type
+PASS request.result.primaryKey is primaryKey
+PASS request.result.name is file.name
+PASS request.result.lastModified is file.lastModified
+PASS request.result.primaryKey is primaryKey
+PASS request.result.height is imageData.height
+PASS request.result.width is imageData.width
+PASS JSON.stringify(request.result.data) is JSON.stringify(imageData.data)
+PASS request.result.primaryKey is primaryKey
+PASS request.result.length is fileList.length
+PASS request.result.primaryKey is primaryKey
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Added: trunk/LayoutTests/storage/indexeddb/modern/objectstore-autoincrement-types.html (0 => 243807)
--- trunk/LayoutTests/storage/indexeddb/modern/objectstore-autoincrement-types.html (rev 0)
+++ trunk/LayoutTests/storage/indexeddb/modern/objectstore-autoincrement-types.html 2019-04-03 17:03:59 UTC (rev 243807)
@@ -0,0 +1,10 @@
+<html>
+<head>
+<script src=""
+<script src=""
+</head>
+<body>
+<input id="fileInput" multiple type="file">
+<script src=""
+</body>
+</html>
\ No newline at end of file
Added: trunk/LayoutTests/storage/indexeddb/modern/resources/objectstore-autoincrement-types.js (0 => 243807)
--- trunk/LayoutTests/storage/indexeddb/modern/resources/objectstore-autoincrement-types.js (rev 0)
+++ trunk/LayoutTests/storage/indexeddb/modern/resources/objectstore-autoincrement-types.js 2019-04-03 17:03:59 UTC (rev 243807)
@@ -0,0 +1,95 @@
+if (this.importScripts) {
+ importScripts('../../../resources/js-test.js');
+ importScripts('shared.js');
+}
+
+description("Test IndexedDB's IDBObjectStore auto-increment feature with more types.");
+
+indexedDBTest(prepareDatabase);
+
+var db;
+var testGenerator;
+function next()
+{
+ testGenerator.next();
+}
+
+function prepareDatabase()
+{
+ db = event.target.result;
+ event.target.transaction._onabort_ = unexpectedAbortCallback;
+
+ debug("createObjectStore():");
+ evalAndLog("store = db.createObjectStore('Store', {keyPath: 'primaryKey', autoIncrement: true})");
+ event.target._onsuccess_ = function() {
+ testGenerator = testSteps();
+ testGenerator.next();
+ };
+}
+
+
+function* testSteps()
+{
+ transaction = db.transaction("Store", "readwrite");
+ objectStore = transaction.objectStore("Store");
+ primaryKey = 1;
+
+ // Blob
+ var imageURL = "data:image/png;base64,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
kJggg==";
+ const [typePart, partRest] = imageURL.split(',');
+ const contentType = typePart.split(':')[1].split(';')[0];
+ const raw = atob(partRest);
+ const rawLength = raw.length;
+ const uInt8Array = new Uint8Array(rawLength);
+ for (let i = 0; i < rawLength; ++i)
+ uInt8Array[i] = raw.charCodeAt(i);
+ blob = new Blob([uInt8Array], { type: contentType });
+ objectStore.put(blob)._onsuccess_ = next;
+ yield;
+ request = objectStore.get(primaryKey);
+ request._onsuccess_ = next;
+ yield;
+ shouldBe("request.result.size", "blob.size");
+ shouldBe("request.result.type", "blob.type");
+ shouldBe("request.result.primaryKey", "primaryKey");
+ ++ primaryKey;
+
+ // File
+ file = new File([blob], "Filename");
+ objectStore.put(file)._onsuccess_ = next;
+ yield;
+ request = objectStore.get(primaryKey);
+ request._onsuccess_ = next;
+ yield;
+ shouldBe("request.result.name", "file.name");
+ shouldBe("request.result.lastModified", "file.lastModified");
+ shouldBe("request.result.primaryKey", "primaryKey");
+ ++ primaryKey;
+
+ // ImageData
+ canvas = document.createElement('canvas');
+ context = canvas.getContext('2d');
+ imageData = context.createImageData(1, 1);
+ objectStore.put(imageData)._onsuccess_ = next;
+ yield;
+ request = objectStore.get(primaryKey);
+ request._onsuccess_ = next;
+ yield;
+ shouldBe("request.result.height", "imageData.height");
+ shouldBe("request.result.width", "imageData.width");
+ shouldBe("JSON.stringify(request.result.data)", "JSON.stringify(imageData.data)");
+ shouldBe("request.result.primaryKey", "primaryKey");
+ ++ primaryKey;
+
+ // Filelist
+ fileList = document.getElementById("fileInput").files;
+ objectStore.put(fileList)._onsuccess_ = next;
+ yield;
+ request = objectStore.get(primaryKey);
+ request._onsuccess_ = next;
+ yield;
+ shouldBe("request.result.length", "fileList.length");
+ shouldBe("request.result.primaryKey", "primaryKey");
+
+ finishJSTest();
+}
\ No newline at end of file
Modified: trunk/Source/WebCore/ChangeLog (243806 => 243807)
--- trunk/Source/WebCore/ChangeLog 2019-04-03 17:00:36 UTC (rev 243806)
+++ trunk/Source/WebCore/ChangeLog 2019-04-03 17:03:59 UTC (rev 243807)
@@ -1,3 +1,112 @@
+2019-04-03 Sihui Liu <[email protected]>
+
+ Blob type cannot be stored correctly in IDB when IDBObjectStore has autoIncrement and keyPath options
+ https://bugs.webkit.org/show_bug.cgi?id=196128
+
+ Reviewed by Geoffrey Garen.
+
+ If a key is auto-generated, it should become a property of the value object. Network process would perform the
+ key injection by deserializing IDBValue into script value, setting the property, serializing the result and
+ storing it in a database record. But network process does not have a JSDOMGlobalObject, so it would fail to
+ deserialize types including Blob and File.
+
+ To solve this issue, we move the key injection to web process and let network process store the original value
+ it gets. In this case, when web process asks for some value, network process should return key, value and key
+ path so that web process can decide whether it should perform a key injection before returning the result. Note
+ that the auto-generated key would always be stored as the key in a ObjectStore record.
+
+ Test: storage/indexeddb/modern/objectstore-autoincrement-types.html
+
+ * Modules/indexeddb/IDBCursor.cpp:
+ (WebCore::IDBCursor::setGetResult):
+ * Modules/indexeddb/IDBCursor.h:
+ (WebCore::IDBCursor::primaryKeyPath):
+ * Modules/indexeddb/IDBGetAllResult.cpp:
+ (WebCore::IDBGetAllResult::isolatedCopy):
+ (WebCore::IDBGetAllResult::addKey):
+ (WebCore::IDBGetAllResult::addValue):
+ (WebCore::IDBGetAllResult::keys const):
+ (WebCore::IDBGetAllResult::values const):
+ (WebCore::IDBGetAllResult::allBlobFilePaths const):
+ (WebCore::isolatedCopyOfVariant): Deleted.
+
+ * Modules/indexeddb/IDBGetAllResult.h: Introduce an IDBKeyPath parameter. Also replace Variant with two Vectors,
+ because we only needed to store either key or value before, and now the stored value could be incomplete.
+ (WebCore::IDBGetAllResult::IDBGetAllResult):
+ (WebCore::IDBGetAllResult::keyPath const):
+ (WebCore::IDBGetAllResult::encode const):
+ (WebCore::IDBGetAllResult::decode):
+
+ * Modules/indexeddb/IDBGetResult.cpp:
+ (WebCore::IDBGetResult::setValue):
+ * Modules/indexeddb/IDBGetResult.h:
+ (WebCore::IDBGetResult::IDBGetResult):
+ (WebCore::IDBGetResult::keyPath const):
+ * Modules/indexeddb/IDBObjectStore.cpp:
+ * Modules/indexeddb/IDBRequest.cpp:
+ (WebCore::IDBRequest::setResult):
+ (WebCore::IDBRequest::setResultToStructuredClone):
+ * Modules/indexeddb/IDBRequest.h:
+ * Modules/indexeddb/IDBTransaction.cpp:
+ (WebCore::IDBTransaction::didGetAllRecordsOnServer):
+ (WebCore::IDBTransaction::didGetRecordOnServer):
+ * Modules/indexeddb/server/MemoryIDBBackingStore.cpp:
+ (WebCore::IDBServer::MemoryIDBBackingStore::getRecord):
+ * Modules/indexeddb/server/MemoryIndex.cpp:
+ (WebCore::IDBServer::MemoryIndex::getResultForKeyRange const):
+ (WebCore::IDBServer::MemoryIndex::getAllRecords const):
+ * Modules/indexeddb/server/MemoryIndexCursor.cpp:
+ (WebCore::IDBServer::MemoryIndexCursor::currentData):
+ * Modules/indexeddb/server/MemoryObjectStore.cpp:
+ (WebCore::IDBServer::MemoryObjectStore::updateIndexesForPutRecord):
+ (WebCore::IDBServer::MemoryObjectStore::populateIndexWithExistingRecords):
+ (WebCore::IDBServer::MemoryObjectStore::getAllRecords const):
+ * Modules/indexeddb/server/MemoryObjectStoreCursor.cpp:
+ (WebCore::IDBServer::MemoryObjectStoreCursor::currentData):
+ * Modules/indexeddb/server/SQLiteIDBBackingStore.cpp:
+ (WebCore::IDBServer::SQLiteIDBBackingStore::updateOneIndexForAddRecord):
+ (WebCore::IDBServer::SQLiteIDBBackingStore::updateAllIndexesForAddRecord):
+ (WebCore::IDBServer::SQLiteIDBBackingStore::getRecord):
+ (WebCore::IDBServer::SQLiteIDBBackingStore::cachedStatementForGetAllObjectStoreRecords):
+ (WebCore::IDBServer::SQLiteIDBBackingStore::getAllObjectStoreRecords):
+ (WebCore::IDBServer::SQLiteIDBBackingStore::getAllIndexRecords):
+ (WebCore::IDBServer::SQLiteIDBBackingStore::getIndexRecord):
+ (WebCore::IDBServer::SQLiteIDBBackingStore::uncheckedGetIndexRecordForOneKey):
+ (WebCore::IDBServer::SQLiteIDBBackingStore::openCursor):
+ (WebCore::IDBServer::SQLiteIDBBackingStore::iterateCursor):
+ * Modules/indexeddb/server/SQLiteIDBCursor.cpp:
+ (WebCore::IDBServer::SQLiteIDBCursor::currentData):
+ * Modules/indexeddb/server/SQLiteIDBCursor.h:
+
+ * Modules/indexeddb/server/UniqueIDBDatabase.cpp:
+ (WebCore::IDBServer::UniqueIDBDatabase::performPutOrAdd): Remove the key injection from network process.
+ UniqueIDBDatabase stores any value it gets from IDBClient.
+
+ * Modules/indexeddb/shared/IDBResultData.cpp:
+ (WebCore::IDBResultData::getResultRef):
+ * Modules/indexeddb/shared/IDBResultData.h:
+
+ * bindings/js/IDBBindingUtilities.cpp:
+ (WebCore::injectIDBKeyIntoScriptValue): If property is read-only, set would fail and injectKeyIntoResult would
+ return null, but we expect it to return result as long as the property value is the same as target. Therefore,
+ we can add an early return here.
+ (WebCore::createKeyPathArray):
+
+ (WebCore::generateIndexKeyForValue): We used to generate IndexKey from value stored in database but now the
+ value gets stored does not include auto-generated key, as we remove the key injection from network process. In
+ this case if the IDBIndex has the same key path as the auto-generated key, IndexKey would be failed to create
+ for it cannot extract auto-generated key from value. Since the auto-generated key would always be the key in
+ database record, we could use value of that key when we find a match in key path.
+
+ (WebCore::deserializeIDBValueWithKeyInjection): If the key path in the result is single entry, the key is
+ probably auto-generated, so we could inject the result key into the result value unconditionally.
+
+ * bindings/js/IDBBindingUtilities.h:
+ * bindings/js/JSIDBCursorWithValueCustom.cpp:
+ (WebCore::JSIDBCursorWithValue::value const):
+ * bindings/js/JSIDBRequestCustom.cpp:
+ (WebCore::JSIDBRequest::result const):
+
2019-04-03 Michael Catanzaro <[email protected]>
Get rid of HTMLInputElement::setEditingValue
Modified: trunk/Source/WebCore/Modules/indexeddb/IDBCursor.cpp (243806 => 243807)
--- trunk/Source/WebCore/Modules/indexeddb/IDBCursor.cpp 2019-04-03 17:00:36 UTC (rev 243806)
+++ trunk/Source/WebCore/Modules/indexeddb/IDBCursor.cpp 2019-04-03 17:03:59 UTC (rev 243807)
@@ -341,8 +341,10 @@
m_primaryKeyData = getResult.primaryKeyData();
m_primaryKey = m_primaryKeyData.maybeCreateIDBKey();
- if (isKeyCursorWithValue())
+ if (isKeyCursorWithValue()) {
m_value = getResult.value();
+ m_keyPath = getResult.keyPath();
+ }
m_gotValue = true;
return true;
Modified: trunk/Source/WebCore/Modules/indexeddb/IDBCursor.h (243806 => 243807)
--- trunk/Source/WebCore/Modules/indexeddb/IDBCursor.h 2019-04-03 17:00:36 UTC (rev 243806)
+++ trunk/Source/WebCore/Modules/indexeddb/IDBCursor.h 2019-04-03 17:03:59 UTC (rev 243807)
@@ -30,6 +30,7 @@
#include "ExceptionOr.h"
#include "IDBCursorDirection.h"
#include "IDBCursorInfo.h"
+#include "IDBKeyPath.h"
#include "IDBValue.h"
#include "JSValueInWrappedObject.h"
#include <_javascript_Core/Strong.h>
@@ -58,6 +59,7 @@
IDBKey* key() { return m_key.get(); };
IDBKey* primaryKey() { return m_primaryKey.get(); };
IDBValue value() { return m_value; };
+ const Optional<IDBKeyPath>& primaryKeyPath() { return m_keyPath; };
JSValueInWrappedObject& keyWrapper() { return m_keyWrapper; }
JSValueInWrappedObject& primaryKeyWrapper() { return m_primaryKeyWrapper; }
JSValueInWrappedObject& valueWrapper() { return m_valueWrapper; }
@@ -104,6 +106,7 @@
IDBKeyData m_keyData;
IDBKeyData m_primaryKeyData;
IDBValue m_value;
+ Optional<IDBKeyPath> m_keyPath;
JSValueInWrappedObject m_keyWrapper;
JSValueInWrappedObject m_primaryKeyWrapper;
Modified: trunk/Source/WebCore/Modules/indexeddb/IDBGetAllResult.cpp (243806 => 243807)
--- trunk/Source/WebCore/Modules/indexeddb/IDBGetAllResult.cpp 2019-04-03 17:00:36 UTC (rev 243806)
+++ trunk/Source/WebCore/Modules/indexeddb/IDBGetAllResult.cpp 2019-04-03 17:03:59 UTC (rev 243807)
@@ -28,20 +28,11 @@
#if ENABLE(INDEXED_DATABASE)
+#include <wtf/CrossThreadCopier.h>
#include <wtf/HashSet.h>
namespace WebCore {
-template<typename T> void isolatedCopyOfVariant(const WTF::Variant<Vector<IDBKeyData>, Vector<IDBValue>, std::nullptr_t>& source, WTF::Variant<Vector<IDBKeyData>, Vector<IDBValue>, std::nullptr_t>& target)
-{
- target = Vector<T>();
- auto& sourceVector = WTF::get<Vector<T>>(source);
- auto& targetVector = WTF::get<Vector<T>>(target);
- targetVector.reserveInitialCapacity(sourceVector.size());
- for (auto& element : sourceVector)
- targetVector.uncheckedAppend(element.isolatedCopy());
-}
-
IDBGetAllResult::IDBGetAllResult(const IDBGetAllResult& that, IsolatedCopyTag)
{
isolatedCopy(that, *this);
@@ -55,46 +46,29 @@
void IDBGetAllResult::isolatedCopy(const IDBGetAllResult& source, IDBGetAllResult& destination)
{
destination.m_type = source.m_type;
-
- if (WTF::holds_alternative<std::nullptr_t>(source.m_results))
- return;
-
- switch (source.m_type) {
- case IndexedDB::GetAllType::Keys:
- isolatedCopyOfVariant<IDBKeyData>(source.m_results, destination.m_results);
- break;
- case IndexedDB::GetAllType::Values:
- isolatedCopyOfVariant<IDBValue>(source.m_results, destination.m_results);
- break;
- }
+ destination.m_keys = crossThreadCopy(source.m_keys);
+ destination.m_values = crossThreadCopy(source.m_values);
+ destination.m_keyPath = WebCore::isolatedCopy(source.m_keyPath);
}
void IDBGetAllResult::addKey(IDBKeyData&& key)
{
- ASSERT(m_type == IndexedDB::GetAllType::Keys);
- ASSERT(WTF::holds_alternative<Vector<IDBKeyData>>(m_results));
- WTF::get<Vector<IDBKeyData>>(m_results).append(WTFMove(key));
+ m_keys.append(WTFMove(key));
}
void IDBGetAllResult::addValue(IDBValue&& value)
{
- ASSERT(m_type == IndexedDB::GetAllType::Values);
- ASSERT(WTF::holds_alternative<Vector<IDBValue>>(m_results));
- WTF::get<Vector<IDBValue>>(m_results).append(WTFMove(value));
+ m_values.append(WTFMove(value));
}
const Vector<IDBKeyData>& IDBGetAllResult::keys() const
{
- ASSERT(m_type == IndexedDB::GetAllType::Keys);
- ASSERT(WTF::holds_alternative<Vector<IDBKeyData>>(m_results));
- return WTF::get<Vector<IDBKeyData>>(m_results);
+ return m_keys;
}
const Vector<IDBValue>& IDBGetAllResult::values() const
{
- ASSERT(m_type == IndexedDB::GetAllType::Values);
- ASSERT(WTF::holds_alternative<Vector<IDBValue>>(m_results));
- return WTF::get<Vector<IDBValue>>(m_results);
+ return m_values;
}
Vector<String> IDBGetAllResult::allBlobFilePaths() const
@@ -102,7 +76,7 @@
ASSERT(m_type == IndexedDB::GetAllType::Values);
HashSet<String> pathSet;
- for (auto& value : WTF::get<Vector<IDBValue>>(m_results)) {
+ for (auto& value : m_values) {
for (auto& path : value.blobFilePaths())
pathSet.add(path);
}
Modified: trunk/Source/WebCore/Modules/indexeddb/IDBGetAllResult.h (243806 => 243807)
--- trunk/Source/WebCore/Modules/indexeddb/IDBGetAllResult.h 2019-04-03 17:00:36 UTC (rev 243806)
+++ trunk/Source/WebCore/Modules/indexeddb/IDBGetAllResult.h 2019-04-03 17:03:59 UTC (rev 243807)
@@ -28,6 +28,7 @@
#if ENABLE(INDEXED_DATABASE)
#include "IDBKeyData.h"
+#include "IDBKeyPath.h"
#include "IDBValue.h"
#include "IndexedDB.h"
@@ -42,17 +43,10 @@
{
}
- IDBGetAllResult(IndexedDB::GetAllType type)
+ IDBGetAllResult(IndexedDB::GetAllType type, const Optional<IDBKeyPath>& keyPath)
: m_type(type)
+ , m_keyPath(keyPath)
{
- switch (m_type) {
- case IndexedDB::GetAllType::Keys:
- m_results = Vector<IDBKeyData>();
- break;
- case IndexedDB::GetAllType::Values:
- m_results = Vector<IDBValue>();
- break;
- }
}
enum IsolatedCopyTag { IsolatedCopy };
@@ -60,6 +54,7 @@
IDBGetAllResult isolatedCopy() const;
IndexedDB::GetAllType type() const { return m_type; }
+ const Optional<IDBKeyPath>& keyPath() const { return m_keyPath; }
const Vector<IDBKeyData>& keys() const;
const Vector<IDBValue>& values() const;
@@ -75,26 +70,15 @@
static void isolatedCopy(const IDBGetAllResult& source, IDBGetAllResult& destination);
IndexedDB::GetAllType m_type { IndexedDB::GetAllType::Keys };
- WTF::Variant<Vector<IDBKeyData>, Vector<IDBValue>, std::nullptr_t> m_results { nullptr };
+ Vector<IDBKeyData> m_keys;
+ Vector<IDBValue> m_values;
+ Optional<IDBKeyPath> m_keyPath;
};
template<class Encoder>
void IDBGetAllResult::encode(Encoder& encoder) const
{
- encoder << m_type << static_cast<uint64_t>(m_results.index());
-
- switch (m_results.index()) {
- case 0:
- encoder << WTF::get<Vector<IDBKeyData>>(m_results);
- break;
- case 1:
- encoder << WTF::get<Vector<IDBValue>>(m_results);
- break;
- case 2:
- break;
- default:
- RELEASE_ASSERT_NOT_REACHED();
- }
+ encoder << m_type << m_keys << m_values << m_keyPath;
}
template<class Decoder>
@@ -103,32 +87,14 @@
if (!decoder.decode(result.m_type))
return false;
- uint64_t index;
- if (!decoder.decode(index))
+ if (!decoder.decode(result.m_keys))
return false;
- switch (index) {
- case 0: {
- result.m_results = Vector<IDBKeyData>();
- if (!decoder.decode(WTF::get<Vector<IDBKeyData>>(result.m_results)))
- return false;
- break;
- }
- case 1: {
- result.m_results = Vector<IDBValue>();
- Optional<Vector<IDBValue>> optional;
- decoder >> optional;
- if (!optional)
- return false;
- WTF::get<Vector<IDBValue>>(result.m_results) = WTFMove(*optional);
- break;
- }
- case 2:
- result.m_results = nullptr;
- break;
- default:
- RELEASE_ASSERT_NOT_REACHED();
- }
+ if (!decoder.decode(result.m_values))
+ return false;
+
+ if (!decoder.decode(result.m_keyPath))
+ return false;
return true;
}
Modified: trunk/Source/WebCore/Modules/indexeddb/IDBGetResult.cpp (243806 => 243807)
--- trunk/Source/WebCore/Modules/indexeddb/IDBGetResult.cpp 2019-04-03 17:00:36 UTC (rev 243806)
+++ trunk/Source/WebCore/Modules/indexeddb/IDBGetResult.cpp 2019-04-03 17:03:59 UTC (rev 243807)
@@ -57,6 +57,11 @@
destination.m_isDefined = source.m_isDefined;
}
+void IDBGetResult::setValue(IDBValue&& value)
+{
+ m_value = WTFMove(value);
+}
+
} // namespace WebCore
#endif // ENABLE(INDEXED_DATABASE)
Modified: trunk/Source/WebCore/Modules/indexeddb/IDBGetResult.h (243806 => 243807)
--- trunk/Source/WebCore/Modules/indexeddb/IDBGetResult.h 2019-04-03 17:00:36 UTC (rev 243806)
+++ trunk/Source/WebCore/Modules/indexeddb/IDBGetResult.h 2019-04-03 17:03:59 UTC (rev 243807)
@@ -43,40 +43,11 @@
{
}
- IDBGetResult(const IDBValue& value, const IDBKeyData& currentPrimaryKey)
- : m_value(value)
- , m_primaryKeyData(currentPrimaryKey)
- {
- }
-
- IDBGetResult(const ThreadSafeDataBuffer& buffer)
- : m_value(buffer)
- {
- }
-
- IDBGetResult(IDBValue&& buffer)
- : m_value(WTFMove(buffer))
- {
- }
-
- IDBGetResult(IDBKey& key)
- : m_keyData(&key)
- {
- }
-
IDBGetResult(const IDBKeyData& keyData)
: m_keyData(keyData)
{
}
- IDBGetResult(SharedBuffer* buffer, IDBKey& key, const IDBKeyPath& path)
- : m_keyData(&key)
- , m_keyPath(path)
- {
- if (buffer)
- dataFromBuffer(*buffer);
- }
-
IDBGetResult(const IDBKeyData& keyData, const IDBKeyData& primaryKeyData)
: m_keyData(keyData)
, m_primaryKeyData(primaryKeyData)
@@ -83,17 +54,25 @@
{
}
- IDBGetResult(const IDBKeyData& keyData, const IDBKeyData& primaryKeyData, IDBValue&& value)
+ IDBGetResult(const IDBKeyData& keyData, const ThreadSafeDataBuffer& buffer, const Optional<IDBKeyPath>& keyPath)
+ : m_value(buffer)
+ , m_keyData(keyData)
+ , m_keyPath(keyPath)
+ {
+ }
+
+ IDBGetResult(const IDBKeyData& keyData, IDBValue&& value, const Optional<IDBKeyPath>& keyPath)
: m_value(WTFMove(value))
, m_keyData(keyData)
- , m_primaryKeyData(primaryKeyData)
+ , m_keyPath(keyPath)
{
}
- IDBGetResult(const IDBKeyData& keyData, const IDBKeyData& primaryKeyData, const IDBValue& value)
- : m_value(value)
+ IDBGetResult(const IDBKeyData& keyData, const IDBKeyData& primaryKeyData, IDBValue&& value, const Optional<IDBKeyPath>& keyPath)
+ : m_value(WTFMove(value))
, m_keyData(keyData)
, m_primaryKeyData(primaryKeyData)
+ , m_keyPath(keyPath)
{
}
@@ -102,10 +81,12 @@
IDBGetResult isolatedCopy() const;
+ void setValue(IDBValue&&);
+
const IDBValue& value() const { return m_value; }
const IDBKeyData& keyData() const { return m_keyData; }
const IDBKeyData& primaryKeyData() const { return m_primaryKeyData; }
- const IDBKeyPath& keyPath() const { return m_keyPath; }
+ const Optional<IDBKeyPath>& keyPath() const { return m_keyPath; }
bool isDefined() const { return m_isDefined; }
template<class Encoder> void encode(Encoder&) const;
@@ -119,7 +100,7 @@
IDBValue m_value;
IDBKeyData m_keyData;
IDBKeyData m_primaryKeyData;
- IDBKeyPath m_keyPath;
+ Optional<IDBKeyPath> m_keyPath;
bool m_isDefined { true };
};
Modified: trunk/Source/WebCore/Modules/indexeddb/IDBRequest.cpp (243806 => 243807)
--- trunk/Source/WebCore/Modules/indexeddb/IDBRequest.cpp 2019-04-03 17:00:36 UTC (rev 243806)
+++ trunk/Source/WebCore/Modules/indexeddb/IDBRequest.cpp 2019-04-03 17:03:59 UTC (rev 243807)
@@ -391,7 +391,7 @@
m_resultWrapper = { };
}
-void IDBRequest::setResult(const Vector<IDBValue>& values)
+void IDBRequest::setResult(const IDBGetAllResult& result)
{
ASSERT(&originThread() == &Thread::current());
@@ -401,7 +401,7 @@
VM& vm = context->vm();
JSLockHolder lock(vm);
- m_result = values;
+ m_result = result;
m_resultWrapper = { };
}
@@ -419,7 +419,7 @@
m_resultWrapper = { };
}
-void IDBRequest::setResultToStructuredClone(const IDBValue& value)
+void IDBRequest::setResultToStructuredClone(const IDBGetResult& result)
{
ASSERT(&originThread() == &Thread::current());
@@ -431,7 +431,7 @@
VM& vm = context->vm();
JSLockHolder lock(vm);
- m_result = value;
+ m_result = result;
m_resultWrapper = { };
}
Modified: trunk/Source/WebCore/Modules/indexeddb/IDBRequest.h (243806 => 243807)
--- trunk/Source/WebCore/Modules/indexeddb/IDBRequest.h 2019-04-03 17:00:36 UTC (rev 243806)
+++ trunk/Source/WebCore/Modules/indexeddb/IDBRequest.h 2019-04-03 17:03:59 UTC (rev 243807)
@@ -31,6 +31,8 @@
#include "ExceptionOr.h"
#include "IDBActiveDOMObject.h"
#include "IDBError.h"
+#include "IDBGetAllResult.h"
+#include "IDBGetResult.h"
#include "IDBKeyData.h"
#include "IDBResourceIdentifier.h"
#include "IDBValue.h"
@@ -75,7 +77,7 @@
virtual ~IDBRequest();
- using Result = Variant<RefPtr<IDBCursor>, RefPtr<IDBDatabase>, IDBKeyData, Vector<IDBKeyData>, IDBValue, Vector<IDBValue>, uint64_t, NullResultType>;
+ using Result = Variant<RefPtr<IDBCursor>, RefPtr<IDBDatabase>, IDBKeyData, Vector<IDBKeyData>, IDBGetResult, IDBGetAllResult, uint64_t, NullResultType>;
ExceptionOr<Result> result() const;
JSValueInWrappedObject& resultWrapper() { return m_resultWrapper; }
JSValueInWrappedObject& cursorWrapper() { return m_cursorWrapper; }
@@ -106,9 +108,9 @@
void setResult(const IDBKeyData&);
void setResult(const Vector<IDBKeyData>&);
- void setResult(const Vector<IDBValue>&);
+ void setResultToStructuredClone(const IDBGetResult&);
+ void setResult(const IDBGetAllResult&);
void setResult(uint64_t);
- void setResultToStructuredClone(const IDBValue&);
void setResultToUndefined();
void willIterateCursor(IDBCursor&);
Modified: trunk/Source/WebCore/Modules/indexeddb/IDBTransaction.cpp (243806 => 243807)
--- trunk/Source/WebCore/Modules/indexeddb/IDBTransaction.cpp 2019-04-03 17:00:36 UTC (rev 243806)
+++ trunk/Source/WebCore/Modules/indexeddb/IDBTransaction.cpp 2019-04-03 17:03:59 UTC (rev 243807)
@@ -986,7 +986,7 @@
request.setResult(getAllResult.keys());
break;
case IndexedDB::GetAllType::Values:
- request.setResult(getAllResult.values());
+ request.setResult(getAllResult);
break;
}
@@ -1090,7 +1090,7 @@
request.setResultToUndefined();
} else {
if (resultData.getResult().value().data().data())
- request.setResultToStructuredClone(resultData.getResult().value());
+ request.setResultToStructuredClone(resultData.getResult());
else
request.setResultToUndefined();
}
Modified: trunk/Source/WebCore/Modules/indexeddb/server/MemoryIDBBackingStore.cpp (243806 => 243807)
--- trunk/Source/WebCore/Modules/indexeddb/server/MemoryIDBBackingStore.cpp 2019-04-03 17:00:36 UTC (rev 243806)
+++ trunk/Source/WebCore/Modules/indexeddb/server/MemoryIDBBackingStore.cpp 2019-04-03 17:03:59 UTC (rev 243807)
@@ -363,9 +363,11 @@
return IDBError { UnknownError, "No backing store object store found"_s };
switch (type) {
- case IDBGetRecordDataType::KeyAndValue:
- outValue = objectStore->valueForKeyRange(range);
+ case IDBGetRecordDataType::KeyAndValue: {
+ auto key = objectStore->lowestKeyWithRecordInRange(range);
+ outValue = { key, key.isNull() ? ThreadSafeDataBuffer() : objectStore->valueForKey(key), objectStore->info().keyPath() };
break;
+ }
case IDBGetRecordDataType::KeyOnly:
outValue = objectStore->lowestKeyWithRecordInRange(range);
break;
Modified: trunk/Source/WebCore/Modules/indexeddb/server/MemoryIndex.cpp (243806 => 243807)
--- trunk/Source/WebCore/Modules/indexeddb/server/MemoryIndex.cpp 2019-04-03 17:00:36 UTC (rev 243806)
+++ trunk/Source/WebCore/Modules/indexeddb/server/MemoryIndex.cpp 2019-04-03 17:03:59 UTC (rev 243807)
@@ -126,7 +126,7 @@
if (!keyValue)
return { };
- return type == IndexedDB::IndexRecordType::Key ? IDBGetResult(*keyValue) : IDBGetResult(m_objectStore.valueForKeyRange(*keyValue));
+ return type == IndexedDB::IndexRecordType::Key ? IDBGetResult(*keyValue) : IDBGetResult(*keyValue, m_objectStore.valueForKeyRange(*keyValue), m_objectStore.info().keyPath());
}
uint64_t MemoryIndex::countForKeyRange(const IDBKeyRangeData& inRange)
@@ -156,7 +156,7 @@
{
LOG(IndexedDB, "MemoryIndex::getAllRecords");
- result = { type };
+ result = { type, m_objectStore.info().keyPath() };
if (!m_records)
return;
@@ -179,10 +179,8 @@
auto allValues = m_records->allValuesForKey(key, targetCount - currentCount);
for (auto& keyValue : allValues) {
- if (type == IndexedDB::GetAllType::Keys) {
- IDBKeyData keyCopy { keyValue };
- result.addKey(WTFMove(keyCopy));
- } else
+ result.addKey(IDBKeyData(keyValue));
+ if (type == IndexedDB::GetAllType::Values)
result.addValue(m_objectStore.valueForKeyRange(keyValue));
}
Modified: trunk/Source/WebCore/Modules/indexeddb/server/MemoryIndexCursor.cpp (243806 => 243807)
--- trunk/Source/WebCore/Modules/indexeddb/server/MemoryIndexCursor.cpp 2019-04-03 17:00:36 UTC (rev 243806)
+++ trunk/Source/WebCore/Modules/indexeddb/server/MemoryIndexCursor.cpp 2019-04-03 17:03:59 UTC (rev 243807)
@@ -75,7 +75,7 @@
getResult = { m_currentKey, m_currentPrimaryKey };
else {
IDBValue value = { m_index.objectStore().valueForKey(m_currentPrimaryKey), { }, { }, { } };
- getResult = { m_currentKey, m_currentPrimaryKey, WTFMove(value) };
+ getResult = { m_currentKey, m_currentPrimaryKey, WTFMove(value), m_index.objectStore().info().keyPath() };
}
}
Modified: trunk/Source/WebCore/Modules/indexeddb/server/MemoryObjectStore.cpp (243806 => 243807)
--- trunk/Source/WebCore/Modules/indexeddb/server/MemoryObjectStore.cpp 2019-04-03 17:00:36 UTC (rev 243806)
+++ trunk/Source/WebCore/Modules/indexeddb/server/MemoryObjectStore.cpp 2019-04-03 17:03:59 UTC (rev 243807)
@@ -310,7 +310,7 @@
for (auto& index : m_indexesByName.values()) {
IndexKey indexKey;
- generateIndexKeyForValue(UniqueIDBDatabase::databaseThreadExecState(), index->info(), jsValue, indexKey);
+ generateIndexKeyForValue(UniqueIDBDatabase::databaseThreadExecState(), index->info(), jsValue, indexKey, m_info.keyPath(), key);
if (indexKey.isNull())
continue;
@@ -344,7 +344,7 @@
return IDBError { };
IndexKey indexKey;
- generateIndexKeyForValue(UniqueIDBDatabase::databaseThreadExecState(), index.info(), jsValue, indexKey);
+ generateIndexKeyForValue(UniqueIDBDatabase::databaseThreadExecState(), index.info(), jsValue, indexKey, m_info.keyPath(), iterator.key);
if (indexKey.isNull())
continue;
@@ -407,7 +407,7 @@
void MemoryObjectStore::getAllRecords(const IDBKeyRangeData& keyRangeData, Optional<uint32_t> count, IndexedDB::GetAllType type, IDBGetAllResult& result) const
{
- result = { type };
+ result = { type, m_info.keyPath() };
uint32_t targetCount;
if (count && count.value())
@@ -424,11 +424,9 @@
range.lowerKey = key;
range.lowerOpen = true;
-
- if (type == IndexedDB::GetAllType::Keys)
- result.addKey(WTFMove(key));
- else
+ if (type == IndexedDB::GetAllType::Values)
result.addValue(valueForKey(key));
+ result.addKey(WTFMove(key));
++currentCount;
}
Modified: trunk/Source/WebCore/Modules/indexeddb/server/MemoryObjectStoreCursor.cpp (243806 => 243807)
--- trunk/Source/WebCore/Modules/indexeddb/server/MemoryObjectStoreCursor.cpp 2019-04-03 17:00:36 UTC (rev 243806)
+++ trunk/Source/WebCore/Modules/indexeddb/server/MemoryObjectStoreCursor.cpp 2019-04-03 17:03:59 UTC (rev 243807)
@@ -194,7 +194,7 @@
data = { m_currentPositionKey, m_currentPositionKey };
else {
IDBValue value = { m_objectStore.valueForKeyRange(m_currentPositionKey), { }, { }, { } };
- data = { m_currentPositionKey, m_currentPositionKey, WTFMove(value) };
+ data = { m_currentPositionKey, m_currentPositionKey, WTFMove(value), m_objectStore.info().keyPath() };
}
}
Modified: trunk/Source/WebCore/Modules/indexeddb/server/SQLiteIDBBackingStore.cpp (243806 => 243807)
--- trunk/Source/WebCore/Modules/indexeddb/server/SQLiteIDBBackingStore.cpp 2019-04-03 17:00:36 UTC (rev 243806)
+++ trunk/Source/WebCore/Modules/indexeddb/server/SQLiteIDBBackingStore.cpp 2019-04-03 17:03:59 UTC (rev 243807)
@@ -29,6 +29,7 @@
#if ENABLE(INDEXED_DATABASE)
#include "IDBBindingUtilities.h"
+#include "IDBCursorInfo.h"
#include "IDBGetAllRecordsData.h"
#include "IDBGetAllResult.h"
#include "IDBGetRecordData.h"
@@ -1752,7 +1753,9 @@
return IDBError { };
IndexKey indexKey;
- generateIndexKeyForValue(*m_globalObject->globalExec(), info, jsValue, indexKey);
+ auto* objectStoreInfo = infoForObjectStore(info.objectStoreIdentifier());
+ ASSERT(objectStoreInfo);
+ generateIndexKeyForValue(*m_globalObject->globalExec(), info, jsValue, indexKey, objectStoreInfo->keyPath(), key);
if (indexKey.isNull())
return IDBError { };
@@ -1772,7 +1775,7 @@
bool anyRecordsSucceeded = false;
for (auto& index : info.indexMap().values()) {
IndexKey indexKey;
- generateIndexKeyForValue(*m_globalObject->globalExec(), index, jsValue, indexKey);
+ generateIndexKeyForValue(*m_globalObject->globalExec(), index, jsValue, indexKey, info.keyPath(), key);
if (indexKey.isNull())
continue;
@@ -2004,12 +2007,12 @@
}
int64_t recordID = 0;
- ThreadSafeDataBuffer resultBuffer;
+ ThreadSafeDataBuffer keyResultBuffer, valueResultBuffer;
{
- static const char* const lowerOpenUpperOpen = "SELECT value, ROWID FROM Records WHERE objectStoreID = ? AND key > CAST(? AS TEXT) AND key < CAST(? AS TEXT) ORDER BY key;";
- static const char* const lowerOpenUpperClosed = "SELECT value, ROWID FROM Records WHERE objectStoreID = ? AND key > CAST(? AS TEXT) AND key <= CAST(? AS TEXT) ORDER BY key;";
- static const char* const lowerClosedUpperOpen = "SELECT value, ROWID FROM Records WHERE objectStoreID = ? AND key >= CAST(? AS TEXT) AND key < CAST(? AS TEXT) ORDER BY key;";
- static const char* const lowerClosedUpperClosed = "SELECT value, ROWID FROM Records WHERE objectStoreID = ? AND key >= CAST(? AS TEXT) AND key <= CAST(? AS TEXT) ORDER BY key;";
+ static const char* const lowerOpenUpperOpen = "SELECT key, value, ROWID FROM Records WHERE objectStoreID = ? AND key > CAST(? AS TEXT) AND key < CAST(? AS TEXT) ORDER BY key;";
+ static const char* const lowerOpenUpperClosed = "SELECT key, value, ROWID FROM Records WHERE objectStoreID = ? AND key > CAST(? AS TEXT) AND key <= CAST(? AS TEXT) ORDER BY key;";
+ static const char* const lowerClosedUpperOpen = "SELECT key, value, ROWID FROM Records WHERE objectStoreID = ? AND key >= CAST(? AS TEXT) AND key < CAST(? AS TEXT) ORDER BY key;";
+ static const char* const lowerClosedUpperClosed = "SELECT key, value, ROWID FROM Records WHERE objectStoreID = ? AND key >= CAST(? AS TEXT) AND key <= CAST(? AS TEXT) ORDER BY key;";
static const char* const lowerOpenUpperOpenKeyOnly = "SELECT key FROM Records WHERE objectStoreID = ? AND key > CAST(? AS TEXT) AND key < CAST(? AS TEXT) ORDER BY key;";
static const char* const lowerOpenUpperClosedKeyOnly = "SELECT key FROM Records WHERE objectStoreID = ? AND key > CAST(? AS TEXT) AND key <= CAST(? AS TEXT) ORDER BY key;";
@@ -2066,27 +2069,31 @@
return IDBError { UnknownError, "Error looking up record in object store by key range"_s };
}
- Vector<uint8_t> buffer;
- sql->getColumnBlobAsVector(0, buffer);
- resultBuffer = ThreadSafeDataBuffer::create(WTFMove(buffer));
+ Vector<uint8_t> keyBuffer;
+ sql->getColumnBlobAsVector(0, keyBuffer);
+ keyResultBuffer = ThreadSafeDataBuffer::create(WTFMove(keyBuffer));
- if (type == IDBGetRecordDataType::KeyAndValue)
- recordID = sql->getColumnInt64(1);
+ if (type == IDBGetRecordDataType::KeyAndValue) {
+ Vector<uint8_t> valueBuffer;
+ sql->getColumnBlobAsVector(1, valueBuffer);
+ valueResultBuffer = ThreadSafeDataBuffer::create(WTFMove(valueBuffer));
+ recordID = sql->getColumnInt64(2);
+ }
}
+ auto* keyVector = keyResultBuffer.data();
+ if (!keyVector) {
+ LOG_ERROR("Unable to deserialize key data from database for IDBObjectStore");
+ return IDBError { UnknownError, "Error extracting key data from database executing IDBObjectStore get"_s };
+ }
+
+ IDBKeyData keyData;
+ if (!deserializeIDBKeyData(keyVector->data(), keyVector->size(), keyData)) {
+ LOG_ERROR("Unable to deserialize key data from database for IDBObjectStore");
+ return IDBError { UnknownError, "Error extracting key data from database executing IDBObjectStore get"_s };
+ }
+
if (type == IDBGetRecordDataType::KeyOnly) {
- auto* vector = resultBuffer.data();
- if (!vector) {
- LOG_ERROR("Unable to deserialize key data from database for IDBObjectStore.getKey()");
- return IDBError { UnknownError, "Error extracting key data from database executing IDBObjectStore.getKey()"_s };
- }
-
- IDBKeyData keyData;
- if (!deserializeIDBKeyData(vector->data(), vector->size(), keyData)) {
- LOG_ERROR("Unable to deserialize key data from database for IDBObjectStore.getKey()");
- return IDBError { UnknownError, "Error extracting key data from database executing IDBObjectStore.getKey()"_s };
- }
-
resultValue = { keyData };
return IDBError { };
}
@@ -2100,7 +2107,9 @@
if (!error.isNull())
return error;
- resultValue = { { resultBuffer, WTFMove(blobURLs), sessionID, WTFMove(blobFilePaths) } };
+ auto* objectStoreInfo = infoForObjectStore(objectStoreID);
+ ASSERT(objectStoreInfo);
+ resultValue = { keyData, { valueResultBuffer, WTFMove(blobURLs), sessionID, WTFMove(blobFilePaths) }, objectStoreInfo->keyPath()};
return IDBError { };
}
@@ -2115,10 +2124,10 @@
static const char* const lowerOpenUpperClosedKey = "SELECT key FROM Records WHERE objectStoreID = ? AND key > CAST(? AS TEXT) AND key <= CAST(? AS TEXT) ORDER BY key;";
static const char* const lowerClosedUpperOpenKey = "SELECT key FROM Records WHERE objectStoreID = ? AND key >= CAST(? AS TEXT) AND key < CAST(? AS TEXT) ORDER BY key;";
static const char* const lowerClosedUpperClosedKey = "SELECT key FROM Records WHERE objectStoreID = ? AND key >= CAST(? AS TEXT) AND key <= CAST(? AS TEXT) ORDER BY key;";
- static const char* const lowerOpenUpperOpenValue = "SELECT value, ROWID FROM Records WHERE objectStoreID = ? AND key > CAST(? AS TEXT) AND key < CAST(? AS TEXT) ORDER BY key;";
- static const char* const lowerOpenUpperClosedValue = "SELECT value, ROWID FROM Records WHERE objectStoreID = ? AND key > CAST(? AS TEXT) AND key <= CAST(? AS TEXT) ORDER BY key;";
- static const char* const lowerClosedUpperOpenValue = "SELECT value, ROWID FROM Records WHERE objectStoreID = ? AND key >= CAST(? AS TEXT) AND key < CAST(? AS TEXT) ORDER BY key;";
- static const char* const lowerClosedUpperClosedValue = "SELECT value, ROWID FROM Records WHERE objectStoreID = ? AND key >= CAST(? AS TEXT) AND key <= CAST(? AS TEXT) ORDER BY key;";
+ static const char* const lowerOpenUpperOpenValue = "SELECT key, value, ROWID FROM Records WHERE objectStoreID = ? AND key > CAST(? AS TEXT) AND key < CAST(? AS TEXT) ORDER BY key;";
+ static const char* const lowerOpenUpperClosedValue = "SELECT key, value, ROWID FROM Records WHERE objectStoreID = ? AND key > CAST(? AS TEXT) AND key <= CAST(? AS TEXT) ORDER BY key;";
+ static const char* const lowerClosedUpperOpenValue = "SELECT key, value, ROWID FROM Records WHERE objectStoreID = ? AND key >= CAST(? AS TEXT) AND key < CAST(? AS TEXT) ORDER BY key;";
+ static const char* const lowerClosedUpperClosedValue = "SELECT key, value, ROWID FROM Records WHERE objectStoreID = ? AND key >= CAST(? AS TEXT) AND key <= CAST(? AS TEXT) ORDER BY key;";
if (getAllRecordsData.getAllType == IndexedDB::GetAllType::Keys) {
if (getAllRecordsData.keyRangeData.lowerOpen) {
@@ -2183,7 +2192,9 @@
return IDBError { UnknownError, "Failed to look up record in object store by key range"_s };
}
- result = { getAllRecordsData.getAllType };
+ auto* objectStoreInfo = infoForObjectStore(getAllRecordsData.objectStoreIdentifier);
+ ASSERT(objectStoreInfo);
+ result = { getAllRecordsData.getAllType, objectStoreInfo->keyPath() };
uint32_t targetResults;
if (getAllRecordsData.count && getAllRecordsData.count.value())
@@ -2195,12 +2206,21 @@
uint32_t returnedResults = 0;
while (sqlResult == SQLITE_ROW && returnedResults < targetResults) {
+ Vector<uint8_t> keyBuffer;
+ IDBKeyData keyData;
+ sql->getColumnBlobAsVector(0, keyBuffer);
+ if (!deserializeIDBKeyData(keyBuffer.data(), keyBuffer.size(), keyData)) {
+ LOG_ERROR("Unable to deserialize key data from database while getting all records");
+ return IDBError { UnknownError, "Unable to deserialize key data while getting all records"_s };
+ }
+ result.addKey(WTFMove(keyData));
+
if (getAllRecordsData.getAllType == IndexedDB::GetAllType::Values) {
- Vector<uint8_t> buffer;
- sql->getColumnBlobAsVector(0, buffer);
- ThreadSafeDataBuffer resultBuffer = ThreadSafeDataBuffer::create(WTFMove(buffer));
+ Vector<uint8_t> valueBuffer;
+ sql->getColumnBlobAsVector(1, valueBuffer);
+ ThreadSafeDataBuffer valueResultBuffer = ThreadSafeDataBuffer::create(WTFMove(valueBuffer));
- auto recordID = sql->getColumnInt64(1);
+ auto recordID = sql->getColumnInt64(2);
ASSERT(recordID);
Vector<String> blobURLs, blobFilePaths;
@@ -2211,18 +2231,7 @@
if (!error.isNull())
return error;
- result.addValue({ resultBuffer, WTFMove(blobURLs), sessionID, WTFMove(blobFilePaths) });
- } else {
- Vector<uint8_t> keyData;
- IDBKeyData key;
- sql->getColumnBlobAsVector(0, keyData);
-
- if (!deserializeIDBKeyData(keyData.data(), keyData.size(), key)) {
- LOG_ERROR("Unable to deserialize key data from database while getting all key records");
- return IDBError { UnknownError, "Unable to deserialize key data while getting all key records"_s };
- }
-
- result.addKey(WTFMove(key));
+ result.addValue({ valueResultBuffer, WTFMove(blobURLs), sessionID, WTFMove(blobFilePaths) });
}
++returnedResults;
@@ -2263,16 +2272,18 @@
return IDBError { UnknownError, "Cursor failed while looking up index records in database"_s };
}
- result = { getAllRecordsData.getAllType };
+ auto* objectStoreInfo = infoForObjectStore(getAllRecordsData.objectStoreIdentifier);
+ ASSERT(objectStoreInfo);
+ result = { getAllRecordsData.getAllType, objectStoreInfo->keyPath() };
+
uint32_t currentCount = 0;
uint32_t targetCount = getAllRecordsData.count ? getAllRecordsData.count.value() : 0;
if (!targetCount)
targetCount = std::numeric_limits<uint32_t>::max();
while (!cursor->didComplete() && !cursor->didError() && currentCount < targetCount) {
- if (getAllRecordsData.getAllType == IndexedDB::GetAllType::Keys) {
- IDBKeyData keyCopy = cursor->currentPrimaryKey();
- result.addKey(WTFMove(keyCopy));
- } else
+ IDBKeyData keyCopy = cursor->currentPrimaryKey();
+ result.addKey(WTFMove(keyCopy));
+ if (getAllRecordsData.getAllType == IndexedDB::GetAllType::Values)
result.addValue(cursor->currentValue() ? *cursor->currentValue() : IDBValue());
++currentCount;
@@ -2319,8 +2330,11 @@
else {
if (type == IndexedDB::IndexRecordType::Key)
getResult = { cursor->currentPrimaryKey() };
- else
- getResult = { cursor->currentValue() ? *cursor->currentValue() : IDBValue(), cursor->currentPrimaryKey() };
+ else {
+ auto* objectStoreInfo = infoForObjectStore(objectStoreID);
+ ASSERT(objectStoreInfo);
+ getResult = { cursor->currentPrimaryKey(), cursor->currentPrimaryKey(), cursor->currentValue() ? *cursor->currentValue() : IDBValue(), objectStoreInfo->keyPath() };
+ }
}
return IDBError { };
@@ -2371,7 +2385,8 @@
return IDBError { };
}
- sql->getColumnBlobAsVector(1, keyVector);
+ Vector<uint8_t> valueVector;
+ sql->getColumnBlobAsVector(1, valueVector);
int64_t recordID = sql->getColumnInt64(2);
Vector<String> blobURLs, blobFilePaths;
@@ -2382,7 +2397,9 @@
if (!error.isNull())
return error;
- getResult = { { ThreadSafeDataBuffer::create(WTFMove(keyVector)), WTFMove(blobURLs), sessionID, WTFMove(blobFilePaths) }, objectStoreKey };
+ auto* objectStoreInfo = infoForObjectStore(objectStoreID);
+ ASSERT(objectStoreInfo);
+ getResult = { objectStoreKey, objectStoreKey, { ThreadSafeDataBuffer::create(WTFMove(valueVector)), WTFMove(blobURLs), sessionID, WTFMove(blobFilePaths) }, objectStoreInfo->keyPath() };
return IDBError { };
}
@@ -2547,7 +2564,9 @@
m_cursors.set(cursor->identifier(), cursor);
- cursor->currentData(result);
+ auto* objectStoreInfo = infoForObjectStore(info.objectStoreIdentifier());
+ ASSERT(objectStoreInfo);
+ cursor->currentData(result, objectStoreInfo->keyPath());
return IDBError { };
}
@@ -2590,7 +2609,9 @@
}
}
- cursor->currentData(result);
+ auto* objectStoreInfo = infoForObjectStore(cursor->objectStoreID());
+ ASSERT(objectStoreInfo);
+ cursor->currentData(result, objectStoreInfo->keyPath());
return IDBError { };
}
Modified: trunk/Source/WebCore/Modules/indexeddb/server/SQLiteIDBCursor.cpp (243806 => 243807)
--- trunk/Source/WebCore/Modules/indexeddb/server/SQLiteIDBCursor.cpp 2019-04-03 17:00:36 UTC (rev 243806)
+++ trunk/Source/WebCore/Modules/indexeddb/server/SQLiteIDBCursor.cpp 2019-04-03 17:03:59 UTC (rev 243807)
@@ -101,7 +101,7 @@
m_transaction->closeCursor(*this);
}
-void SQLiteIDBCursor::currentData(IDBGetResult& result)
+void SQLiteIDBCursor::currentData(IDBGetResult& result, const Optional<IDBKeyPath>& keyPath)
{
ASSERT(!m_fetchedRecords.isEmpty());
@@ -112,7 +112,7 @@
return;
}
- result = { currentRecord.record.key, currentRecord.record.primaryKey, currentRecord.record.value ? *currentRecord.record.value : IDBValue() };
+ result = { currentRecord.record.key, currentRecord.record.primaryKey, currentRecord.record.value ? *currentRecord.record.value : IDBValue(), keyPath};
}
static String buildIndexStatement(const IDBKeyRangeData& keyRange, IndexedDB::CursorDirection cursorDirection)
Modified: trunk/Source/WebCore/Modules/indexeddb/server/SQLiteIDBCursor.h (243806 => 243807)
--- trunk/Source/WebCore/Modules/indexeddb/server/SQLiteIDBCursor.h 2019-04-03 17:00:36 UTC (rev 243806)
+++ trunk/Source/WebCore/Modules/indexeddb/server/SQLiteIDBCursor.h 2019-04-03 17:03:59 UTC (rev 243807)
@@ -79,7 +79,7 @@
void objectStoreRecordsChanged();
- void currentData(IDBGetResult&);
+ void currentData(IDBGetResult&, const Optional<IDBKeyPath>&);
private:
bool establishStatement();
Modified: trunk/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.cpp (243806 => 243807)
--- trunk/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.cpp 2019-04-03 17:00:36 UTC (rev 243806)
+++ trunk/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.cpp 2019-04-03 17:03:59 UTC (rev 243807)
@@ -1251,35 +1251,6 @@
}
}
- // 3.4.1.2 Object Store Storage Operation
- // If ObjectStore has a key path and the key is autogenerated, then inject the key into the value
- // using steps to assign a key to a value using a key path.
- ThreadSafeDataBuffer injectedRecordValue;
- if (usedKeyIsGenerated && objectStoreInfo->keyPath()) {
- VM& vm = databaseThreadVM();
- JSLockHolder locker(vm);
- auto scope = DECLARE_THROW_SCOPE(vm);
-
- auto value = deserializeIDBValueToJSValue(databaseThreadExecState(), originalRecordValue.data());
- if (value.isUndefined()) {
- postDatabaseTaskReply(createCrossThreadTask(*this, &UniqueIDBDatabase::didPerformPutOrAdd, callbackIdentifier, IDBError(ConstraintError, "Unable to deserialize record value for record key injection"_s), usedKey));
- return;
- }
-
- if (!injectIDBKeyIntoScriptValue(databaseThreadExecState(), usedKey, value, objectStoreInfo->keyPath().value())) {
- postDatabaseTaskReply(createCrossThreadTask(*this, &UniqueIDBDatabase::didPerformPutOrAdd, callbackIdentifier, IDBError(ConstraintError, "Unable to inject record key into record value"_s), usedKey));
- return;
- }
-
- auto serializedValue = SerializedScriptValue::create(databaseThreadExecState(), value);
- if (UNLIKELY(scope.exception())) {
- postDatabaseTaskReply(createCrossThreadTask(*this, &UniqueIDBDatabase::didPerformPutOrAdd, callbackIdentifier, IDBError(ConstraintError, "Unable to serialize record value after injecting record key"_s), usedKey));
- return;
- }
-
- injectedRecordValue = ThreadSafeDataBuffer::copyVector(serializedValue->data());
- }
-
// 3.4.1 Object Store Storage Operation
// ...If a record already exists in store ...
// then remove the record from store using the steps for deleting records from an object store...
@@ -1290,10 +1261,7 @@
return;
}
- if (injectedRecordValue.data())
- error = m_backingStore->addRecord(transactionIdentifier, *objectStoreInfo, usedKey, { injectedRecordValue, originalRecordValue.blobURLs(), originalRecordValue.sessionID(), originalRecordValue.blobFilePaths() });
- else
- error = m_backingStore->addRecord(transactionIdentifier, *objectStoreInfo, usedKey, originalRecordValue);
+ error = m_backingStore->addRecord(transactionIdentifier, *objectStoreInfo, usedKey, originalRecordValue);
if (!error.isNull()) {
postDatabaseTaskReply(createCrossThreadTask(*this, &UniqueIDBDatabase::didPerformPutOrAdd, callbackIdentifier, error, usedKey));
Modified: trunk/Source/WebCore/Modules/indexeddb/shared/IDBResultData.cpp (243806 => 243807)
--- trunk/Source/WebCore/Modules/indexeddb/shared/IDBResultData.cpp 2019-04-03 17:00:36 UTC (rev 243806)
+++ trunk/Source/WebCore/Modules/indexeddb/shared/IDBResultData.cpp 2019-04-03 17:03:59 UTC (rev 243807)
@@ -233,6 +233,12 @@
return *m_getResult;
}
+IDBGetResult& IDBResultData::getResultRef()
+{
+ RELEASE_ASSERT(m_getResult);
+ return *m_getResult;
+}
+
const IDBGetAllResult& IDBResultData::getAllResult() const
{
RELEASE_ASSERT(m_getAllResult);
Modified: trunk/Source/WebCore/Modules/indexeddb/shared/IDBResultData.h (243806 => 243807)
--- trunk/Source/WebCore/Modules/indexeddb/shared/IDBResultData.h 2019-04-03 17:00:36 UTC (rev 243806)
+++ trunk/Source/WebCore/Modules/indexeddb/shared/IDBResultData.h 2019-04-03 17:03:59 UTC (rev 243807)
@@ -107,6 +107,7 @@
uint64_t resultInteger() const { return m_resultInteger; }
WEBCORE_EXPORT const IDBGetResult& getResult() const;
+ WEBCORE_EXPORT IDBGetResult& getResultRef();
WEBCORE_EXPORT const IDBGetAllResult& getAllResult() const;
WEBCORE_EXPORT IDBResultData();
Modified: trunk/Source/WebCore/bindings/js/IDBBindingUtilities.cpp (243806 => 243807)
--- trunk/Source/WebCore/bindings/js/IDBBindingUtilities.cpp 2019-04-03 17:00:36 UTC (rev 243806)
+++ trunk/Source/WebCore/bindings/js/IDBBindingUtilities.cpp 2019-04-03 17:03:59 UTC (rev 243807)
@@ -31,6 +31,7 @@
#include "IDBBindingUtilities.h"
+#include "ExceptionCode.h"
#include "IDBIndexInfo.h"
#include "IDBKey.h"
#include "IDBKeyData.h"
@@ -41,6 +42,7 @@
#include "JSDOMBinding.h"
#include "JSDOMConvertDate.h"
#include "JSDOMConvertNullable.h"
+#include "JSDOMExceptionHandling.h"
#include "JSFile.h"
#include "Logging.h"
#include "MessagePort.h"
@@ -324,6 +326,12 @@
if (!key)
return false;
+ // Do not set if object already has the correct property value.
+ auto jsKey = toJS(exec, *exec.lexicalGlobalObject(), key.get());
+ JSValue existingKey;
+ if (get(exec, parent, keyPathElements.last(), existingKey) && existingKey == jsKey)
+ return true;
+
if (!set(exec, parent, keyPathElements.last(), toJS(exec, *exec.lexicalGlobalObject(), key.get())))
return false;
@@ -411,9 +419,13 @@
return toJS(*state, *globalObject, keyData.maybeCreateIDBKey().get());
}
-static Vector<IDBKeyData> createKeyPathArray(ExecState& exec, JSValue value, const IDBIndexInfo& info)
+static Vector<IDBKeyData> createKeyPathArray(ExecState& exec, JSValue value, const IDBIndexInfo& info, Optional<IDBKeyPath> objectStoreKeyPath, const IDBKeyData& objectStoreKey)
{
auto visitor = WTF::makeVisitor([&](const String& string) -> Vector<IDBKeyData> {
+ // Value doesn't contain auto-generated key, so we need to manually add key if it is possibly auto-generated.
+ if (objectStoreKeyPath && WTF::holds_alternative<String>(objectStoreKeyPath.value()) && IDBKeyPath(string) == objectStoreKeyPath.value())
+ return { objectStoreKey };
+
auto idbKey = internalCreateIDBKeyFromScriptValueAndKeyPath(exec, value, string);
if (!idbKey)
return { };
@@ -428,10 +440,14 @@
}, [&](const Vector<String>& vector) -> Vector<IDBKeyData> {
Vector<IDBKeyData> keys;
for (auto& entry : vector) {
- auto key = internalCreateIDBKeyFromScriptValueAndKeyPath(exec, value, entry);
- if (!key || !key->isValid())
- return { };
- keys.append(key.get());
+ if (objectStoreKeyPath && WTF::holds_alternative<String>(objectStoreKeyPath.value()) && IDBKeyPath(entry) == objectStoreKeyPath.value())
+ keys.append(objectStoreKey);
+ else {
+ auto key = internalCreateIDBKeyFromScriptValueAndKeyPath(exec, value, entry);
+ if (!key || !key->isValid())
+ return { };
+ keys.append(key.get());
+ }
}
return keys;
});
@@ -439,10 +455,9 @@
return WTF::visit(visitor, info.keyPath());
}
-void generateIndexKeyForValue(ExecState& exec, const IDBIndexInfo& info, JSValue value, IndexKey& outKey)
+void generateIndexKeyForValue(ExecState& exec, const IDBIndexInfo& info, JSValue value, IndexKey& outKey, const Optional<IDBKeyPath>& objectStoreKeyPath, const IDBKeyData& objectStoreKey)
{
- auto keyDatas = createKeyPathArray(exec, value, info);
-
+ auto keyDatas = createKeyPathArray(exec, value, info, objectStoreKeyPath, objectStoreKey);
if (keyDatas.isEmpty())
return;
@@ -449,6 +464,22 @@
outKey = IndexKey(WTFMove(keyDatas));
}
+Optional<JSC::JSValue> deserializeIDBValueWithKeyInjection(ExecState& state, const IDBValue& value, const IDBKeyData& key, const Optional<IDBKeyPath>& keyPath)
+{
+ auto jsValue = deserializeIDBValueToJSValue(state, value);
+ if (jsValue.isUndefined() || !keyPath || !WTF::holds_alternative<String>(keyPath.value()) || !isIDBKeyPathValid(keyPath.value()))
+ return jsValue;
+
+ JSLockHolder locker(state.vm());
+ if (!injectIDBKeyIntoScriptValue(state, key, jsValue, keyPath.value())) {
+ auto throwScope = DECLARE_THROW_SCOPE(state.vm());
+ propagateException(state, throwScope, Exception(UnknownError, "Cannot inject key into script value"_s));
+ return WTF::nullopt;
+ }
+
+ return jsValue;
+}
+
} // namespace WebCore
#endif // ENABLE(INDEXED_DATABASE)
Modified: trunk/Source/WebCore/bindings/js/IDBBindingUtilities.h (243806 => 243807)
--- trunk/Source/WebCore/bindings/js/IDBBindingUtilities.h 2019-04-03 17:00:36 UTC (rev 243806)
+++ trunk/Source/WebCore/bindings/js/IDBBindingUtilities.h 2019-04-03 17:03:59 UTC (rev 243807)
@@ -50,15 +50,17 @@
bool canInjectIDBKeyIntoScriptValue(JSC::ExecState&, const JSC::JSValue&, const IDBKeyPath&);
bool injectIDBKeyIntoScriptValue(JSC::ExecState&, const IDBKeyData&, JSC::JSValue, const IDBKeyPath&);
-void generateIndexKeyForValue(JSC::ExecState&, const IDBIndexInfo&, JSC::JSValue, IndexKey& outKey);
+void generateIndexKeyForValue(JSC::ExecState&, const IDBIndexInfo&, JSC::JSValue, IndexKey& outKey, const Optional<IDBKeyPath>&, const IDBKeyData&);
Ref<IDBKey> scriptValueToIDBKey(JSC::ExecState&, const JSC::JSValue&);
+JSC::JSValue deserializeIDBValueToJSValue(JSC::ExecState&, const IDBValue&, Vector<std::pair<String, String>>&);
JSC::JSValue deserializeIDBValueToJSValue(JSC::ExecState&, const IDBValue&);
JSC::JSValue toJS(JSC::ExecState*, JSDOMGlobalObject*, const IDBValue&);
JSC::JSValue toJS(JSC::ExecState&, JSC::JSGlobalObject&, IDBKey*);
JSC::JSValue toJS(JSC::ExecState*, JSDOMGlobalObject*, const IDBKeyData&);
+Optional<JSC::JSValue> deserializeIDBValueWithKeyInjection(JSC::ExecState&, const IDBValue&, const IDBKeyData&, const Optional<IDBKeyPath>&);
}
#endif // ENABLE(INDEXED_DATABASE)
Modified: trunk/Source/WebCore/bindings/js/JSIDBCursorWithValueCustom.cpp (243806 => 243807)
--- trunk/Source/WebCore/bindings/js/JSIDBCursorWithValueCustom.cpp 2019-04-03 17:00:36 UTC (rev 243806)
+++ trunk/Source/WebCore/bindings/js/JSIDBCursorWithValueCustom.cpp 2019-04-03 17:03:59 UTC (rev 243807)
@@ -38,7 +38,8 @@
JSC::JSValue JSIDBCursorWithValue::value(JSC::ExecState& state) const
{
return cachedPropertyValue(state, *this, wrapped().valueWrapper(), [&] {
- return deserializeIDBValueToJSValue(state, wrapped().value());
+ auto result = deserializeIDBValueWithKeyInjection(state, wrapped().value(), wrapped().primaryKey(), wrapped().primaryKeyPath());
+ return result ? result.value() : jsNull();
});
}
Modified: trunk/Source/WebCore/bindings/js/JSIDBRequestCustom.cpp (243806 => 243807)
--- trunk/Source/WebCore/bindings/js/JSIDBRequestCustom.cpp 2019-04-03 17:00:36 UTC (rev 243806)
+++ trunk/Source/WebCore/bindings/js/JSIDBRequestCustom.cpp 2019-04-03 17:03:59 UTC (rev 243807)
@@ -57,10 +57,21 @@
return toJS<IDLIDBKeyData>(state, *jsCast<JSDOMGlobalObject*>(state.lexicalGlobalObject()), keyData);
}, [&state] (Vector<IDBKeyData> keyDatas) {
return toJS<IDLSequence<IDLIDBKeyData>>(state, *jsCast<JSDOMGlobalObject*>(state.lexicalGlobalObject()), keyDatas);
- }, [&state] (IDBValue value) {
- return toJS<IDLIDBValue>(state, *jsCast<JSDOMGlobalObject*>(state.lexicalGlobalObject()), value);
- }, [&state] (Vector<IDBValue> values) {
- return toJS<IDLSequence<IDLIDBValue>>(state, *jsCast<JSDOMGlobalObject*>(state.lexicalGlobalObject()), values);
+ }, [&state] (IDBGetResult getResult) {
+ auto result = deserializeIDBValueWithKeyInjection(state, getResult.value(), getResult.keyData(), getResult.keyPath());
+ return result ? result.value() : jsNull();
+ }, [&state] (IDBGetAllResult getAllResult) {
+ auto& keys = getAllResult.keys();
+ auto& values = getAllResult.values();
+ auto& keyPath = getAllResult.keyPath();
+ Vector<JSC::JSValue> results;
+ for (unsigned i = 0; i < values.size(); i ++) {
+ auto result = deserializeIDBValueWithKeyInjection(state, values[i], keys[i], keyPath);
+ if (!result)
+ return jsNull();
+ results.append(result.value());
+ }
+ return JSValue(JSC::constructArray(&state, nullptr, state.lexicalGlobalObject(), results.data(), results.size()));
}, [] (uint64_t number) {
return toJS<IDLUnsignedLongLong>(number);
}, [] (IDBRequest::NullResultType other) {