| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2010 Google Inc. All rights reserved. | 2 * Copyright (C) 2010 Google Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
| 6 * are met: | 6 * are met: |
| 7 * | 7 * |
| 8 * 1. Redistributions of source code must retain the above copyright | 8 * 1. Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * 2. Redistributions in binary form must reproduce the above copyright | 10 * 2. Redistributions in binary form must reproduce the above copyright |
| (...skipping 22 matching lines...) Expand all Loading... |
| 33 #include "bindings/modules/v8/ToV8ForModules.h" | 33 #include "bindings/modules/v8/ToV8ForModules.h" |
| 34 #include "bindings/modules/v8/V8BindingForModules.h" | 34 #include "bindings/modules/v8/V8BindingForModules.h" |
| 35 #include "core/dom/DOMStringList.h" | 35 #include "core/dom/DOMStringList.h" |
| 36 #include "core/dom/ExceptionCode.h" | 36 #include "core/dom/ExceptionCode.h" |
| 37 #include "core/dom/ExecutionContext.h" | 37 #include "core/dom/ExecutionContext.h" |
| 38 #include "modules/indexeddb/IDBAny.h" | 38 #include "modules/indexeddb/IDBAny.h" |
| 39 #include "modules/indexeddb/IDBCursorWithValue.h" | 39 #include "modules/indexeddb/IDBCursorWithValue.h" |
| 40 #include "modules/indexeddb/IDBDatabase.h" | 40 #include "modules/indexeddb/IDBDatabase.h" |
| 41 #include "modules/indexeddb/IDBKeyPath.h" | 41 #include "modules/indexeddb/IDBKeyPath.h" |
| 42 #include "modules/indexeddb/IDBTracing.h" | 42 #include "modules/indexeddb/IDBTracing.h" |
| 43 #include "modules/indexeddb/IDBValueWrapping.h" |
| 43 #include "platform/Histogram.h" | 44 #include "platform/Histogram.h" |
| 44 #include "platform/SharedBuffer.h" | 45 #include "platform/SharedBuffer.h" |
| 45 #include "platform/bindings/ScriptState.h" | 46 #include "platform/bindings/ScriptState.h" |
| 47 #include "platform/wtf/RefPtr.h" |
| 46 #include "public/platform/WebBlobInfo.h" | 48 #include "public/platform/WebBlobInfo.h" |
| 47 #include "public/platform/WebData.h" | 49 #include "public/platform/WebData.h" |
| 48 #include "public/platform/WebVector.h" | 50 #include "public/platform/WebVector.h" |
| 49 #include "public/platform/modules/indexeddb/WebIDBKey.h" | 51 #include "public/platform/modules/indexeddb/WebIDBKey.h" |
| 50 #include "public/platform/modules/indexeddb/WebIDBKeyRange.h" | 52 #include "public/platform/modules/indexeddb/WebIDBKeyRange.h" |
| 51 #include "v8/include/v8.h" | 53 #include "v8/include/v8.h" |
| 52 | 54 |
| 53 using blink::WebBlobInfo; | 55 using blink::WebBlobInfo; |
| 54 using blink::WebIDBCallbacks; | 56 using blink::WebIDBCallbacks; |
| 55 using blink::WebIDBCursor; | 57 using blink::WebIDBCursor; |
| (...skipping 313 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 369 return nullptr; | 371 return nullptr; |
| 370 } | 372 } |
| 371 if (transaction_->IsReadOnly()) { | 373 if (transaction_->IsReadOnly()) { |
| 372 exception_state.ThrowDOMException( | 374 exception_state.ThrowDOMException( |
| 373 kReadOnlyError, IDBDatabase::kTransactionReadOnlyErrorMessage); | 375 kReadOnlyError, IDBDatabase::kTransactionReadOnlyErrorMessage); |
| 374 return nullptr; | 376 return nullptr; |
| 375 } | 377 } |
| 376 | 378 |
| 377 v8::Isolate* isolate = script_state->GetIsolate(); | 379 v8::Isolate* isolate = script_state->GetIsolate(); |
| 378 DCHECK(isolate->InContext()); | 380 DCHECK(isolate->InContext()); |
| 379 Vector<WebBlobInfo> blob_info; | |
| 380 SerializedScriptValue::SerializeOptions options; | |
| 381 options.blob_info = &blob_info; | |
| 382 | |
| 383 // TODO(crbug.com/719053): This wasm behavior differs from other browsers. | 381 // TODO(crbug.com/719053): This wasm behavior differs from other browsers. |
| 384 options.wasm_policy = | 382 SerializedScriptValue::SerializeOptions::WasmSerializationPolicy wasm_policy = |
| 385 ExecutionContext::From(script_state)->IsSecureContext() | 383 ExecutionContext::From(script_state)->IsSecureContext() |
| 386 ? SerializedScriptValue::SerializeOptions::kSerialize | 384 ? SerializedScriptValue::SerializeOptions::kSerialize |
| 387 : SerializedScriptValue::SerializeOptions::kBlockedInNonSecureContext; | 385 : SerializedScriptValue::SerializeOptions::kBlockedInNonSecureContext; |
| 388 options.for_storage = SerializedScriptValue::kForStorage; | 386 IDBValueWrapper value_wrapper(isolate, value.V8Value(), wasm_policy, |
| 389 RefPtr<SerializedScriptValue> serialized_value = | 387 exception_state); |
| 390 SerializedScriptValue::Serialize(isolate, value.V8Value(), options, | |
| 391 exception_state); | |
| 392 if (exception_state.HadException()) | 388 if (exception_state.HadException()) |
| 393 return nullptr; | 389 return nullptr; |
| 394 | 390 |
| 395 // Keys that need to be extracted must be taken from a clone so that | 391 // Keys that need to be extracted must be taken from a clone so that |
| 396 // side effects (i.e. getters) are not triggered. Construct the | 392 // side effects (i.e. getters) are not triggered. Construct the |
| 397 // clone lazily since the operation may be expensive. | 393 // clone lazily since the operation may be expensive. |
| 398 ScriptValue clone; | 394 ScriptValue clone; |
| 399 | 395 |
| 400 const IDBKeyPath& key_path = IdbKeyPath(); | 396 const IDBKeyPath& key_path = IdbKeyPath(); |
| 401 const bool uses_in_line_keys = !key_path.IsNull(); | 397 const bool uses_in_line_keys = !key_path.IsNull(); |
| 402 const bool has_key_generator = autoIncrement(); | 398 const bool has_key_generator = autoIncrement(); |
| 403 | 399 |
| 404 if (put_mode != kWebIDBPutModeCursorUpdate && uses_in_line_keys && key) { | 400 if (put_mode != kWebIDBPutModeCursorUpdate && uses_in_line_keys && key) { |
| 405 exception_state.ThrowDOMException(kDataError, | 401 exception_state.ThrowDOMException(kDataError, |
| 406 "The object store uses in-line keys and " | 402 "The object store uses in-line keys and " |
| 407 "the key parameter was provided."); | 403 "the key parameter was provided."); |
| 408 return nullptr; | 404 return nullptr; |
| 409 } | 405 } |
| 410 | 406 |
| 411 // This test logically belongs in IDBCursor, but must operate on the cloned | 407 // This test logically belongs in IDBCursor, but must operate on the cloned |
| 412 // value. | 408 // value. |
| 413 if (put_mode == kWebIDBPutModeCursorUpdate && uses_in_line_keys) { | 409 if (put_mode == kWebIDBPutModeCursorUpdate && uses_in_line_keys) { |
| 414 DCHECK(key); | 410 DCHECK(key); |
| 415 if (clone.IsEmpty()) | 411 DCHECK(clone.IsEmpty()); |
| 416 clone = DeserializeScriptValue(script_state, serialized_value.Get(), | 412 value_wrapper.Clone(script_state, &clone); |
| 417 &blob_info); | |
| 418 IDBKey* key_path_key = ScriptValue::To<IDBKey*>( | 413 IDBKey* key_path_key = ScriptValue::To<IDBKey*>( |
| 419 script_state->GetIsolate(), clone, exception_state, key_path); | 414 script_state->GetIsolate(), clone, exception_state, key_path); |
| 420 if (exception_state.HadException()) | 415 if (exception_state.HadException()) |
| 421 return nullptr; | 416 return nullptr; |
| 422 if (!key_path_key || !key_path_key->IsEqual(key)) { | 417 if (!key_path_key || !key_path_key->IsEqual(key)) { |
| 423 exception_state.ThrowDOMException( | 418 exception_state.ThrowDOMException( |
| 424 kDataError, | 419 kDataError, |
| 425 "The effective object store of this cursor uses in-line keys and " | 420 "The effective object store of this cursor uses in-line keys and " |
| 426 "evaluating the key path of the value parameter results in a " | 421 "evaluating the key path of the value parameter results in a " |
| 427 "different value than the cursor's effective key."); | 422 "different value than the cursor's effective key."); |
| 428 return nullptr; | 423 return nullptr; |
| 429 } | 424 } |
| 430 } | 425 } |
| 431 | 426 |
| 432 if (!uses_in_line_keys && !has_key_generator && !key) { | 427 if (!uses_in_line_keys && !has_key_generator && !key) { |
| 433 exception_state.ThrowDOMException(kDataError, | 428 exception_state.ThrowDOMException(kDataError, |
| 434 "The object store uses out-of-line keys " | 429 "The object store uses out-of-line keys " |
| 435 "and has no key generator and the key " | 430 "and has no key generator and the key " |
| 436 "parameter was not provided."); | 431 "parameter was not provided."); |
| 437 return nullptr; | 432 return nullptr; |
| 438 } | 433 } |
| 439 if (uses_in_line_keys) { | 434 if (uses_in_line_keys) { |
| 440 if (clone.IsEmpty()) { | 435 if (clone.IsEmpty()) |
| 441 clone = DeserializeScriptValue(script_state, serialized_value.Get(), | 436 value_wrapper.Clone(script_state, &clone); |
| 442 &blob_info); | |
| 443 } | |
| 444 IDBKey* key_path_key = ScriptValue::To<IDBKey*>( | 437 IDBKey* key_path_key = ScriptValue::To<IDBKey*>( |
| 445 script_state->GetIsolate(), clone, exception_state, key_path); | 438 script_state->GetIsolate(), clone, exception_state, key_path); |
| 446 if (exception_state.HadException()) | 439 if (exception_state.HadException()) |
| 447 return nullptr; | 440 return nullptr; |
| 448 if (key_path_key && !key_path_key->IsValid()) { | 441 if (key_path_key && !key_path_key->IsValid()) { |
| 449 exception_state.ThrowDOMException( | 442 exception_state.ThrowDOMException( |
| 450 kDataError, | 443 kDataError, |
| 451 "Evaluating the object store's key path " | 444 "Evaluating the object store's key path " |
| 452 "yielded a value that is not a valid " | 445 "yielded a value that is not a valid " |
| 453 "key."); | 446 "key."); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 487 DEFINE_THREAD_SAFE_STATIC_LOCAL( | 480 DEFINE_THREAD_SAFE_STATIC_LOCAL( |
| 488 EnumerationHistogram, key_type_histogram, | 481 EnumerationHistogram, key_type_histogram, |
| 489 new EnumerationHistogram("WebCore.IndexedDB.ObjectStore.Record.KeyType", | 482 new EnumerationHistogram("WebCore.IndexedDB.ObjectStore.Record.KeyType", |
| 490 static_cast<int>(IDBKey::kTypeEnumMax))); | 483 static_cast<int>(IDBKey::kTypeEnumMax))); |
| 491 key_type_histogram.Count(static_cast<int>(key->GetType())); | 484 key_type_histogram.Count(static_cast<int>(key->GetType())); |
| 492 } | 485 } |
| 493 | 486 |
| 494 Vector<int64_t> index_ids; | 487 Vector<int64_t> index_ids; |
| 495 HeapVector<IndexKeys> index_keys; | 488 HeapVector<IndexKeys> index_keys; |
| 496 for (const auto& it : Metadata().indexes) { | 489 for (const auto& it : Metadata().indexes) { |
| 497 if (clone.IsEmpty()) { | 490 if (clone.IsEmpty()) |
| 498 clone = DeserializeScriptValue(script_state, serialized_value.Get(), | 491 value_wrapper.Clone(script_state, &clone); |
| 499 &blob_info); | |
| 500 } | |
| 501 IndexKeys keys; | 492 IndexKeys keys; |
| 502 GenerateIndexKeysForValue(script_state->GetIsolate(), *it.value, clone, | 493 GenerateIndexKeysForValue(script_state->GetIsolate(), *it.value, clone, |
| 503 &keys); | 494 &keys); |
| 504 index_ids.push_back(it.key); | 495 index_ids.push_back(it.key); |
| 505 index_keys.push_back(keys); | 496 index_keys.push_back(keys); |
| 506 } | 497 } |
| 507 | 498 |
| 508 IDBRequest* request = | 499 IDBRequest* request = |
| 509 IDBRequest::Create(script_state, source, transaction_.Get()); | 500 IDBRequest::Create(script_state, source, transaction_.Get()); |
| 510 Vector<char> wire_bytes; | |
| 511 serialized_value->ToWireBytes(wire_bytes); | |
| 512 RefPtr<SharedBuffer> value_buffer = SharedBuffer::AdoptVector(wire_bytes); | |
| 513 | 501 |
| 514 request->StorePutOperationBlobs(serialized_value->BlobDataHandles()); | 502 value_wrapper.ExtractBlobDataHandles(request->transit_blob_handles()); |
| 503 value_wrapper.WrapIfBiggerThan(IDBValueWrapper::kWrapThreshold); |
| 515 | 504 |
| 516 BackendDB()->Put(transaction_->Id(), Id(), WebData(value_buffer), blob_info, | 505 BackendDB()->Put( |
| 517 key, static_cast<WebIDBPutMode>(put_mode), | 506 transaction_->Id(), Id(), WebData(value_wrapper.ExtractWireBytes()), |
| 518 request->CreateWebCallbacks().release(), index_ids, | 507 value_wrapper.WrappedBlobInfo(), key, |
| 519 index_keys); | 508 static_cast<WebIDBPutMode>(put_mode), |
| 509 request->CreateWebCallbacks().release(), index_ids, index_keys); |
| 510 |
| 520 return request; | 511 return request; |
| 521 } | 512 } |
| 522 | 513 |
| 523 IDBRequest* IDBObjectStore::deleteFunction(ScriptState* script_state, | 514 IDBRequest* IDBObjectStore::deleteFunction(ScriptState* script_state, |
| 524 const ScriptValue& key, | 515 const ScriptValue& key, |
| 525 ExceptionState& exception_state) { | 516 ExceptionState& exception_state) { |
| 526 IDB_TRACE("IDBObjectStore::delete"); | 517 IDB_TRACE("IDBObjectStore::delete"); |
| 527 if (IsDeleted()) { | 518 if (IsDeleted()) { |
| 528 exception_state.ThrowDOMException( | 519 exception_state.ThrowDOMException( |
| 529 kInvalidStateError, IDBDatabase::kObjectStoreDeletedErrorMessage); | 520 kInvalidStateError, IDBDatabase::kObjectStoreDeletedErrorMessage); |
| (...skipping 529 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1059 } | 1050 } |
| 1060 } | 1051 } |
| 1061 return IDBIndexMetadata::kInvalidId; | 1052 return IDBIndexMetadata::kInvalidId; |
| 1062 } | 1053 } |
| 1063 | 1054 |
| 1064 WebIDBDatabase* IDBObjectStore::BackendDB() const { | 1055 WebIDBDatabase* IDBObjectStore::BackendDB() const { |
| 1065 return transaction_->BackendDB(); | 1056 return transaction_->BackendDB(); |
| 1066 } | 1057 } |
| 1067 | 1058 |
| 1068 } // namespace blink | 1059 } // namespace blink |
| OLD | NEW |