Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(199)

Side by Side Diff: third_party/WebKit/Source/modules/indexeddb/IDBRequest.cpp

Issue 2822453003: Wrap large IndexedDB values into Blobs before writing to LevelDB. (Closed)
Patch Set: Rebased. Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 11 matching lines...) Expand all
22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */ 27 */
28 28
29 #include "modules/indexeddb/IDBRequest.h" 29 #include "modules/indexeddb/IDBRequest.h"
30 30
31 #include <memory> 31 #include <memory>
32 #include <utility>
33
32 #include "bindings/core/v8/ExceptionState.h" 34 #include "bindings/core/v8/ExceptionState.h"
33 #include "bindings/core/v8/ToV8ForCore.h" 35 #include "bindings/core/v8/ToV8ForCore.h"
34 #include "bindings/modules/v8/ToV8ForModules.h" 36 #include "bindings/modules/v8/ToV8ForModules.h"
35 #include "bindings/modules/v8/V8BindingForModules.h" 37 #include "bindings/modules/v8/V8BindingForModules.h"
36 #include "core/dom/DOMException.h" 38 #include "core/dom/DOMException.h"
37 #include "core/dom/ExceptionCode.h" 39 #include "core/dom/ExceptionCode.h"
38 #include "core/dom/ExecutionContext.h" 40 #include "core/dom/ExecutionContext.h"
39 #include "core/events/EventQueue.h" 41 #include "core/events/EventQueue.h"
40 #include "modules/IndexedDBNames.h" 42 #include "modules/IndexedDBNames.h"
41 #include "modules/indexeddb/IDBCursorWithValue.h" 43 #include "modules/indexeddb/IDBCursorWithValue.h"
42 #include "modules/indexeddb/IDBDatabase.h" 44 #include "modules/indexeddb/IDBDatabase.h"
43 #include "modules/indexeddb/IDBEventDispatcher.h" 45 #include "modules/indexeddb/IDBEventDispatcher.h"
46 #include "modules/indexeddb/IDBRequestQueueItem.h"
44 #include "modules/indexeddb/IDBTracing.h" 47 #include "modules/indexeddb/IDBTracing.h"
45 #include "modules/indexeddb/IDBValue.h" 48 #include "modules/indexeddb/IDBValue.h"
49 #include "modules/indexeddb/IDBValueWrapping.h"
46 #include "modules/indexeddb/WebIDBCallbacksImpl.h" 50 #include "modules/indexeddb/WebIDBCallbacksImpl.h"
47 #include "platform/SharedBuffer.h" 51 #include "platform/SharedBuffer.h"
52 #include "platform/wtf/PtrUtil.h"
48 #include "public/platform/WebBlobInfo.h" 53 #include "public/platform/WebBlobInfo.h"
49 54
50 using blink::WebIDBCursor; 55 using blink::WebIDBCursor;
51 56
52 namespace blink { 57 namespace blink {
53 58
54 IDBRequest* IDBRequest::Create(ScriptState* script_state, 59 IDBRequest* IDBRequest::Create(ScriptState* script_state,
55 IDBAny* source, 60 IDBAny* source,
56 IDBTransaction* transaction) { 61 IDBTransaction* transaction) {
57 IDBRequest* request = new IDBRequest(script_state, source, transaction); 62 IDBRequest* request = new IDBRequest(script_state, source, transaction);
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
193 if (result_->GetType() == IDBAny::kIDBCursorType) 198 if (result_->GetType() == IDBAny::kIDBCursorType)
194 return result_->IdbCursor(); 199 return result_->IdbCursor();
195 if (result_->GetType() == IDBAny::kIDBCursorWithValueType) 200 if (result_->GetType() == IDBAny::kIDBCursorWithValueType)
196 return result_->IdbCursorWithValue(); 201 return result_->IdbCursorWithValue();
197 return nullptr; 202 return nullptr;
198 } 203 }
199 204
200 void IDBRequest::SetResultCursor(IDBCursor* cursor, 205 void IDBRequest::SetResultCursor(IDBCursor* cursor,
201 IDBKey* key, 206 IDBKey* key,
202 IDBKey* primary_key, 207 IDBKey* primary_key,
203 PassRefPtr<IDBValue> value) { 208 RefPtr<IDBValue>&& value) {
204 DCHECK_EQ(ready_state_, PENDING); 209 DCHECK_EQ(ready_state_, PENDING);
205 cursor_key_ = key; 210 cursor_key_ = key;
206 cursor_primary_key_ = primary_key; 211 cursor_primary_key_ = primary_key;
207 cursor_value_ = std::move(value); 212 cursor_value_ = std::move(value);
208 AckReceivedBlobs(cursor_value_.Get()); 213 AckReceivedBlobs(cursor_value_.Get());
209 214
210 EnqueueResultInternal(IDBAny::Create(cursor)); 215 EnqueueResultInternal(IDBAny::Create(cursor));
211 } 216 }
212 217
213 void IDBRequest::AckReceivedBlobs(const IDBValue* value) { 218 void IDBRequest::AckReceivedBlobs(const IDBValue* value) {
(...skipping 13 matching lines...) Expand all
227 if (!GetExecutionContext()) 232 if (!GetExecutionContext())
228 return false; 233 return false;
229 DCHECK(ready_state_ == PENDING || ready_state_ == DONE); 234 DCHECK(ready_state_ == PENDING || ready_state_ == DONE);
230 if (request_aborted_) 235 if (request_aborted_)
231 return false; 236 return false;
232 DCHECK_EQ(ready_state_, PENDING); 237 DCHECK_EQ(ready_state_, PENDING);
233 DCHECK(!error_ && !result_); 238 DCHECK(!error_ && !result_);
234 return true; 239 return true;
235 } 240 }
236 241
242 void IDBRequest::HandleResponse(DOMException* error) {
243 transit_blob_handles_.clear();
244 if (!transaction_ || !transaction_->HasQueuedResults())
245 return EnqueueResponse(error);
246 transaction_->EnqueueResult(
247 WTF::MakeUnique<IDBRequestQueueItem>(this, error));
248 }
249
250 void IDBRequest::HandleResponse(IDBKey* key) {
251 transit_blob_handles_.clear();
252 DCHECK(transaction_);
253 if (!transaction_->HasQueuedResults())
254 return EnqueueResponse(key);
255 transaction_->EnqueueResult(WTF::MakeUnique<IDBRequestQueueItem>(this, key));
256 }
257
258 void IDBRequest::HandleResponse(int64_t value_or_old_version) {
259 transit_blob_handles_.clear();
260 if (!transaction_ || !transaction_->HasQueuedResults())
261 return EnqueueResponse(value_or_old_version);
262 transaction_->EnqueueResult(
263 WTF::MakeUnique<IDBRequestQueueItem>(this, value_or_old_version));
264 }
265
266 void IDBRequest::HandleResponse() {
267 transit_blob_handles_.clear();
268 if (!transaction_ || !transaction_->HasQueuedResults())
269 return EnqueueResponse();
270 transaction_->EnqueueResult(WTF::MakeUnique<IDBRequestQueueItem>(this));
271 }
272
273 void IDBRequest::HandleResponse(std::unique_ptr<WebIDBCursor> backend,
274 IDBKey* key,
275 IDBKey* primary_key,
276 RefPtr<IDBValue>&& value) {
277 bool is_wrapped = IDBValueUnwrapper::IsWrapped(value.Get());
278 DCHECK(transaction_);
279 if (!transaction_->HasQueuedResults() && !is_wrapped) {
280 return EnqueueResponse(std::move(backend), key, primary_key,
281 std::move(value));
282 }
283 transaction_->EnqueueResult(WTF::MakeUnique<IDBRequestQueueItem>(
284 this, std::move(backend), key, primary_key, std::move(value),
285 is_wrapped));
286 }
287
288 void IDBRequest::HandleResponse(RefPtr<IDBValue>&& value) {
289 bool is_wrapped = IDBValueUnwrapper::IsWrapped(value.Get());
290 DCHECK(transaction_);
291 if (!transaction_->HasQueuedResults() && !is_wrapped)
292 return EnqueueResponse(std::move(value));
293 transaction_->EnqueueResult(
294 WTF::MakeUnique<IDBRequestQueueItem>(this, std::move(value), is_wrapped));
295 }
296
297 void IDBRequest::HandleResponse(const Vector<RefPtr<IDBValue>>& values) {
298 bool is_wrapped = IDBValueUnwrapper::IsWrapped(values);
299 DCHECK(transaction_);
300 if (!transaction_->HasQueuedResults() && !is_wrapped)
301 return EnqueueResponse(values);
302 transaction_->EnqueueResult(
303 WTF::MakeUnique<IDBRequestQueueItem>(this, values, is_wrapped));
304 }
305
306 void IDBRequest::HandleResponse(IDBKey* key,
307 IDBKey* primary_key,
308 RefPtr<IDBValue>&& value) {
309 bool is_wrapped = IDBValueUnwrapper::IsWrapped(value.Get());
310
311 DCHECK(transaction_);
312 if (!transaction_->HasQueuedResults() && !is_wrapped)
313 return EnqueueResponse(key, primary_key, std::move(value));
314
315 transaction_->EnqueueResult(WTF::MakeUnique<IDBRequestQueueItem>(
316 this, key, primary_key, std::move(value), is_wrapped));
317 }
318
237 void IDBRequest::EnqueueResponse(DOMException* error) { 319 void IDBRequest::EnqueueResponse(DOMException* error) {
238 IDB_TRACE("IDBRequest::onError()"); 320 IDB_TRACE("IDBRequest::EnqueueResponse(DOMException)");
239 ClearPutOperationBlobs();
240 if (!ShouldEnqueueEvent()) 321 if (!ShouldEnqueueEvent())
241 return; 322 return;
242 323
243 error_ = error; 324 error_ = error;
244 SetResult(IDBAny::CreateUndefined()); 325 SetResult(IDBAny::CreateUndefined());
245 pending_cursor_.Clear(); 326 pending_cursor_.Clear();
246 EnqueueEvent(Event::CreateCancelableBubble(EventTypeNames::error)); 327 EnqueueEvent(Event::CreateCancelableBubble(EventTypeNames::error));
247 } 328 }
248 329
249 void IDBRequest::EnqueueResponse(const Vector<String>& string_list) { 330 void IDBRequest::EnqueueResponse(const Vector<String>& string_list) {
250 IDB_TRACE("IDBRequest::onSuccess(StringList)"); 331 IDB_TRACE("IDBRequest::onSuccess(StringList)");
251 if (!ShouldEnqueueEvent()) 332 if (!ShouldEnqueueEvent())
252 return; 333 return;
253 334
254 DOMStringList* dom_string_list = DOMStringList::Create(); 335 DOMStringList* dom_string_list = DOMStringList::Create();
255 for (size_t i = 0; i < string_list.size(); ++i) 336 for (size_t i = 0; i < string_list.size(); ++i)
256 dom_string_list->Append(string_list[i]); 337 dom_string_list->Append(string_list[i]);
257 EnqueueResultInternal(IDBAny::Create(dom_string_list)); 338 EnqueueResultInternal(IDBAny::Create(dom_string_list));
258 } 339 }
259 340
260 void IDBRequest::EnqueueResponse(std::unique_ptr<WebIDBCursor> backend, 341 void IDBRequest::EnqueueResponse(std::unique_ptr<WebIDBCursor> backend,
261 IDBKey* key, 342 IDBKey* key,
262 IDBKey* primary_key, 343 IDBKey* primary_key,
263 PassRefPtr<IDBValue> value) { 344 RefPtr<IDBValue>&& value) {
264 IDB_TRACE("IDBRequest::onSuccess(IDBCursor)"); 345 IDB_TRACE("IDBRequest::EnqueueResponse(IDBCursor)");
265 if (!ShouldEnqueueEvent()) 346 if (!ShouldEnqueueEvent())
266 return; 347 return;
267 348
268 DCHECK(!pending_cursor_); 349 DCHECK(!pending_cursor_);
269 IDBCursor* cursor = nullptr; 350 IDBCursor* cursor = nullptr;
270 switch (cursor_type_) { 351 switch (cursor_type_) {
271 case IndexedDB::kCursorKeyOnly: 352 case IndexedDB::kCursorKeyOnly:
272 cursor = IDBCursor::Create(std::move(backend), cursor_direction_, this, 353 cursor = IDBCursor::Create(std::move(backend), cursor_direction_, this,
273 source_.Get(), transaction_.Get()); 354 source_.Get(), transaction_.Get());
274 break; 355 break;
275 case IndexedDB::kCursorKeyAndValue: 356 case IndexedDB::kCursorKeyAndValue:
276 cursor = 357 cursor =
277 IDBCursorWithValue::Create(std::move(backend), cursor_direction_, 358 IDBCursorWithValue::Create(std::move(backend), cursor_direction_,
278 this, source_.Get(), transaction_.Get()); 359 this, source_.Get(), transaction_.Get());
279 break; 360 break;
280 default: 361 default:
281 NOTREACHED(); 362 NOTREACHED();
282 } 363 }
283 SetResultCursor(cursor, key, primary_key, std::move(value)); 364 SetResultCursor(cursor, key, primary_key, std::move(value));
284 } 365 }
285 366
286 void IDBRequest::EnqueueResponse(IDBKey* idb_key) { 367 void IDBRequest::EnqueueResponse(IDBKey* idb_key) {
287 IDB_TRACE("IDBRequest::onSuccess(IDBKey)"); 368 IDB_TRACE("IDBRequest::EnqueueResponse(IDBKey)");
288 ClearPutOperationBlobs();
289 if (!ShouldEnqueueEvent()) 369 if (!ShouldEnqueueEvent())
290 return; 370 return;
291 371
292 if (idb_key && idb_key->IsValid()) 372 if (idb_key && idb_key->IsValid())
293 EnqueueResultInternal(IDBAny::Create(idb_key)); 373 EnqueueResultInternal(IDBAny::Create(idb_key));
294 else 374 else
295 EnqueueResultInternal(IDBAny::CreateUndefined()); 375 EnqueueResultInternal(IDBAny::CreateUndefined());
296 } 376 }
297 377
298 void IDBRequest::EnqueueResponse(const Vector<RefPtr<IDBValue>>& values) { 378 void IDBRequest::EnqueueResponse(const Vector<RefPtr<IDBValue>>& values) {
299 IDB_TRACE("IDBRequest::onSuccess([IDBValue])"); 379 IDB_TRACE("IDBRequest::EnqueueResponse([IDBValue])");
300 if (!ShouldEnqueueEvent()) 380 if (!ShouldEnqueueEvent())
301 return; 381 return;
302 382
303 AckReceivedBlobs(values); 383 AckReceivedBlobs(values);
304 EnqueueResultInternal(IDBAny::Create(values)); 384 EnqueueResultInternal(IDBAny::Create(values));
305 } 385 }
306 386
307 #if DCHECK_IS_ON() 387 #if DCHECK_IS_ON()
308 static IDBObjectStore* EffectiveObjectStore(IDBAny* source) { 388 static IDBObjectStore* EffectiveObjectStore(IDBAny* source) {
309 if (source->GetType() == IDBAny::kIDBObjectStoreType) 389 if (source->GetType() == IDBAny::kIDBObjectStoreType)
310 return source->IdbObjectStore(); 390 return source->IdbObjectStore();
311 if (source->GetType() == IDBAny::kIDBIndexType) 391 if (source->GetType() == IDBAny::kIDBIndexType)
312 return source->IdbIndex()->objectStore(); 392 return source->IdbIndex()->objectStore();
313 393
314 NOTREACHED(); 394 NOTREACHED();
315 return nullptr; 395 return nullptr;
316 } 396 }
317 #endif // DCHECK_IS_ON() 397 #endif // DCHECK_IS_ON()
318 398
319 void IDBRequest::EnqueueResponse(PassRefPtr<IDBValue> prp_value) { 399 void IDBRequest::EnqueueResponse(RefPtr<IDBValue>&& value) {
320 IDB_TRACE("IDBRequest::onSuccess(IDBValue)"); 400 IDB_TRACE("IDBRequest::EnqueueResponse(IDBValue)");
321 if (!ShouldEnqueueEvent()) 401 if (!ShouldEnqueueEvent())
322 return; 402 return;
323 403
324 RefPtr<IDBValue> value(std::move(prp_value));
325 AckReceivedBlobs(value.Get()); 404 AckReceivedBlobs(value.Get());
326 405
327 if (pending_cursor_) { 406 if (pending_cursor_) {
328 // Value should be null, signifying the end of the cursor's range. 407 // Value should be null, signifying the end of the cursor's range.
329 DCHECK(value->IsNull()); 408 DCHECK(value->IsNull());
330 DCHECK(!value->BlobInfo()->size()); 409 DCHECK(!value->BlobInfo()->size());
331 pending_cursor_->Close(); 410 pending_cursor_->Close();
332 pending_cursor_.Clear(); 411 pending_cursor_.Clear();
333 } 412 }
334 413
335 #if DCHECK_IS_ON() 414 #if DCHECK_IS_ON()
336 DCHECK(!value->PrimaryKey() || 415 DCHECK(!value->PrimaryKey() ||
337 value->KeyPath() == EffectiveObjectStore(source_)->IdbKeyPath()); 416 value->KeyPath() == EffectiveObjectStore(source_)->IdbKeyPath());
338 #endif 417 #endif
339 418
340 EnqueueResultInternal(IDBAny::Create(value.Release())); 419 EnqueueResultInternal(IDBAny::Create(std::move(value)));
341 } 420 }
342 421
343 void IDBRequest::EnqueueResponse(int64_t value) { 422 void IDBRequest::EnqueueResponse(int64_t value) {
344 IDB_TRACE("IDBRequest::onSuccess(int64_t)"); 423 IDB_TRACE("IDBRequest::EnqueueResponse(int64_t)");
345 if (!ShouldEnqueueEvent()) 424 if (!ShouldEnqueueEvent())
346 return; 425 return;
347 EnqueueResultInternal(IDBAny::Create(value)); 426 EnqueueResultInternal(IDBAny::Create(value));
348 } 427 }
349 428
350 void IDBRequest::EnqueueResponse() { 429 void IDBRequest::EnqueueResponse() {
351 IDB_TRACE("IDBRequest::onSuccess()"); 430 IDB_TRACE("IDBRequest::EnqueueResponse()");
352 if (!ShouldEnqueueEvent()) 431 if (!ShouldEnqueueEvent())
353 return; 432 return;
354 EnqueueResultInternal(IDBAny::CreateUndefined()); 433 EnqueueResultInternal(IDBAny::CreateUndefined());
355 } 434 }
356 435
357 void IDBRequest::EnqueueResultInternal(IDBAny* result) { 436 void IDBRequest::EnqueueResultInternal(IDBAny* result) {
358 DCHECK(GetExecutionContext()); 437 DCHECK(GetExecutionContext());
359 DCHECK(!pending_cursor_); 438 DCHECK(!pending_cursor_);
360 DCHECK(transit_blob_handles_.IsEmpty()); 439 DCHECK(transit_blob_handles_.IsEmpty());
361 SetResult(result); 440 SetResult(result);
362 EnqueueEvent(Event::Create(EventTypeNames::success)); 441 EnqueueEvent(Event::Create(EventTypeNames::success));
363 } 442 }
364 443
365 void IDBRequest::SetResult(IDBAny* result) { 444 void IDBRequest::SetResult(IDBAny* result) {
366 result_ = result; 445 result_ = result;
367 result_dirty_ = true; 446 result_dirty_ = true;
368 } 447 }
369 448
370 void IDBRequest::EnqueueResponse(IDBKey* key, 449 void IDBRequest::EnqueueResponse(IDBKey* key,
371 IDBKey* primary_key, 450 IDBKey* primary_key,
372 PassRefPtr<IDBValue> value) { 451 RefPtr<IDBValue>&& value) {
373 IDB_TRACE("IDBRequest::onSuccess(key, primaryKey, value)"); 452 IDB_TRACE("IDBRequest::EnqueueResponse(IDBKey, IDBKey primaryKey, IDBValue)");
374 if (!ShouldEnqueueEvent()) 453 if (!ShouldEnqueueEvent())
375 return; 454 return;
376 455
377 DCHECK(pending_cursor_); 456 DCHECK(pending_cursor_);
378 SetResultCursor(pending_cursor_.Release(), key, primary_key, 457 SetResultCursor(pending_cursor_.Release(), key, primary_key,
379 std::move(value)); 458 std::move(value));
380 } 459 }
381 460
382 bool IDBRequest::HasPendingActivity() const { 461 bool IDBRequest::HasPendingActivity() const {
383 // FIXME: In an ideal world, we should return true as long as anyone has a or 462 // FIXME: In an ideal world, we should return true as long as anyone has a or
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
553 } 632 }
554 633
555 void IDBRequest::DequeueEvent(Event* event) { 634 void IDBRequest::DequeueEvent(Event* event) {
556 for (size_t i = 0; i < enqueued_events_.size(); ++i) { 635 for (size_t i = 0; i < enqueued_events_.size(); ++i) {
557 if (enqueued_events_[i].Get() == event) 636 if (enqueued_events_[i].Get() == event)
558 enqueued_events_.erase(i); 637 enqueued_events_.erase(i);
559 } 638 }
560 } 639 }
561 640
562 } // namespace blink 641 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698