Changeset 244436 in webkit
- Timestamp:
- Apr 18, 2019 2:45:41 PM (5 years ago)
- Location:
- trunk
- Files:
-
- 3 added
- 30 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r244430 r244436 1 2019-04-18 Sihui Liu <sihui_liu@apple.com> 2 3 Blob type cannot be stored correctly in IDB when IDBObjectStore has autoIncrement and keyPath options 4 https://bugs.webkit.org/show_bug.cgi?id=196128 5 <rdar://problem/49562115> 6 7 Reviewed by Geoffrey Garen. 8 9 * storage/indexeddb/modern/objectstore-autoincrement-types-expected.txt: Added. 10 * storage/indexeddb/modern/objectstore-autoincrement-types.html: Added. 11 * storage/indexeddb/modern/resources/objectstore-autoincrement-types.js: Added. 12 (prepareDatabase.event.target.onsuccess): 13 (prepareDatabase): 14 (compare): 15 (runGetTest): 16 (runGetAllTest): 17 (get store): 18 (testSteps): 19 1 20 2019-04-18 Timothy Hatcher <timothy@apple.com> 2 21 -
trunk/LayoutTests/imported/w3c/ChangeLog
r244423 r244436 1 2019-04-18 Sihui Liu <sihui_liu@apple.com> 2 3 Blob type cannot be stored correctly in IDB when IDBObjectStore has autoIncrement and keyPath options 4 https://bugs.webkit.org/show_bug.cgi?id=196128 5 <rdar://problem/49562115> 6 7 Reviewed by Geoffrey Garen. 8 9 Updated test expectations to PASS. 10 11 * web-platform-tests/IndexedDB/nested-cloning-large-expected.txt: 12 * web-platform-tests/IndexedDB/nested-cloning-large-multiple-expected.txt: 13 * web-platform-tests/IndexedDB/nested-cloning-small-expected.txt: 14 1 15 2019-04-18 Antoine Quint <graouts@apple.com> 2 16 -
trunk/LayoutTests/imported/w3c/web-platform-tests/IndexedDB/nested-cloning-large-expected.txt
r243910 r244436 2 2 PASS large typed array 3 3 PASS blob with large typed array 4 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]" 4 PASS blob with large typed array with key generator 5 5 PASS array of blobs and large typed arrays 6 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]" 6 PASS array of blobs and large typed arrays with key generator 7 7 PASS object with blobs and large typed arrays 8 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]" 8 PASS object with blobs and large typed arrays with key generator 9 9 -
trunk/LayoutTests/imported/w3c/web-platform-tests/IndexedDB/nested-cloning-large-multiple-expected.txt
r243910 r244436 1 1 2 2 PASS multiple requests of objects with blobs and large typed arrays 3 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]" 3 PASS multiple requests of objects with blobs and large typed arrays with key generator 4 4 -
trunk/LayoutTests/imported/w3c/web-platform-tests/IndexedDB/nested-cloning-small-expected.txt
r243910 r244436 3 3 PASS blob 4 4 PASS blob with small typed array 5 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]" 5 PASS blob with small typed array with key generator 6 6 PASS blob array 7 FAIL blob array with key generator assert_equals: IndexedDB result class should match put() argument expected "[object Blob]" but got "[object Null]" 7 PASS blob array with key generator 8 8 PASS array of blobs and small typed arrays 9 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]" 9 PASS array of blobs and small typed arrays with key generator 10 10 -
trunk/Source/WebCore/ChangeLog
r244434 r244436 1 2019-04-18 Sihui Liu <sihui_liu@apple.com> 2 3 Blob type cannot be stored correctly in IDB when IDBObjectStore has autoIncrement and keyPath options 4 https://bugs.webkit.org/show_bug.cgi?id=196128 5 <rdar://problem/49562115> 6 7 Reviewed by Geoffrey Garen. 8 9 If a key is auto-generated, it should become a property of the value object. Network process would perform the 10 key injection by deserializing IDBValue into script value, setting the property, serializing the result and 11 storing it in a database record. But network process does not have a JSDOMGlobalObject, so it would fail to 12 deserialize types including Blob and File. 13 14 To solve this issue, we move the key injection to web process and let network process store the original value 15 it gets. In this case, when web process asks for some value, network process should return key, value and key 16 path so that web process can decide whether it should perform a key injection before returning the result. Note 17 that the auto-generated key would always be stored as the key in a ObjectStore record. 18 19 Test: storage/indexeddb/modern/objectstore-autoincrement-types.html 20 21 * Modules/indexeddb/IDBCursor.cpp: 22 (WebCore::IDBCursor::setGetResult): 23 * Modules/indexeddb/IDBCursor.h: 24 (WebCore::IDBCursor::primaryKeyPath): 25 * Modules/indexeddb/IDBGetAllResult.cpp: 26 (WebCore::IDBGetAllResult::isolatedCopy): 27 (WebCore::IDBGetAllResult::addKey): 28 (WebCore::IDBGetAllResult::addValue): 29 (WebCore::IDBGetAllResult::keys const): 30 (WebCore::IDBGetAllResult::values const): 31 (WebCore::IDBGetAllResult::allBlobFilePaths const): 32 (WebCore::isolatedCopyOfVariant): Deleted. 33 34 * Modules/indexeddb/IDBGetAllResult.h: Introduce an IDBKeyPath parameter. Also replace Variant with two Vectors, 35 because we only needed to store either key or value before, and now the stored value could be incomplete. 36 (WebCore::IDBGetAllResult::IDBGetAllResult): 37 (WebCore::IDBGetAllResult::keyPath const): 38 (WebCore::IDBGetAllResult::encode const): 39 (WebCore::IDBGetAllResult::decode): 40 41 * Modules/indexeddb/IDBGetResult.cpp: 42 (WebCore::IDBGetResult::setValue): 43 * Modules/indexeddb/IDBGetResult.h: 44 (WebCore::IDBGetResult::IDBGetResult): 45 (WebCore::IDBGetResult::keyPath const): 46 * Modules/indexeddb/IDBRequest.cpp: 47 (WebCore::IDBRequest::setResult): 48 (WebCore::IDBRequest::setResultToStructuredClone): 49 * Modules/indexeddb/IDBRequest.h: 50 * Modules/indexeddb/IDBTransaction.cpp: 51 (WebCore::IDBTransaction::didGetAllRecordsOnServer): 52 (WebCore::IDBTransaction::didGetRecordOnServer): 53 * Modules/indexeddb/server/MemoryIDBBackingStore.cpp: 54 (WebCore::IDBServer::MemoryIDBBackingStore::getRecord): 55 * Modules/indexeddb/server/MemoryIndex.cpp: 56 (WebCore::IDBServer::MemoryIndex::getResultForKeyRange const): 57 (WebCore::IDBServer::MemoryIndex::getAllRecords const): 58 * Modules/indexeddb/server/MemoryIndexCursor.cpp: 59 (WebCore::IDBServer::MemoryIndexCursor::currentData): 60 * Modules/indexeddb/server/MemoryObjectStore.cpp: 61 (WebCore::IDBServer::MemoryObjectStore::updateIndexesForPutRecord): 62 (WebCore::IDBServer::MemoryObjectStore::populateIndexWithExistingRecords): 63 (WebCore::IDBServer::MemoryObjectStore::getAllRecords const): 64 * Modules/indexeddb/server/MemoryObjectStoreCursor.cpp: 65 (WebCore::IDBServer::MemoryObjectStoreCursor::currentData): 66 * Modules/indexeddb/server/SQLiteIDBBackingStore.cpp: 67 (WebCore::IDBServer::SQLiteIDBBackingStore::updateOneIndexForAddRecord): 68 (WebCore::IDBServer::SQLiteIDBBackingStore::updateAllIndexesForAddRecord): 69 (WebCore::IDBServer::SQLiteIDBBackingStore::getRecord): 70 (WebCore::IDBServer::SQLiteIDBBackingStore::cachedStatementForGetAllObjectStoreRecords): 71 (WebCore::IDBServer::SQLiteIDBBackingStore::getAllObjectStoreRecords): 72 (WebCore::IDBServer::SQLiteIDBBackingStore::getAllIndexRecords): 73 (WebCore::IDBServer::SQLiteIDBBackingStore::getIndexRecord): 74 (WebCore::IDBServer::SQLiteIDBBackingStore::uncheckedGetIndexRecordForOneKey): 75 (WebCore::IDBServer::SQLiteIDBBackingStore::openCursor): 76 (WebCore::IDBServer::SQLiteIDBBackingStore::iterateCursor): 77 * Modules/indexeddb/server/SQLiteIDBCursor.cpp: 78 (WebCore::IDBServer::SQLiteIDBCursor::currentData): 79 * Modules/indexeddb/server/SQLiteIDBCursor.h: 80 * Modules/indexeddb/server/UniqueIDBDatabase.cpp: 81 82 (WebCore::IDBServer::UniqueIDBDatabase::performPutOrAdd): Remove the key injection from network process. 83 UniqueIDBDatabase stores any value it gets from IDBClient. 84 85 * Modules/indexeddb/shared/IDBResultData.cpp: 86 (WebCore::IDBResultData::getResultRef): 87 * Modules/indexeddb/shared/IDBResultData.h: 88 89 * bindings/js/IDBBindingUtilities.cpp: 90 (WebCore::injectIDBKeyIntoScriptValue): If property is read-only, set would fail and injectKeyIntoResult would 91 return null, but we expect it to return result as long as the property value is the same as target. Therefore, 92 we can add an early return here. 93 94 (WebCore::createKeyPathArray): 95 (WebCore::generateIndexKeyForValue): We used to generate IndexKey from value stored in database but now the 96 value gets stored does not include auto-generated key, as we remove the key injection from network process. In 97 this case if the IDBIndex has the same key path as the auto-generated key, IndexKey would be failed to create 98 for it cannot extract auto-generated key from value. Since the auto-generated key would always be the key in 99 database record, we could use value of that key when we find a match in key path. 100 101 (WebCore::deserializeIDBValueWithKeyInjection): If the key path in the result is single entry, the key is 102 probably auto-generated, so we could inject the result key into the result value unconditionally. 103 104 * bindings/js/IDBBindingUtilities.h: 105 * bindings/js/JSIDBCursorWithValueCustom.cpp: 106 (WebCore::JSIDBCursorWithValue::value const): 107 * bindings/js/JSIDBRequestCustom.cpp: 108 (WebCore::JSIDBRequest::result const): 109 1 110 2019-04-18 Zalan Bujtas <zalan@apple.com> 2 111 -
trunk/Source/WebCore/Modules/indexeddb/IDBCursor.cpp
r243910 r244436 345 345 m_primaryKey = m_primaryKeyData.maybeCreateIDBKey(); 346 346 347 if (isKeyCursorWithValue()) 347 if (isKeyCursorWithValue()) { 348 348 m_value = getResult.value(); 349 m_keyPath = getResult.keyPath(); 350 } 349 351 350 352 m_gotValue = true; -
trunk/Source/WebCore/Modules/indexeddb/IDBCursor.h
r244115 r244436 31 31 #include "IDBCursorDirection.h" 32 32 #include "IDBCursorInfo.h" 33 #include "IDBKeyPath.h" 33 34 #include "IDBRequest.h" 34 35 #include "IDBValue.h" … … 61 62 IDBKey* primaryKey() { return m_primaryKey.get(); }; 62 63 IDBValue value() { return m_value; }; 64 const Optional<IDBKeyPath>& primaryKeyPath() { return m_keyPath; }; 63 65 JSValueInWrappedObject& keyWrapper() { return m_keyWrapper; } 64 66 JSValueInWrappedObject& primaryKeyWrapper() { return m_primaryKeyWrapper; } … … 107 109 IDBKeyData m_primaryKeyData; 108 110 IDBValue m_value; 111 Optional<IDBKeyPath> m_keyPath; 109 112 110 113 JSValueInWrappedObject m_keyWrapper; -
trunk/Source/WebCore/Modules/indexeddb/IDBGetAllResult.cpp
r243910 r244436 29 29 #if ENABLE(INDEXED_DATABASE) 30 30 31 #include <wtf/CrossThreadCopier.h> 31 32 #include <wtf/HashSet.h> 32 33 33 34 namespace WebCore { 34 35 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)36 {37 target = Vector<T>();38 auto& sourceVector = WTF::get<Vector<T>>(source);39 auto& targetVector = WTF::get<Vector<T>>(target);40 targetVector.reserveInitialCapacity(sourceVector.size());41 for (auto& element : sourceVector)42 targetVector.uncheckedAppend(element.isolatedCopy());43 }44 35 45 36 IDBGetAllResult::IDBGetAllResult(const IDBGetAllResult& that, IsolatedCopyTag) … … 56 47 { 57 48 destination.m_type = source.m_type; 58 59 if (WTF::holds_alternative<std::nullptr_t>(source.m_results)) 60 return; 61 62 switch (source.m_type) { 63 case IndexedDB::GetAllType::Keys: 64 isolatedCopyOfVariant<IDBKeyData>(source.m_results, destination.m_results); 65 break; 66 case IndexedDB::GetAllType::Values: 67 isolatedCopyOfVariant<IDBValue>(source.m_results, destination.m_results); 68 break; 69 } 49 destination.m_keys = crossThreadCopy(source.m_keys); 50 destination.m_values = crossThreadCopy(source.m_values); 51 destination.m_keyPath = WebCore::isolatedCopy(source.m_keyPath); 70 52 } 71 53 72 54 void IDBGetAllResult::addKey(IDBKeyData&& key) 73 55 { 74 ASSERT(m_type == IndexedDB::GetAllType::Keys); 75 ASSERT(WTF::holds_alternative<Vector<IDBKeyData>>(m_results)); 76 WTF::get<Vector<IDBKeyData>>(m_results).append(WTFMove(key)); 56 m_keys.append(WTFMove(key)); 77 57 } 78 58 79 59 void IDBGetAllResult::addValue(IDBValue&& value) 80 60 { 81 ASSERT(m_type == IndexedDB::GetAllType::Values); 82 ASSERT(WTF::holds_alternative<Vector<IDBValue>>(m_results)); 83 WTF::get<Vector<IDBValue>>(m_results).append(WTFMove(value)); 61 m_values.append(WTFMove(value)); 84 62 } 85 63 86 64 const Vector<IDBKeyData>& IDBGetAllResult::keys() const 87 65 { 88 ASSERT(m_type == IndexedDB::GetAllType::Keys); 89 ASSERT(WTF::holds_alternative<Vector<IDBKeyData>>(m_results)); 90 return WTF::get<Vector<IDBKeyData>>(m_results); 66 return m_keys; 91 67 } 92 68 93 69 const Vector<IDBValue>& IDBGetAllResult::values() const 94 70 { 95 ASSERT(m_type == IndexedDB::GetAllType::Values); 96 ASSERT(WTF::holds_alternative<Vector<IDBValue>>(m_results)); 97 return WTF::get<Vector<IDBValue>>(m_results); 71 return m_values; 98 72 } 99 73 … … 103 77 104 78 HashSet<String> pathSet; 105 for (auto& value : WTF::get<Vector<IDBValue>>(m_results)) {79 for (auto& value : m_values) { 106 80 for (auto& path : value.blobFilePaths()) 107 81 pathSet.add(path); -
trunk/Source/WebCore/Modules/indexeddb/IDBGetAllResult.h
r243910 r244436 29 29 30 30 #include "IDBKeyData.h" 31 #include "IDBKeyPath.h" 31 32 #include "IDBValue.h" 32 33 #include "IndexedDB.h" … … 43 44 } 44 45 45 IDBGetAllResult(IndexedDB::GetAllType type )46 IDBGetAllResult(IndexedDB::GetAllType type, const Optional<IDBKeyPath>& keyPath) 46 47 : m_type(type) 48 , m_keyPath(keyPath) 47 49 { 48 switch (m_type) {49 case IndexedDB::GetAllType::Keys:50 m_results = Vector<IDBKeyData>();51 break;52 case IndexedDB::GetAllType::Values:53 m_results = Vector<IDBValue>();54 break;55 }56 50 } 57 51 … … 61 55 62 56 IndexedDB::GetAllType type() const { return m_type; } 57 const Optional<IDBKeyPath>& keyPath() const { return m_keyPath; } 63 58 const Vector<IDBKeyData>& keys() const; 64 59 const Vector<IDBValue>& values() const; … … 76 71 77 72 IndexedDB::GetAllType m_type { IndexedDB::GetAllType::Keys }; 78 WTF::Variant<Vector<IDBKeyData>, Vector<IDBValue>, std::nullptr_t> m_results { nullptr }; 73 Vector<IDBKeyData> m_keys; 74 Vector<IDBValue> m_values; 75 Optional<IDBKeyPath> m_keyPath; 79 76 }; 80 77 … … 82 79 void IDBGetAllResult::encode(Encoder& encoder) const 83 80 { 84 encoder << m_type << static_cast<uint64_t>(m_results.index()); 85 86 switch (m_results.index()) { 87 case 0: 88 encoder << WTF::get<Vector<IDBKeyData>>(m_results); 89 break; 90 case 1: 91 encoder << WTF::get<Vector<IDBValue>>(m_results); 92 break; 93 case 2: 94 break; 95 default: 96 RELEASE_ASSERT_NOT_REACHED(); 97 } 81 encoder << m_type << m_keys << m_values << m_keyPath; 98 82 } 99 83 … … 104 88 return false; 105 89 106 uint64_t index; 107 if (!decoder.decode(index)) 90 if (!decoder.decode(result.m_keys)) 108 91 return false; 109 92 110 switch (index) { 111 case 0: { 112 result.m_results = Vector<IDBKeyData>(); 113 if (!decoder.decode(WTF::get<Vector<IDBKeyData>>(result.m_results))) 114 return false; 115 break; 116 } 117 case 1: { 118 result.m_results = Vector<IDBValue>(); 119 Optional<Vector<IDBValue>> optional; 120 decoder >> optional; 121 if (!optional) 122 return false; 123 WTF::get<Vector<IDBValue>>(result.m_results) = WTFMove(*optional); 124 break; 125 } 126 case 2: 127 result.m_results = nullptr; 128 break; 129 default: 130 RELEASE_ASSERT_NOT_REACHED(); 131 } 93 if (!decoder.decode(result.m_values)) 94 return false; 95 96 if (!decoder.decode(result.m_keyPath)) 97 return false; 132 98 133 99 return true; -
trunk/Source/WebCore/Modules/indexeddb/IDBGetResult.cpp
r243910 r244436 58 58 } 59 59 60 void IDBGetResult::setValue(IDBValue&& value) 61 { 62 m_value = WTFMove(value); 63 } 64 60 65 } // namespace WebCore 61 66 -
trunk/Source/WebCore/Modules/indexeddb/IDBGetResult.h
r243910 r244436 44 44 } 45 45 46 IDBGetResult(const IDBValue& value, const IDBKeyData& currentPrimaryKey)47 : m_value(value)48 , m_primaryKeyData(currentPrimaryKey)49 {50 }51 52 IDBGetResult(const ThreadSafeDataBuffer& buffer)53 : m_value(buffer)54 {55 }56 57 IDBGetResult(IDBValue&& buffer)58 : m_value(WTFMove(buffer))59 {60 }61 62 IDBGetResult(IDBKey& key)63 : m_keyData(&key)64 {65 }66 67 46 IDBGetResult(const IDBKeyData& keyData) 68 47 : m_keyData(keyData) 69 48 { 70 }71 72 IDBGetResult(SharedBuffer* buffer, IDBKey& key, const IDBKeyPath& path)73 : m_keyData(&key)74 , m_keyPath(path)75 {76 if (buffer)77 dataFromBuffer(*buffer);78 49 } 79 50 … … 84 55 } 85 56 86 IDBGetResult(const IDBKeyData& keyData, const IDBKeyData& primaryKeyData, IDBValue&& value) 57 IDBGetResult(const IDBKeyData& keyData, const ThreadSafeDataBuffer& buffer, const Optional<IDBKeyPath>& keyPath) 58 : m_value(buffer) 59 , m_keyData(keyData) 60 , m_keyPath(keyPath) 61 { 62 } 63 64 IDBGetResult(const IDBKeyData& keyData, IDBValue&& value, const Optional<IDBKeyPath>& keyPath) 65 : m_value(WTFMove(value)) 66 , m_keyData(keyData) 67 , m_keyPath(keyPath) 68 { 69 } 70 71 IDBGetResult(const IDBKeyData& keyData, const IDBKeyData& primaryKeyData, IDBValue&& value, const Optional<IDBKeyPath>& keyPath) 87 72 : m_value(WTFMove(value)) 88 73 , m_keyData(keyData) 89 74 , m_primaryKeyData(primaryKeyData) 90 { 91 } 92 93 IDBGetResult(const IDBKeyData& keyData, const IDBKeyData& primaryKeyData, const IDBValue& value) 94 : m_value(value) 95 , m_keyData(keyData) 96 , m_primaryKeyData(primaryKeyData) 75 , m_keyPath(keyPath) 97 76 { 98 77 } … … 103 82 IDBGetResult isolatedCopy() const; 104 83 84 void setValue(IDBValue&&); 85 105 86 const IDBValue& value() const { return m_value; } 106 87 const IDBKeyData& keyData() const { return m_keyData; } 107 88 const IDBKeyData& primaryKeyData() const { return m_primaryKeyData; } 108 const IDBKeyPath& keyPath() const { return m_keyPath; }89 const Optional<IDBKeyPath>& keyPath() const { return m_keyPath; } 109 90 bool isDefined() const { return m_isDefined; } 110 91 … … 120 101 IDBKeyData m_keyData; 121 102 IDBKeyData m_primaryKeyData; 122 IDBKeyPathm_keyPath;103 Optional<IDBKeyPath> m_keyPath; 123 104 bool m_isDefined { true }; 124 105 }; -
trunk/Source/WebCore/Modules/indexeddb/IDBRequest.cpp
r243910 r244436 395 395 } 396 396 397 void IDBRequest::setResult(const Vector<IDBValue>& values)398 { 399 ASSERT(&originThread() == &Thread::current()); 400 401 auto* context = scriptExecutionContext(); 402 if (!context) 403 return; 404 405 VM& vm = context->vm(); 406 JSLockHolder lock(vm); 407 m_result = values;397 void IDBRequest::setResult(const IDBGetAllResult& result) 398 { 399 ASSERT(&originThread() == &Thread::current()); 400 401 auto* context = scriptExecutionContext(); 402 if (!context) 403 return; 404 405 VM& vm = context->vm(); 406 JSLockHolder lock(vm); 407 m_result = result; 408 408 m_resultWrapper = { }; 409 409 } … … 423 423 } 424 424 425 void IDBRequest::setResultToStructuredClone(const IDB Value& value)425 void IDBRequest::setResultToStructuredClone(const IDBGetResult& result) 426 426 { 427 427 ASSERT(&originThread() == &Thread::current()); … … 435 435 VM& vm = context->vm(); 436 436 JSLockHolder lock(vm); 437 m_result = value;437 m_result = result; 438 438 m_resultWrapper = { }; 439 439 } -
trunk/Source/WebCore/Modules/indexeddb/IDBRequest.h
r243910 r244436 32 32 #include "IDBActiveDOMObject.h" 33 33 #include "IDBError.h" 34 #include "IDBGetAllResult.h" 35 #include "IDBGetResult.h" 34 36 #include "IDBKeyData.h" 35 37 #include "IDBResourceIdentifier.h" … … 77 79 virtual ~IDBRequest(); 78 80 79 using Result = Variant<RefPtr<IDBCursor>, RefPtr<IDBDatabase>, IDBKeyData, Vector<IDBKeyData>, IDB Value, Vector<IDBValue>, uint64_t, NullResultType>;81 using Result = Variant<RefPtr<IDBCursor>, RefPtr<IDBDatabase>, IDBKeyData, Vector<IDBKeyData>, IDBGetResult, IDBGetAllResult, uint64_t, NullResultType>; 80 82 ExceptionOr<Result> result() const; 81 83 JSValueInWrappedObject& resultWrapper() { return m_resultWrapper; } … … 108 110 void setResult(const IDBKeyData&); 109 111 void setResult(const Vector<IDBKeyData>&); 110 void setResult(const Vector<IDBValue>&); 112 void setResultToStructuredClone(const IDBGetResult&); 113 void setResult(const IDBGetAllResult&); 111 114 void setResult(uint64_t); 112 void setResultToStructuredClone(const IDBValue&);113 115 void setResultToUndefined(); 114 116 -
trunk/Source/WebCore/Modules/indexeddb/IDBTransaction.cpp
r243910 r244436 990 990 break; 991 991 case IndexedDB::GetAllType::Values: 992 request.setResult(getAllResult .values());992 request.setResult(getAllResult); 993 993 break; 994 994 } … … 1094 1094 } else { 1095 1095 if (resultData.getResult().value().data().data()) 1096 request.setResultToStructuredClone(resultData.getResult() .value());1096 request.setResultToStructuredClone(resultData.getResult()); 1097 1097 else 1098 1098 request.setResultToUndefined(); -
trunk/Source/WebCore/Modules/indexeddb/server/MemoryIDBBackingStore.cpp
r243910 r244436 364 364 365 365 switch (type) { 366 case IDBGetRecordDataType::KeyAndValue: 367 outValue = objectStore->valueForKeyRange(range); 366 case IDBGetRecordDataType::KeyAndValue: { 367 auto key = objectStore->lowestKeyWithRecordInRange(range); 368 outValue = { key, key.isNull() ? ThreadSafeDataBuffer() : objectStore->valueForKey(key), objectStore->info().keyPath() }; 368 369 break; 370 } 369 371 case IDBGetRecordDataType::KeyOnly: 370 372 outValue = objectStore->lowestKeyWithRecordInRange(range); -
trunk/Source/WebCore/Modules/indexeddb/server/MemoryIndex.cpp
r243910 r244436 127 127 return { }; 128 128 129 return type == IndexedDB::IndexRecordType::Key ? IDBGetResult(*keyValue) : IDBGetResult( m_objectStore.valueForKeyRange(*keyValue));129 return type == IndexedDB::IndexRecordType::Key ? IDBGetResult(*keyValue) : IDBGetResult(*keyValue, m_objectStore.valueForKeyRange(*keyValue), m_objectStore.info().keyPath()); 130 130 } 131 131 … … 157 157 LOG(IndexedDB, "MemoryIndex::getAllRecords"); 158 158 159 result = { type };159 result = { type, m_objectStore.info().keyPath() }; 160 160 161 161 if (!m_records) … … 180 180 auto allValues = m_records->allValuesForKey(key, targetCount - currentCount); 181 181 for (auto& keyValue : allValues) { 182 if (type == IndexedDB::GetAllType::Keys) { 183 IDBKeyData keyCopy { keyValue }; 184 result.addKey(WTFMove(keyCopy)); 185 } else 182 result.addKey(IDBKeyData(keyValue)); 183 if (type == IndexedDB::GetAllType::Values) 186 184 result.addValue(m_objectStore.valueForKeyRange(keyValue)); 187 185 } -
trunk/Source/WebCore/Modules/indexeddb/server/MemoryIndexCursor.cpp
r243910 r244436 76 76 else { 77 77 IDBValue value = { m_index.objectStore().valueForKey(m_currentPrimaryKey), { }, { }, { } }; 78 getResult = { m_currentKey, m_currentPrimaryKey, WTFMove(value) };78 getResult = { m_currentKey, m_currentPrimaryKey, WTFMove(value), m_index.objectStore().info().keyPath() }; 79 79 } 80 80 } -
trunk/Source/WebCore/Modules/indexeddb/server/MemoryObjectStore.cpp
r243910 r244436 311 311 for (auto& index : m_indexesByName.values()) { 312 312 IndexKey indexKey; 313 generateIndexKeyForValue(UniqueIDBDatabase::databaseThreadExecState(), index->info(), jsValue, indexKey );313 generateIndexKeyForValue(UniqueIDBDatabase::databaseThreadExecState(), index->info(), jsValue, indexKey, m_info.keyPath(), key); 314 314 315 315 if (indexKey.isNull()) … … 345 345 346 346 IndexKey indexKey; 347 generateIndexKeyForValue(UniqueIDBDatabase::databaseThreadExecState(), index.info(), jsValue, indexKey );347 generateIndexKeyForValue(UniqueIDBDatabase::databaseThreadExecState(), index.info(), jsValue, indexKey, m_info.keyPath(), iterator.key); 348 348 349 349 if (indexKey.isNull()) … … 408 408 void MemoryObjectStore::getAllRecords(const IDBKeyRangeData& keyRangeData, Optional<uint32_t> count, IndexedDB::GetAllType type, IDBGetAllResult& result) const 409 409 { 410 result = { type };410 result = { type, m_info.keyPath() }; 411 411 412 412 uint32_t targetCount; … … 425 425 range.lowerKey = key; 426 426 range.lowerOpen = true; 427 428 if (type == IndexedDB::GetAllType::Keys) 429 result.addKey(WTFMove(key)); 430 else 427 if (type == IndexedDB::GetAllType::Values) 431 428 result.addValue(valueForKey(key)); 429 result.addKey(WTFMove(key)); 432 430 433 431 ++currentCount; -
trunk/Source/WebCore/Modules/indexeddb/server/MemoryObjectStoreCursor.cpp
r243910 r244436 195 195 else { 196 196 IDBValue value = { m_objectStore.valueForKeyRange(m_currentPositionKey), { }, { }, { } }; 197 data = { m_currentPositionKey, m_currentPositionKey, WTFMove(value) };197 data = { m_currentPositionKey, m_currentPositionKey, WTFMove(value), m_objectStore.info().keyPath() }; 198 198 } 199 199 } -
trunk/Source/WebCore/Modules/indexeddb/server/SQLiteIDBBackingStore.cpp
r243910 r244436 30 30 31 31 #include "IDBBindingUtilities.h" 32 #include "IDBCursorInfo.h" 32 33 #include "IDBGetAllRecordsData.h" 33 34 #include "IDBGetAllResult.h" … … 1753 1754 1754 1755 IndexKey indexKey; 1755 generateIndexKeyForValue(*m_globalObject->globalExec(), info, jsValue, indexKey); 1756 auto* objectStoreInfo = infoForObjectStore(info.objectStoreIdentifier()); 1757 ASSERT(objectStoreInfo); 1758 generateIndexKeyForValue(*m_globalObject->globalExec(), info, jsValue, indexKey, objectStoreInfo->keyPath(), key); 1756 1759 1757 1760 if (indexKey.isNull()) … … 1773 1776 for (auto& index : info.indexMap().values()) { 1774 1777 IndexKey indexKey; 1775 generateIndexKeyForValue(*m_globalObject->globalExec(), index, jsValue, indexKey );1778 generateIndexKeyForValue(*m_globalObject->globalExec(), index, jsValue, indexKey, info.keyPath(), key); 1776 1779 1777 1780 if (indexKey.isNull()) … … 2005 2008 2006 2009 int64_t recordID = 0; 2007 ThreadSafeDataBuffer resultBuffer;2008 { 2009 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;";2010 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;";2011 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;";2012 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;";2010 ThreadSafeDataBuffer keyResultBuffer, valueResultBuffer; 2011 { 2012 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;"; 2013 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;"; 2014 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;"; 2015 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;"; 2013 2016 2014 2017 static const char* const lowerOpenUpperOpenKeyOnly = "SELECT key FROM Records WHERE objectStoreID = ? AND key > CAST(? AS TEXT) AND key < CAST(? AS TEXT) ORDER BY key;"; … … 2067 2070 } 2068 2071 2069 Vector<uint8_t> buffer; 2070 sql->getColumnBlobAsVector(0, buffer); 2071 resultBuffer = ThreadSafeDataBuffer::create(WTFMove(buffer)); 2072 2073 if (type == IDBGetRecordDataType::KeyAndValue) 2074 recordID = sql->getColumnInt64(1); 2072 Vector<uint8_t> keyBuffer; 2073 sql->getColumnBlobAsVector(0, keyBuffer); 2074 keyResultBuffer = ThreadSafeDataBuffer::create(WTFMove(keyBuffer)); 2075 2076 if (type == IDBGetRecordDataType::KeyAndValue) { 2077 Vector<uint8_t> valueBuffer; 2078 sql->getColumnBlobAsVector(1, valueBuffer); 2079 valueResultBuffer = ThreadSafeDataBuffer::create(WTFMove(valueBuffer)); 2080 recordID = sql->getColumnInt64(2); 2081 } 2082 } 2083 2084 auto* keyVector = keyResultBuffer.data(); 2085 if (!keyVector) { 2086 LOG_ERROR("Unable to deserialize key data from database for IDBObjectStore"); 2087 return IDBError { UnknownError, "Error extracting key data from database executing IDBObjectStore get"_s }; 2088 } 2089 2090 IDBKeyData keyData; 2091 if (!deserializeIDBKeyData(keyVector->data(), keyVector->size(), keyData)) { 2092 LOG_ERROR("Unable to deserialize key data from database for IDBObjectStore"); 2093 return IDBError { UnknownError, "Error extracting key data from database executing IDBObjectStore get"_s }; 2075 2094 } 2076 2095 2077 2096 if (type == IDBGetRecordDataType::KeyOnly) { 2078 auto* vector = resultBuffer.data();2079 if (!vector) {2080 LOG_ERROR("Unable to deserialize key data from database for IDBObjectStore.getKey()");2081 return IDBError { UnknownError, "Error extracting key data from database executing IDBObjectStore.getKey()"_s };2082 }2083 2084 IDBKeyData keyData;2085 if (!deserializeIDBKeyData(vector->data(), vector->size(), keyData)) {2086 LOG_ERROR("Unable to deserialize key data from database for IDBObjectStore.getKey()");2087 return IDBError { UnknownError, "Error extracting key data from database executing IDBObjectStore.getKey()"_s };2088 }2089 2090 2097 resultValue = { keyData }; 2091 2098 return IDBError { }; … … 2101 2108 return error; 2102 2109 2103 resultValue = { { resultBuffer, WTFMove(blobURLs), sessionID, WTFMove(blobFilePaths) } }; 2110 auto* objectStoreInfo = infoForObjectStore(objectStoreID); 2111 ASSERT(objectStoreInfo); 2112 resultValue = { keyData, { valueResultBuffer, WTFMove(blobURLs), sessionID, WTFMove(blobFilePaths) }, objectStoreInfo->keyPath()}; 2104 2113 return IDBError { }; 2105 2114 } … … 2116 2125 static const char* const lowerClosedUpperOpenKey = "SELECT key FROM Records WHERE objectStoreID = ? AND key >= CAST(? AS TEXT) AND key < CAST(? AS TEXT) ORDER BY key;"; 2117 2126 static const char* const lowerClosedUpperClosedKey = "SELECT key FROM Records WHERE objectStoreID = ? AND key >= CAST(? AS TEXT) AND key <= CAST(? AS TEXT) ORDER BY key;"; 2118 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;";2119 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;";2120 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;";2121 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;";2127 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;"; 2128 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;"; 2129 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;"; 2130 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;"; 2122 2131 2123 2132 if (getAllRecordsData.getAllType == IndexedDB::GetAllType::Keys) { … … 2184 2193 } 2185 2194 2186 result = { getAllRecordsData.getAllType }; 2195 auto* objectStoreInfo = infoForObjectStore(getAllRecordsData.objectStoreIdentifier); 2196 ASSERT(objectStoreInfo); 2197 result = { getAllRecordsData.getAllType, objectStoreInfo->keyPath() }; 2187 2198 2188 2199 uint32_t targetResults; … … 2196 2207 2197 2208 while (sqlResult == SQLITE_ROW && returnedResults < targetResults) { 2209 Vector<uint8_t> keyBuffer; 2210 IDBKeyData keyData; 2211 sql->getColumnBlobAsVector(0, keyBuffer); 2212 if (!deserializeIDBKeyData(keyBuffer.data(), keyBuffer.size(), keyData)) { 2213 LOG_ERROR("Unable to deserialize key data from database while getting all records"); 2214 return IDBError { UnknownError, "Unable to deserialize key data while getting all records"_s }; 2215 } 2216 result.addKey(WTFMove(keyData)); 2217 2198 2218 if (getAllRecordsData.getAllType == IndexedDB::GetAllType::Values) { 2199 Vector<uint8_t> buffer;2200 sql->getColumnBlobAsVector( 0, buffer);2201 ThreadSafeDataBuffer resultBuffer = ThreadSafeDataBuffer::create(WTFMove(buffer));2202 2203 auto recordID = sql->getColumnInt64( 1);2219 Vector<uint8_t> valueBuffer; 2220 sql->getColumnBlobAsVector(1, valueBuffer); 2221 ThreadSafeDataBuffer valueResultBuffer = ThreadSafeDataBuffer::create(WTFMove(valueBuffer)); 2222 2223 auto recordID = sql->getColumnInt64(2); 2204 2224 2205 2225 ASSERT(recordID); … … 2212 2232 return error; 2213 2233 2214 result.addValue({ resultBuffer, WTFMove(blobURLs), sessionID, WTFMove(blobFilePaths) }); 2215 } else { 2216 Vector<uint8_t> keyData; 2217 IDBKeyData key; 2218 sql->getColumnBlobAsVector(0, keyData); 2219 2220 if (!deserializeIDBKeyData(keyData.data(), keyData.size(), key)) { 2221 LOG_ERROR("Unable to deserialize key data from database while getting all key records"); 2222 return IDBError { UnknownError, "Unable to deserialize key data while getting all key records"_s }; 2223 } 2224 2225 result.addKey(WTFMove(key)); 2234 result.addValue({ valueResultBuffer, WTFMove(blobURLs), sessionID, WTFMove(blobFilePaths) }); 2226 2235 } 2227 2236 … … 2264 2273 } 2265 2274 2266 result = { getAllRecordsData.getAllType }; 2275 auto* objectStoreInfo = infoForObjectStore(getAllRecordsData.objectStoreIdentifier); 2276 ASSERT(objectStoreInfo); 2277 result = { getAllRecordsData.getAllType, objectStoreInfo->keyPath() }; 2278 2267 2279 uint32_t currentCount = 0; 2268 2280 uint32_t targetCount = getAllRecordsData.count ? getAllRecordsData.count.value() : 0; … … 2270 2282 targetCount = std::numeric_limits<uint32_t>::max(); 2271 2283 while (!cursor->didComplete() && !cursor->didError() && currentCount < targetCount) { 2272 if (getAllRecordsData.getAllType == IndexedDB::GetAllType::Keys) { 2273 IDBKeyData keyCopy = cursor->currentPrimaryKey(); 2274 result.addKey(WTFMove(keyCopy)); 2275 } else 2284 IDBKeyData keyCopy = cursor->currentPrimaryKey(); 2285 result.addKey(WTFMove(keyCopy)); 2286 if (getAllRecordsData.getAllType == IndexedDB::GetAllType::Values) 2276 2287 result.addValue(cursor->currentValue() ? *cursor->currentValue() : IDBValue()); 2277 2288 … … 2320 2331 if (type == IndexedDB::IndexRecordType::Key) 2321 2332 getResult = { cursor->currentPrimaryKey() }; 2322 else 2323 getResult = { cursor->currentValue() ? *cursor->currentValue() : IDBValue(), cursor->currentPrimaryKey() }; 2333 else { 2334 auto* objectStoreInfo = infoForObjectStore(objectStoreID); 2335 ASSERT(objectStoreInfo); 2336 getResult = { cursor->currentPrimaryKey(), cursor->currentPrimaryKey(), cursor->currentValue() ? *cursor->currentValue() : IDBValue(), objectStoreInfo->keyPath() }; 2337 } 2324 2338 } 2325 2339 … … 2372 2386 } 2373 2387 2374 sql->getColumnBlobAsVector(1, keyVector); 2388 Vector<uint8_t> valueVector; 2389 sql->getColumnBlobAsVector(1, valueVector); 2375 2390 2376 2391 int64_t recordID = sql->getColumnInt64(2); … … 2383 2398 return error; 2384 2399 2385 getResult = { { ThreadSafeDataBuffer::create(WTFMove(keyVector)), WTFMove(blobURLs), sessionID, WTFMove(blobFilePaths) }, objectStoreKey }; 2400 auto* objectStoreInfo = infoForObjectStore(objectStoreID); 2401 ASSERT(objectStoreInfo); 2402 getResult = { objectStoreKey, objectStoreKey, { ThreadSafeDataBuffer::create(WTFMove(valueVector)), WTFMove(blobURLs), sessionID, WTFMove(blobFilePaths) }, objectStoreInfo->keyPath() }; 2386 2403 return IDBError { }; 2387 2404 } … … 2548 2565 m_cursors.set(cursor->identifier(), cursor); 2549 2566 2550 cursor->currentData(result); 2567 auto* objectStoreInfo = infoForObjectStore(info.objectStoreIdentifier()); 2568 ASSERT(objectStoreInfo); 2569 cursor->currentData(result, objectStoreInfo->keyPath()); 2551 2570 return IDBError { }; 2552 2571 } … … 2591 2610 } 2592 2611 2593 cursor->currentData(result); 2612 auto* objectStoreInfo = infoForObjectStore(cursor->objectStoreID()); 2613 ASSERT(objectStoreInfo); 2614 cursor->currentData(result, objectStoreInfo->keyPath()); 2594 2615 return IDBError { }; 2595 2616 } -
trunk/Source/WebCore/Modules/indexeddb/server/SQLiteIDBCursor.cpp
r243910 r244436 102 102 } 103 103 104 void SQLiteIDBCursor::currentData(IDBGetResult& result )104 void SQLiteIDBCursor::currentData(IDBGetResult& result, const Optional<IDBKeyPath>& keyPath) 105 105 { 106 106 ASSERT(!m_fetchedRecords.isEmpty()); … … 113 113 } 114 114 115 result = { currentRecord.record.key, currentRecord.record.primaryKey, currentRecord.record.value ? *currentRecord.record.value : IDBValue() 115 result = { currentRecord.record.key, currentRecord.record.primaryKey, currentRecord.record.value ? *currentRecord.record.value : IDBValue(), keyPath}; 116 116 } 117 117 -
trunk/Source/WebCore/Modules/indexeddb/server/SQLiteIDBCursor.h
r243910 r244436 80 80 void objectStoreRecordsChanged(); 81 81 82 void currentData(IDBGetResult& );82 void currentData(IDBGetResult&, const Optional<IDBKeyPath>&); 83 83 84 84 private: -
trunk/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.cpp
r244077 r244436 1248 1248 } 1249 1249 1250 // 3.4.1.2 Object Store Storage Operation1251 // If ObjectStore has a key path and the key is autogenerated, then inject the key into the value1252 // using steps to assign a key to a value using a key path.1253 ThreadSafeDataBuffer injectedRecordValue;1254 if (usedKeyIsGenerated && objectStoreInfo->keyPath()) {1255 VM& vm = databaseThreadVM();1256 JSLockHolder locker(vm);1257 auto scope = DECLARE_THROW_SCOPE(vm);1258 1259 auto value = deserializeIDBValueToJSValue(databaseThreadExecState(), originalRecordValue.data());1260 if (value.isUndefined()) {1261 postDatabaseTaskReply(createCrossThreadTask(*this, &UniqueIDBDatabase::didPerformPutOrAdd, callbackIdentifier, IDBError(ConstraintError, "Unable to deserialize record value for record key injection"_s), usedKey));1262 return;1263 }1264 1265 if (!injectIDBKeyIntoScriptValue(databaseThreadExecState(), usedKey, value, objectStoreInfo->keyPath().value())) {1266 postDatabaseTaskReply(createCrossThreadTask(*this, &UniqueIDBDatabase::didPerformPutOrAdd, callbackIdentifier, IDBError(ConstraintError, "Unable to inject record key into record value"_s), usedKey));1267 return;1268 }1269 1270 auto serializedValue = SerializedScriptValue::create(databaseThreadExecState(), value);1271 if (UNLIKELY(scope.exception())) {1272 postDatabaseTaskReply(createCrossThreadTask(*this, &UniqueIDBDatabase::didPerformPutOrAdd, callbackIdentifier, IDBError(ConstraintError, "Unable to serialize record value after injecting record key"_s), usedKey));1273 return;1274 }1275 1276 injectedRecordValue = ThreadSafeDataBuffer::copyVector(serializedValue->data());1277 }1278 1279 1250 // 3.4.1 Object Store Storage Operation 1280 1251 // ...If a record already exists in store ... … … 1287 1258 } 1288 1259 1289 if (injectedRecordValue.data()) 1290 error = m_backingStore->addRecord(transactionIdentifier, *objectStoreInfo, usedKey, { injectedRecordValue, originalRecordValue.blobURLs(), originalRecordValue.sessionID(), originalRecordValue.blobFilePaths() }); 1291 else 1292 error = m_backingStore->addRecord(transactionIdentifier, *objectStoreInfo, usedKey, originalRecordValue); 1260 error = m_backingStore->addRecord(transactionIdentifier, *objectStoreInfo, usedKey, originalRecordValue); 1293 1261 1294 1262 if (!error.isNull()) { -
trunk/Source/WebCore/Modules/indexeddb/shared/IDBResultData.cpp
r243910 r244436 234 234 } 235 235 236 IDBGetResult& IDBResultData::getResultRef() 237 { 238 RELEASE_ASSERT(m_getResult); 239 return *m_getResult; 240 } 241 236 242 const IDBGetAllResult& IDBResultData::getAllResult() const 237 243 { -
trunk/Source/WebCore/Modules/indexeddb/shared/IDBResultData.h
r243910 r244436 108 108 109 109 WEBCORE_EXPORT const IDBGetResult& getResult() const; 110 WEBCORE_EXPORT IDBGetResult& getResultRef(); 110 111 WEBCORE_EXPORT const IDBGetAllResult& getAllResult() const; 111 112 -
trunk/Source/WebCore/bindings/js/IDBBindingUtilities.cpp
r243910 r244436 32 32 #include "IDBBindingUtilities.h" 33 33 34 #include "ExceptionCode.h" 34 35 #include "IDBIndexInfo.h" 35 36 #include "IDBKey.h" … … 42 43 #include "JSDOMConvertDate.h" 43 44 #include "JSDOMConvertNullable.h" 45 #include "JSDOMExceptionHandling.h" 44 46 #include "JSFile.h" 45 47 #include "Logging.h" … … 325 327 return false; 326 328 329 // Do not set if object already has the correct property value. 330 auto jsKey = toJS(exec, *exec.lexicalGlobalObject(), key.get()); 331 JSValue existingKey; 332 if (get(exec, parent, keyPathElements.last(), existingKey) && existingKey == jsKey) 333 return true; 334 327 335 if (!set(exec, parent, keyPathElements.last(), toJS(exec, *exec.lexicalGlobalObject(), key.get()))) 328 336 return false; … … 412 420 } 413 421 414 static Vector<IDBKeyData> createKeyPathArray(ExecState& exec, JSValue value, const IDBIndexInfo& info )422 static Vector<IDBKeyData> createKeyPathArray(ExecState& exec, JSValue value, const IDBIndexInfo& info, Optional<IDBKeyPath> objectStoreKeyPath, const IDBKeyData& objectStoreKey) 415 423 { 416 424 auto visitor = WTF::makeVisitor([&](const String& string) -> Vector<IDBKeyData> { 425 // Value doesn't contain auto-generated key, so we need to manually add key if it is possibly auto-generated. 426 if (objectStoreKeyPath && WTF::holds_alternative<String>(objectStoreKeyPath.value()) && IDBKeyPath(string) == objectStoreKeyPath.value()) 427 return { objectStoreKey }; 428 417 429 auto idbKey = internalCreateIDBKeyFromScriptValueAndKeyPath(exec, value, string); 418 430 if (!idbKey) … … 429 441 Vector<IDBKeyData> keys; 430 442 for (auto& entry : vector) { 431 auto key = internalCreateIDBKeyFromScriptValueAndKeyPath(exec, value, entry); 432 if (!key || !key->isValid()) 433 return { }; 434 keys.append(key.get()); 443 if (objectStoreKeyPath && WTF::holds_alternative<String>(objectStoreKeyPath.value()) && IDBKeyPath(entry) == objectStoreKeyPath.value()) 444 keys.append(objectStoreKey); 445 else { 446 auto key = internalCreateIDBKeyFromScriptValueAndKeyPath(exec, value, entry); 447 if (!key || !key->isValid()) 448 return { }; 449 keys.append(key.get()); 450 } 435 451 } 436 452 return keys; … … 440 456 } 441 457 442 void generateIndexKeyForValue(ExecState& exec, const IDBIndexInfo& info, JSValue value, IndexKey& outKey) 443 { 444 auto keyDatas = createKeyPathArray(exec, value, info); 445 458 void generateIndexKeyForValue(ExecState& exec, const IDBIndexInfo& info, JSValue value, IndexKey& outKey, const Optional<IDBKeyPath>& objectStoreKeyPath, const IDBKeyData& objectStoreKey) 459 { 460 auto keyDatas = createKeyPathArray(exec, value, info, objectStoreKeyPath, objectStoreKey); 446 461 if (keyDatas.isEmpty()) 447 462 return; … … 450 465 } 451 466 467 Optional<JSC::JSValue> deserializeIDBValueWithKeyInjection(ExecState& state, const IDBValue& value, const IDBKeyData& key, const Optional<IDBKeyPath>& keyPath) 468 { 469 auto jsValue = deserializeIDBValueToJSValue(state, value); 470 if (jsValue.isUndefined() || !keyPath || !WTF::holds_alternative<String>(keyPath.value()) || !isIDBKeyPathValid(keyPath.value())) 471 return jsValue; 472 473 JSLockHolder locker(state.vm()); 474 if (!injectIDBKeyIntoScriptValue(state, key, jsValue, keyPath.value())) { 475 auto throwScope = DECLARE_THROW_SCOPE(state.vm()); 476 propagateException(state, throwScope, Exception(UnknownError, "Cannot inject key into script value"_s)); 477 return WTF::nullopt; 478 } 479 480 return jsValue; 481 } 482 452 483 } // namespace WebCore 453 484 -
trunk/Source/WebCore/bindings/js/IDBBindingUtilities.h
r243910 r244436 51 51 bool injectIDBKeyIntoScriptValue(JSC::ExecState&, const IDBKeyData&, JSC::JSValue, const IDBKeyPath&); 52 52 53 void generateIndexKeyForValue(JSC::ExecState&, const IDBIndexInfo&, JSC::JSValue, IndexKey& outKey );53 void generateIndexKeyForValue(JSC::ExecState&, const IDBIndexInfo&, JSC::JSValue, IndexKey& outKey, const Optional<IDBKeyPath>&, const IDBKeyData&); 54 54 55 55 Ref<IDBKey> scriptValueToIDBKey(JSC::ExecState&, const JSC::JSValue&); 56 56 57 JSC::JSValue deserializeIDBValueToJSValue(JSC::ExecState&, const IDBValue&, Vector<std::pair<String, String>>&); 57 58 JSC::JSValue deserializeIDBValueToJSValue(JSC::ExecState&, const IDBValue&); 58 59 JSC::JSValue toJS(JSC::ExecState*, JSDOMGlobalObject*, const IDBValue&); … … 60 61 JSC::JSValue toJS(JSC::ExecState*, JSDOMGlobalObject*, const IDBKeyData&); 61 62 63 Optional<JSC::JSValue> deserializeIDBValueWithKeyInjection(JSC::ExecState&, const IDBValue&, const IDBKeyData&, const Optional<IDBKeyPath>&); 62 64 } 63 65 -
trunk/Source/WebCore/bindings/js/JSIDBCursorWithValueCustom.cpp
r244225 r244436 39 39 { 40 40 return cachedPropertyValue(state, *this, wrapped().valueWrapper(), [&] { 41 return deserializeIDBValueToJSValue(state, wrapped().value()); 41 auto result = deserializeIDBValueWithKeyInjection(state, wrapped().value(), wrapped().primaryKey(), wrapped().primaryKeyPath()); 42 return result ? result.value() : jsNull(); 42 43 }); 43 44 } -
trunk/Source/WebCore/bindings/js/JSIDBRequestCustom.cpp
r243910 r244436 58 58 }, [&state] (Vector<IDBKeyData> keyDatas) { 59 59 return toJS<IDLSequence<IDLIDBKeyData>>(state, *jsCast<JSDOMGlobalObject*>(state.lexicalGlobalObject()), keyDatas); 60 }, [&state] (IDBValue value) { 61 return toJS<IDLIDBValue>(state, *jsCast<JSDOMGlobalObject*>(state.lexicalGlobalObject()), value); 62 }, [&state] (Vector<IDBValue> values) { 63 return toJS<IDLSequence<IDLIDBValue>>(state, *jsCast<JSDOMGlobalObject*>(state.lexicalGlobalObject()), values); 60 }, [&state] (IDBGetResult getResult) { 61 auto result = deserializeIDBValueWithKeyInjection(state, getResult.value(), getResult.keyData(), getResult.keyPath()); 62 return result ? result.value() : jsNull(); 63 }, [&state] (IDBGetAllResult getAllResult) { 64 auto& keys = getAllResult.keys(); 65 auto& values = getAllResult.values(); 66 auto& keyPath = getAllResult.keyPath(); 67 auto scope = DECLARE_THROW_SCOPE(state.vm()); 68 JSC::MarkedArgumentBuffer list; 69 for (unsigned i = 0; i < values.size(); i ++) { 70 auto result = deserializeIDBValueWithKeyInjection(state, values[i], keys[i], keyPath); 71 if (!result) 72 return jsNull(); 73 list.append(result.value()); 74 if (UNLIKELY(list.hasOverflowed())) { 75 propagateException(state, scope, Exception(UnknownError)); 76 return jsNull(); 77 } 78 } 79 return JSValue(JSC::constructArray(&state, nullptr, state.lexicalGlobalObject(), list)); 64 80 }, [] (uint64_t number) { 65 81 return toJS<IDLUnsignedLongLong>(number);
Note: See TracChangeset
for help on using the changeset viewer.