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.write_wasm_to_stream = | 382 bool write_wasm_to_stream = |
385 ExecutionContext::From(script_state)->IsSecureContext(); | 383 ExecutionContext::From(script_state)->IsSecureContext(); |
386 options.for_storage = SerializedScriptValue::kForStorage; | 384 IDBValueWrapper value_wrapper(isolate, value.V8Value(), write_wasm_to_stream, |
387 RefPtr<SerializedScriptValue> serialized_value = | 385 exception_state); |
388 SerializedScriptValue::Serialize(isolate, value.V8Value(), options, | |
389 exception_state); | |
390 if (exception_state.HadException()) | 386 if (exception_state.HadException()) |
391 return nullptr; | 387 return nullptr; |
392 | 388 |
393 // Keys that need to be extracted must be taken from a clone so that | 389 // Keys that need to be extracted must be taken from a clone so that |
394 // side effects (i.e. getters) are not triggered. Construct the | 390 // side effects (i.e. getters) are not triggered. Construct the |
395 // clone lazily since the operation may be expensive. | 391 // clone lazily since the operation may be expensive. |
396 ScriptValue clone; | 392 ScriptValue clone; |
397 | 393 |
398 const IDBKeyPath& key_path = IdbKeyPath(); | 394 const IDBKeyPath& key_path = IdbKeyPath(); |
399 const bool uses_in_line_keys = !key_path.IsNull(); | 395 const bool uses_in_line_keys = !key_path.IsNull(); |
400 const bool has_key_generator = autoIncrement(); | 396 const bool has_key_generator = autoIncrement(); |
401 | 397 |
402 if (put_mode != kWebIDBPutModeCursorUpdate && uses_in_line_keys && key) { | 398 if (put_mode != kWebIDBPutModeCursorUpdate && uses_in_line_keys && key) { |
403 exception_state.ThrowDOMException(kDataError, | 399 exception_state.ThrowDOMException(kDataError, |
404 "The object store uses in-line keys and " | 400 "The object store uses in-line keys and " |
405 "the key parameter was provided."); | 401 "the key parameter was provided."); |
406 return nullptr; | 402 return nullptr; |
407 } | 403 } |
408 | 404 |
409 // This test logically belongs in IDBCursor, but must operate on the cloned | 405 // This test logically belongs in IDBCursor, but must operate on the cloned |
410 // value. | 406 // value. |
411 if (put_mode == kWebIDBPutModeCursorUpdate && uses_in_line_keys) { | 407 if (put_mode == kWebIDBPutModeCursorUpdate && uses_in_line_keys) { |
412 DCHECK(key); | 408 DCHECK(key); |
413 if (clone.IsEmpty()) | 409 DCHECK(clone.IsEmpty()); |
414 clone = DeserializeScriptValue(script_state, serialized_value.Get(), | 410 value_wrapper.Clone(script_state, &clone); |
415 &blob_info); | |
416 IDBKey* key_path_key = ScriptValue::To<IDBKey*>( | 411 IDBKey* key_path_key = ScriptValue::To<IDBKey*>( |
417 script_state->GetIsolate(), clone, exception_state, key_path); | 412 script_state->GetIsolate(), clone, exception_state, key_path); |
418 if (exception_state.HadException()) | 413 if (exception_state.HadException()) |
419 return nullptr; | 414 return nullptr; |
420 if (!key_path_key || !key_path_key->IsEqual(key)) { | 415 if (!key_path_key || !key_path_key->IsEqual(key)) { |
421 exception_state.ThrowDOMException( | 416 exception_state.ThrowDOMException( |
422 kDataError, | 417 kDataError, |
423 "The effective object store of this cursor uses in-line keys and " | 418 "The effective object store of this cursor uses in-line keys and " |
424 "evaluating the key path of the value parameter results in a " | 419 "evaluating the key path of the value parameter results in a " |
425 "different value than the cursor's effective key."); | 420 "different value than the cursor's effective key."); |
426 return nullptr; | 421 return nullptr; |
427 } | 422 } |
428 } | 423 } |
429 | 424 |
430 if (!uses_in_line_keys && !has_key_generator && !key) { | 425 if (!uses_in_line_keys && !has_key_generator && !key) { |
431 exception_state.ThrowDOMException(kDataError, | 426 exception_state.ThrowDOMException(kDataError, |
432 "The object store uses out-of-line keys " | 427 "The object store uses out-of-line keys " |
433 "and has no key generator and the key " | 428 "and has no key generator and the key " |
434 "parameter was not provided."); | 429 "parameter was not provided."); |
435 return nullptr; | 430 return nullptr; |
436 } | 431 } |
437 if (uses_in_line_keys) { | 432 if (uses_in_line_keys) { |
438 if (clone.IsEmpty()) { | 433 if (clone.IsEmpty()) |
439 clone = DeserializeScriptValue(script_state, serialized_value.Get(), | 434 value_wrapper.Clone(script_state, &clone); |
440 &blob_info); | |
441 } | |
442 IDBKey* key_path_key = ScriptValue::To<IDBKey*>( | 435 IDBKey* key_path_key = ScriptValue::To<IDBKey*>( |
443 script_state->GetIsolate(), clone, exception_state, key_path); | 436 script_state->GetIsolate(), clone, exception_state, key_path); |
444 if (exception_state.HadException()) | 437 if (exception_state.HadException()) |
445 return nullptr; | 438 return nullptr; |
446 if (key_path_key && !key_path_key->IsValid()) { | 439 if (key_path_key && !key_path_key->IsValid()) { |
447 exception_state.ThrowDOMException( | 440 exception_state.ThrowDOMException( |
448 kDataError, | 441 kDataError, |
449 "Evaluating the object store's key path " | 442 "Evaluating the object store's key path " |
450 "yielded a value that is not a valid " | 443 "yielded a value that is not a valid " |
451 "key."); | 444 "key."); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
485 DEFINE_THREAD_SAFE_STATIC_LOCAL( | 478 DEFINE_THREAD_SAFE_STATIC_LOCAL( |
486 EnumerationHistogram, key_type_histogram, | 479 EnumerationHistogram, key_type_histogram, |
487 new EnumerationHistogram("WebCore.IndexedDB.ObjectStore.Record.KeyType", | 480 new EnumerationHistogram("WebCore.IndexedDB.ObjectStore.Record.KeyType", |
488 static_cast<int>(IDBKey::kTypeEnumMax))); | 481 static_cast<int>(IDBKey::kTypeEnumMax))); |
489 key_type_histogram.Count(static_cast<int>(key->GetType())); | 482 key_type_histogram.Count(static_cast<int>(key->GetType())); |
490 } | 483 } |
491 | 484 |
492 Vector<int64_t> index_ids; | 485 Vector<int64_t> index_ids; |
493 HeapVector<IndexKeys> index_keys; | 486 HeapVector<IndexKeys> index_keys; |
494 for (const auto& it : Metadata().indexes) { | 487 for (const auto& it : Metadata().indexes) { |
495 if (clone.IsEmpty()) { | 488 if (clone.IsEmpty()) |
496 clone = DeserializeScriptValue(script_state, serialized_value.Get(), | 489 value_wrapper.Clone(script_state, &clone); |
497 &blob_info); | |
498 } | |
499 IndexKeys keys; | 490 IndexKeys keys; |
500 GenerateIndexKeysForValue(script_state->GetIsolate(), *it.value, clone, | 491 GenerateIndexKeysForValue(script_state->GetIsolate(), *it.value, clone, |
501 &keys); | 492 &keys); |
502 index_ids.push_back(it.key); | 493 index_ids.push_back(it.key); |
503 index_keys.push_back(keys); | 494 index_keys.push_back(keys); |
504 } | 495 } |
505 | 496 |
506 IDBRequest* request = | 497 IDBRequest* request = |
507 IDBRequest::Create(script_state, source, transaction_.Get()); | 498 IDBRequest::Create(script_state, source, transaction_.Get()); |
508 Vector<char> wire_bytes; | |
509 serialized_value->ToWireBytes(wire_bytes); | |
510 RefPtr<SharedBuffer> value_buffer = SharedBuffer::AdoptVector(wire_bytes); | |
511 | 499 |
512 request->StorePutOperationBlobs(serialized_value->BlobDataHandles()); | 500 value_wrapper.ExtractBlobDataHandles(request->transit_blob_handles()); |
| 501 value_wrapper.WrapIfBiggerThan(IDBValueWrapper::kWrapThreshold); |
513 | 502 |
514 BackendDB()->Put(transaction_->Id(), Id(), WebData(value_buffer), blob_info, | 503 BackendDB()->Put( |
515 key, static_cast<WebIDBPutMode>(put_mode), | 504 transaction_->Id(), Id(), WebData(value_wrapper.ExtractWireBytes()), |
516 request->CreateWebCallbacks().release(), index_ids, | 505 value_wrapper.WrappedBlobInfo(), key, |
517 index_keys); | 506 static_cast<WebIDBPutMode>(put_mode), |
| 507 request->CreateWebCallbacks().release(), index_ids, index_keys); |
| 508 |
518 return request; | 509 return request; |
519 } | 510 } |
520 | 511 |
521 IDBRequest* IDBObjectStore::deleteFunction(ScriptState* script_state, | 512 IDBRequest* IDBObjectStore::deleteFunction(ScriptState* script_state, |
522 const ScriptValue& key, | 513 const ScriptValue& key, |
523 ExceptionState& exception_state) { | 514 ExceptionState& exception_state) { |
524 IDB_TRACE("IDBObjectStore::delete"); | 515 IDB_TRACE("IDBObjectStore::delete"); |
525 if (IsDeleted()) { | 516 if (IsDeleted()) { |
526 exception_state.ThrowDOMException( | 517 exception_state.ThrowDOMException( |
527 kInvalidStateError, IDBDatabase::kObjectStoreDeletedErrorMessage); | 518 kInvalidStateError, IDBDatabase::kObjectStoreDeletedErrorMessage); |
(...skipping 529 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1057 } | 1048 } |
1058 } | 1049 } |
1059 return IDBIndexMetadata::kInvalidId; | 1050 return IDBIndexMetadata::kInvalidId; |
1060 } | 1051 } |
1061 | 1052 |
1062 WebIDBDatabase* IDBObjectStore::BackendDB() const { | 1053 WebIDBDatabase* IDBObjectStore::BackendDB() const { |
1063 return transaction_->BackendDB(); | 1054 return transaction_->BackendDB(); |
1064 } | 1055 } |
1065 | 1056 |
1066 } // namespace blink | 1057 } // namespace blink |
OLD | NEW |