WebCore/storage/IDBRequest.cpp
changeset 0 4f2f89ce4247
equal deleted inserted replaced
-1:000000000000 0:4f2f89ce4247
       
     1 /*
       
     2  * Copyright (C) 2010 Google Inc. All rights reserved.
       
     3  *
       
     4  * Redistribution and use in source and binary forms, with or without
       
     5  * modification, are permitted provided that the following conditions
       
     6  * are met:
       
     7  *
       
     8  * 1.  Redistributions of source code must retain the above copyright
       
     9  *     notice, this list of conditions and the following disclaimer.
       
    10  * 2.  Redistributions in binary form must reproduce the above copyright
       
    11  *     notice, this list of conditions and the following disclaimer in the
       
    12  *     documentation and/or other materials provided with the distribution.
       
    13  * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
       
    14  *     its contributors may be used to endorse or promote products derived
       
    15  *     from this software without specific prior written permission.
       
    16  *
       
    17  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
       
    18  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
       
    19  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
       
    20  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
       
    21  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
       
    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
       
    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
       
    26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
       
    27  */
       
    28 
       
    29 #include "config.h"
       
    30 #include "IDBRequest.h"
       
    31 
       
    32 #if ENABLE(INDEXED_DATABASE)
       
    33 
       
    34 #include "Event.h"
       
    35 #include "EventException.h"
       
    36 #include "EventListener.h"
       
    37 #include "EventNames.h"
       
    38 #include "IDBDatabaseRequest.h"
       
    39 #include "IDBIndexRequest.h"
       
    40 #include "IDBErrorEvent.h"
       
    41 #include "IDBObjectStoreRequest.h"
       
    42 #include "IDBSuccessEvent.h"
       
    43 #include "ScriptExecutionContext.h"
       
    44 
       
    45 namespace WebCore {
       
    46 
       
    47 IDBRequest::IDBRequest(ScriptExecutionContext* context, PassRefPtr<IDBAny> source)
       
    48     : ActiveDOMObject(context, this)
       
    49     , m_source(source)
       
    50     , m_result(IDBAny::create())
       
    51     , m_timer(this, &IDBRequest::timerFired)
       
    52     , m_stopped(false)
       
    53     , m_aborted(false)
       
    54     , m_readyState(INITIAL)
       
    55 {
       
    56 }
       
    57 
       
    58 IDBRequest::~IDBRequest()
       
    59 {
       
    60     if (m_readyState != DONE)
       
    61         abort();
       
    62 }
       
    63 
       
    64 void IDBRequest::onError(PassRefPtr<IDBDatabaseError> error)
       
    65 {
       
    66     onEventCommon();
       
    67     m_error = error;
       
    68 }
       
    69 
       
    70 void IDBRequest::onSuccess()
       
    71 {
       
    72     onEventCommon();
       
    73     m_result->set();
       
    74 }
       
    75 
       
    76 void IDBRequest::onSuccess(PassRefPtr<IDBDatabase> idbDatabase)
       
    77 {
       
    78     onEventCommon();
       
    79     m_result->set(IDBDatabaseRequest::create(idbDatabase));
       
    80 }
       
    81 
       
    82 void IDBRequest::onSuccess(PassRefPtr<IDBIndex> idbIndex)
       
    83 {
       
    84     onEventCommon();
       
    85     m_result->set(IDBIndexRequest::create(idbIndex));
       
    86 }
       
    87 
       
    88 void IDBRequest::onSuccess(PassRefPtr<IDBKey> idbKey)
       
    89 {
       
    90     onEventCommon();
       
    91     m_result->set(idbKey);
       
    92 }
       
    93 
       
    94 void IDBRequest::onSuccess(PassRefPtr<IDBObjectStore> idbObjectStore)
       
    95 {
       
    96     onEventCommon();
       
    97     m_result->set(IDBObjectStoreRequest::create(idbObjectStore));
       
    98 }
       
    99 
       
   100 void IDBRequest::onSuccess(PassRefPtr<SerializedScriptValue> serializedScriptValue)
       
   101 {
       
   102     onEventCommon();
       
   103     m_result->set(serializedScriptValue);
       
   104 }
       
   105 
       
   106 void IDBRequest::abort()
       
   107 {
       
   108     m_timer.stop();
       
   109     m_aborted = true;
       
   110     // FIXME: This should cancel any pending work being done in the backend.
       
   111 }
       
   112 
       
   113 ScriptExecutionContext* IDBRequest::scriptExecutionContext() const
       
   114 {
       
   115     return ActiveDOMObject::scriptExecutionContext();
       
   116 }
       
   117 
       
   118 void IDBRequest::stop()
       
   119 {
       
   120     abort();
       
   121     m_selfRef = 0; // Could trigger a delete.
       
   122 }
       
   123 
       
   124 void IDBRequest::suspend()
       
   125 {
       
   126     m_timer.stop();
       
   127     m_stopped = true;
       
   128 }
       
   129 
       
   130 void IDBRequest::resume()
       
   131 {
       
   132     m_stopped = false;
       
   133     // We only hold our self ref when we're waiting to dispatch an event.
       
   134     if (m_selfRef && !m_aborted)
       
   135         m_timer.startOneShot(0);
       
   136 }
       
   137 
       
   138 EventTargetData* IDBRequest::eventTargetData()
       
   139 {
       
   140     return &m_eventTargetData;
       
   141 }
       
   142 
       
   143 EventTargetData* IDBRequest::ensureEventTargetData()
       
   144 {
       
   145     return &m_eventTargetData;
       
   146 }
       
   147 
       
   148 void IDBRequest::timerFired(Timer<IDBRequest>*)
       
   149 {
       
   150     ASSERT(m_readyState == DONE);
       
   151     ASSERT(m_selfRef);
       
   152     ASSERT(!m_stopped);
       
   153     ASSERT(!m_aborted);
       
   154 
       
   155     // We need to keep self-referencing ourself, otherwise it's possible we'll be deleted.
       
   156     // But in some cases, suspend() could be called while we're dispatching an event, so we
       
   157     // need to make sure that resume() doesn't re-start the timer based on m_selfRef being set.
       
   158     RefPtr<IDBRequest> selfRef = m_selfRef.release();
       
   159 
       
   160     if (m_error) {
       
   161         ASSERT(m_result->type() == IDBAny::UndefinedType);
       
   162         dispatchEvent(IDBErrorEvent::create(m_source, *m_error));
       
   163     } else {
       
   164         ASSERT(m_result->type() != IDBAny::UndefinedType);
       
   165         dispatchEvent(IDBSuccessEvent::create(m_source, m_result));        
       
   166     }
       
   167 }
       
   168 
       
   169 void IDBRequest::onEventCommon()
       
   170 {
       
   171     ASSERT(m_readyState < DONE);
       
   172     ASSERT(m_result->type() == IDBAny::UndefinedType);
       
   173     ASSERT(!m_error);
       
   174     ASSERT(!m_selfRef);
       
   175     ASSERT(!m_timer.isActive());
       
   176 
       
   177     if (m_aborted)
       
   178         return;
       
   179 
       
   180     m_readyState = DONE;
       
   181     m_selfRef = this;
       
   182     if (!m_stopped)
       
   183         m_timer.startOneShot(0);
       
   184 }
       
   185 
       
   186 } // namespace WebCore
       
   187 
       
   188 #endif