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 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
48 | 48 |
49 using blink::WebIDBCursor; | 49 using blink::WebIDBCursor; |
50 | 50 |
51 namespace blink { | 51 namespace blink { |
52 | 52 |
53 IDBRequest* IDBRequest::create(ScriptState* scriptState, | 53 IDBRequest* IDBRequest::create(ScriptState* scriptState, |
54 IDBAny* source, | 54 IDBAny* source, |
55 IDBTransaction* transaction) { | 55 IDBTransaction* transaction) { |
56 IDBRequest* request = new IDBRequest(scriptState, source, transaction); | 56 IDBRequest* request = new IDBRequest(scriptState, source, transaction); |
57 request->suspendIfNeeded(); | 57 request->suspendIfNeeded(); |
58 // Requests associated with IDBFactory (open/deleteDatabase/getDatabaseNames)
are not associated with transactions. | 58 // Requests associated with IDBFactory (open/deleteDatabase/getDatabaseNames) |
| 59 // are not associated with transactions. |
59 if (transaction) | 60 if (transaction) |
60 transaction->registerRequest(request); | 61 transaction->registerRequest(request); |
61 return request; | 62 return request; |
62 } | 63 } |
63 | 64 |
64 IDBRequest::IDBRequest(ScriptState* scriptState, | 65 IDBRequest::IDBRequest(ScriptState* scriptState, |
65 IDBAny* source, | 66 IDBAny* source, |
66 IDBTransaction* transaction) | 67 IDBTransaction* transaction) |
67 : ActiveScriptWrappable(this), | 68 : ActiveScriptWrappable(this), |
68 ActiveDOMObject(scriptState->getExecutionContext()), | 69 ActiveDOMObject(scriptState->getExecutionContext()), |
(...skipping 14 matching lines...) Expand all Loading... |
83 visitor->trace(m_enqueuedEvents); | 84 visitor->trace(m_enqueuedEvents); |
84 visitor->trace(m_pendingCursor); | 85 visitor->trace(m_pendingCursor); |
85 visitor->trace(m_cursorKey); | 86 visitor->trace(m_cursorKey); |
86 visitor->trace(m_cursorPrimaryKey); | 87 visitor->trace(m_cursorPrimaryKey); |
87 EventTargetWithInlineData::trace(visitor); | 88 EventTargetWithInlineData::trace(visitor); |
88 ActiveDOMObject::trace(visitor); | 89 ActiveDOMObject::trace(visitor); |
89 } | 90 } |
90 | 91 |
91 ScriptValue IDBRequest::result(ExceptionState& exceptionState) { | 92 ScriptValue IDBRequest::result(ExceptionState& exceptionState) { |
92 if (m_readyState != DONE) { | 93 if (m_readyState != DONE) { |
93 // Must throw if returning an empty value. Message is arbitrary since it wil
l never be seen. | 94 // Must throw if returning an empty value. Message is arbitrary since it |
| 95 // will never be seen. |
94 exceptionState.throwDOMException( | 96 exceptionState.throwDOMException( |
95 InvalidStateError, IDBDatabase::requestNotFinishedErrorMessage); | 97 InvalidStateError, IDBDatabase::requestNotFinishedErrorMessage); |
96 return ScriptValue(); | 98 return ScriptValue(); |
97 } | 99 } |
98 if (m_contextStopped || !getExecutionContext()) { | 100 if (m_contextStopped || !getExecutionContext()) { |
99 exceptionState.throwDOMException(InvalidStateError, | 101 exceptionState.throwDOMException(InvalidStateError, |
100 IDBDatabase::databaseClosedErrorMessage); | 102 IDBDatabase::databaseClosedErrorMessage); |
101 return ScriptValue(); | 103 return ScriptValue(); |
102 } | 104 } |
103 m_resultDirty = false; | 105 m_resultDirty = false; |
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
361 PassRefPtr<IDBValue> value) { | 363 PassRefPtr<IDBValue> value) { |
362 IDB_TRACE("IDBRequest::onSuccess(key, primaryKey, value)"); | 364 IDB_TRACE("IDBRequest::onSuccess(key, primaryKey, value)"); |
363 if (!shouldEnqueueEvent()) | 365 if (!shouldEnqueueEvent()) |
364 return; | 366 return; |
365 | 367 |
366 DCHECK(m_pendingCursor); | 368 DCHECK(m_pendingCursor); |
367 setResultCursor(m_pendingCursor.release(), key, primaryKey, std::move(value)); | 369 setResultCursor(m_pendingCursor.release(), key, primaryKey, std::move(value)); |
368 } | 370 } |
369 | 371 |
370 bool IDBRequest::hasPendingActivity() const { | 372 bool IDBRequest::hasPendingActivity() const { |
371 // FIXME: In an ideal world, we should return true as long as anyone has a or
can | 373 // FIXME: In an ideal world, we should return true as long as anyone has a or |
372 // get a handle to us and we have event listeners. This is order to han
dle | 374 // can get a handle to us and we have event listeners. This is order to |
373 // user generated events properly. | 375 // handle user generated events properly. |
374 return m_hasPendingActivity && !m_contextStopped; | 376 return m_hasPendingActivity && !m_contextStopped; |
375 } | 377 } |
376 | 378 |
377 void IDBRequest::contextDestroyed() { | 379 void IDBRequest::contextDestroyed() { |
378 if (m_contextStopped) | 380 if (m_contextStopped) |
379 return; | 381 return; |
380 | 382 |
381 m_contextStopped = true; | 383 m_contextStopped = true; |
382 | 384 |
383 if (m_readyState == PENDING) { | 385 if (m_readyState == PENDING) { |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
424 targets.append(this); | 426 targets.append(this); |
425 if (m_transaction && !m_preventPropagation) { | 427 if (m_transaction && !m_preventPropagation) { |
426 targets.append(m_transaction); | 428 targets.append(m_transaction); |
427 // If there ever are events that are associated with a database but | 429 // If there ever are events that are associated with a database but |
428 // that do not have a transaction, then this will not work and we need | 430 // that do not have a transaction, then this will not work and we need |
429 // this object to actually hold a reference to the database (to ensure | 431 // this object to actually hold a reference to the database (to ensure |
430 // it stays alive). | 432 // it stays alive). |
431 targets.append(m_transaction->db()); | 433 targets.append(m_transaction->db()); |
432 } | 434 } |
433 | 435 |
434 // Cursor properties should not be updated until the success event is being di
spatched. | 436 // Cursor properties should not be updated until the success event is being |
| 437 // dispatched. |
435 IDBCursor* cursorToNotify = nullptr; | 438 IDBCursor* cursorToNotify = nullptr; |
436 if (event->type() == EventTypeNames::success) { | 439 if (event->type() == EventTypeNames::success) { |
437 cursorToNotify = getResultCursor(); | 440 cursorToNotify = getResultCursor(); |
438 if (cursorToNotify) | 441 if (cursorToNotify) |
439 cursorToNotify->setValueReady(m_cursorKey.release(), | 442 cursorToNotify->setValueReady(m_cursorKey.release(), |
440 m_cursorPrimaryKey.release(), | 443 m_cursorPrimaryKey.release(), |
441 m_cursorValue.release()); | 444 m_cursorValue.release()); |
442 } | 445 } |
443 | 446 |
444 if (event->type() == EventTypeNames::upgradeneeded) { | 447 if (event->type() == EventTypeNames::upgradeneeded) { |
445 DCHECK(!m_didFireUpgradeNeededEvent); | 448 DCHECK(!m_didFireUpgradeNeededEvent); |
446 m_didFireUpgradeNeededEvent = true; | 449 m_didFireUpgradeNeededEvent = true; |
447 } | 450 } |
448 | 451 |
449 // FIXME: When we allow custom event dispatching, this will probably need to c
hange. | 452 // FIXME: When we allow custom event dispatching, this will probably need to |
| 453 // change. |
450 DCHECK(event->type() == EventTypeNames::success || | 454 DCHECK(event->type() == EventTypeNames::success || |
451 event->type() == EventTypeNames::error || | 455 event->type() == EventTypeNames::error || |
452 event->type() == EventTypeNames::blocked || | 456 event->type() == EventTypeNames::blocked || |
453 event->type() == EventTypeNames::upgradeneeded) | 457 event->type() == EventTypeNames::upgradeneeded) |
454 << "event type was " << event->type(); | 458 << "event type was " << event->type(); |
455 const bool setTransactionActive = | 459 const bool setTransactionActive = |
456 m_transaction && | 460 m_transaction && |
457 (event->type() == EventTypeNames::success || | 461 (event->type() == EventTypeNames::success || |
458 event->type() == EventTypeNames::upgradeneeded || | 462 event->type() == EventTypeNames::upgradeneeded || |
459 (event->type() == EventTypeNames::error && !m_requestAborted)); | 463 (event->type() == EventTypeNames::error && !m_requestAborted)); |
460 | 464 |
461 if (setTransactionActive) | 465 if (setTransactionActive) |
462 m_transaction->setActive(true); | 466 m_transaction->setActive(true); |
463 | 467 |
464 DispatchEventResult dispatchResult = | 468 DispatchEventResult dispatchResult = |
465 IDBEventDispatcher::dispatch(event, targets); | 469 IDBEventDispatcher::dispatch(event, targets); |
466 | 470 |
467 if (m_transaction) { | 471 if (m_transaction) { |
468 if (m_readyState == DONE) | 472 if (m_readyState == DONE) |
469 m_transaction->unregisterRequest(this); | 473 m_transaction->unregisterRequest(this); |
470 | 474 |
471 // Possibly abort the transaction. This must occur after unregistering (so t
his request | 475 // Possibly abort the transaction. This must occur after unregistering (so |
472 // doesn't receive a second error) and before deactivating (which might trig
ger commit). | 476 // this request doesn't receive a second error) and before deactivating |
| 477 // (which might trigger commit). |
473 if (event->type() == EventTypeNames::error && | 478 if (event->type() == EventTypeNames::error && |
474 dispatchResult == DispatchEventResult::NotCanceled && | 479 dispatchResult == DispatchEventResult::NotCanceled && |
475 !m_requestAborted) { | 480 !m_requestAborted) { |
476 m_transaction->setError(m_error); | 481 m_transaction->setError(m_error); |
477 m_transaction->abort(IGNORE_EXCEPTION); | 482 m_transaction->abort(IGNORE_EXCEPTION); |
478 } | 483 } |
479 | 484 |
480 // If this was the last request in the transaction's list, it may commit her
e. | 485 // If this was the last request in the transaction's list, it may commit |
| 486 // here. |
481 if (setTransactionActive) | 487 if (setTransactionActive) |
482 m_transaction->setActive(false); | 488 m_transaction->setActive(false); |
483 } | 489 } |
484 | 490 |
485 if (cursorToNotify) | 491 if (cursorToNotify) |
486 cursorToNotify->postSuccessHandlerCallback(); | 492 cursorToNotify->postSuccessHandlerCallback(); |
487 | 493 |
488 // An upgradeneeded event will always be followed by a success or error event,
so must | 494 // An upgradeneeded event will always be followed by a success or error event, |
489 // be kept alive. | 495 // so must be kept alive. |
490 if (m_readyState == DONE && event->type() != EventTypeNames::upgradeneeded) | 496 if (m_readyState == DONE && event->type() != EventTypeNames::upgradeneeded) |
491 m_hasPendingActivity = false; | 497 m_hasPendingActivity = false; |
492 | 498 |
493 return dispatchResult; | 499 return dispatchResult; |
494 } | 500 } |
495 | 501 |
496 void IDBRequest::uncaughtExceptionInEventHandler() { | 502 void IDBRequest::uncaughtExceptionInEventHandler() { |
497 if (m_transaction && !m_requestAborted) { | 503 if (m_transaction && !m_requestAborted) { |
498 m_transaction->setError(DOMException::create( | 504 m_transaction->setError(DOMException::create( |
499 AbortError, "Uncaught exception in event handler.")); | 505 AbortError, "Uncaught exception in event handler.")); |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
536 } | 542 } |
537 | 543 |
538 void IDBRequest::dequeueEvent(Event* event) { | 544 void IDBRequest::dequeueEvent(Event* event) { |
539 for (size_t i = 0; i < m_enqueuedEvents.size(); ++i) { | 545 for (size_t i = 0; i < m_enqueuedEvents.size(); ++i) { |
540 if (m_enqueuedEvents[i].get() == event) | 546 if (m_enqueuedEvents[i].get() == event) |
541 m_enqueuedEvents.remove(i); | 547 m_enqueuedEvents.remove(i); |
542 } | 548 } |
543 } | 549 } |
544 | 550 |
545 } // namespace blink | 551 } // namespace blink |
OLD | NEW |