Changeset 66726 in webkit


Ignore:
Timestamp:
Sep 3, 2010 5:53:44 AM (14 years ago)
Author:
jorlow@chromium.org
Message:

2010-08-31 Jeremy Orlow <jorlow@chromium.org>

Reviewed by Steve Block.

IDBCursor.continue() should reuse the .openCursor's IDBRequest object
https://bugs.webkit.org/show_bug.cgi?id=44953

  • storage/indexeddb/objectstore-cursor.html:

2010-08-31 Jeremy Orlow <jorlow@chromium.org>

Reviewed by Steve Block.

IDBCursor.continue() should reuse the .openCursor's IDBRequest object
https://bugs.webkit.org/show_bug.cgi?id=44953

This is to match the spec. This requires a modification to IDBRequest so
that multiple events can be queued up.

Note that the initial state for IDBRequest was removed from the spec.

Test: modified existing test to verify new behavior.

  • storage/IDBAny.cpp: (WebCore::IDBAny::createInvalid): (WebCore::IDBAny::createNull): (WebCore::IDBAny::setNull):
  • storage/IDBAny.h: (WebCore::IDBAny::create):
  • storage/IDBCursor.cpp: (WebCore::IDBCursor::IDBCursor): (WebCore::IDBCursor::continueFunction):
  • storage/IDBCursor.h: (WebCore::IDBCursor::create):
  • storage/IDBCursor.idl:
  • storage/IDBRequest.cpp: (WebCore::IDBRequest::IDBRequest): (WebCore::IDBRequest::~IDBRequest): (WebCore::IDBRequest::resetReadyState): (WebCore::IDBRequest::onError): (WebCore::IDBRequest::onSuccess): (WebCore::IDBRequest::abort): (WebCore::IDBRequest::timerFired): (WebCore::IDBRequest::scheduleEvent):
  • storage/IDBRequest.h:
  • storage/IDBRequest.idl:

2010-08-31 Jeremy Orlow <jorlow@chromium.org>

Reviewed by Steve Block.

IDBCursor.continue() should reuse the .openCursor's IDBRequest object
https://bugs.webkit.org/show_bug.cgi?id=44953

  • src/WebIDBCallbacksImpl.cpp: (WebCore::WebIDBCallbacksImpl::onError): (WebCore::WebIDBCallbacksImpl::onSuccess):
Location:
trunk
Files:
13 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r66724 r66726  
     12010-08-31  Jeremy Orlow  <jorlow@chromium.org>
     2
     3        Reviewed by Steve Block.
     4
     5        IDBCursor.continue() should reuse the .openCursor's IDBRequest object
     6        https://bugs.webkit.org/show_bug.cgi?id=44953
     7
     8        * storage/indexeddb/objectstore-cursor.html:
     9
    1102010-09-03  Anton Muhin  <antonm@chromium.org>
    211
  • trunk/LayoutTests/storage/indexeddb/objectstore-cursor.html

    r66473 r66726  
    196196    testWithinBounds();
    197197
    198     request = event.result.continue();
    199     // FIXME: The spec says we should not return an IDBRequest and instead re-use the original request.
    200     request.onsuccess = cursorIteration;
    201     request.onerror = unexpectedErrorCallback;
     198    event.result.continue();
    202199}
    203200 
  • trunk/WebCore/ChangeLog

    r66723 r66726  
     12010-08-31  Jeremy Orlow  <jorlow@chromium.org>
     2
     3        Reviewed by Steve Block.
     4
     5        IDBCursor.continue() should reuse the .openCursor's IDBRequest object
     6        https://bugs.webkit.org/show_bug.cgi?id=44953
     7
     8        This is to match the spec. This requires a modification to IDBRequest so
     9        that multiple events can be queued up.
     10
     11        Note that the initial state for IDBRequest was removed from the spec.
     12
     13        Test: modified existing test to verify new behavior.
     14
     15        * storage/IDBAny.cpp:
     16        (WebCore::IDBAny::createInvalid):
     17        (WebCore::IDBAny::createNull):
     18        (WebCore::IDBAny::setNull):
     19        * storage/IDBAny.h:
     20        (WebCore::IDBAny::create):
     21        * storage/IDBCursor.cpp:
     22        (WebCore::IDBCursor::IDBCursor):
     23        (WebCore::IDBCursor::continueFunction):
     24        * storage/IDBCursor.h:
     25        (WebCore::IDBCursor::create):
     26        * storage/IDBCursor.idl:
     27        * storage/IDBRequest.cpp:
     28        (WebCore::IDBRequest::IDBRequest):
     29        (WebCore::IDBRequest::~IDBRequest):
     30        (WebCore::IDBRequest::resetReadyState):
     31        (WebCore::IDBRequest::onError):
     32        (WebCore::IDBRequest::onSuccess):
     33        (WebCore::IDBRequest::abort):
     34        (WebCore::IDBRequest::timerFired):
     35        (WebCore::IDBRequest::scheduleEvent):
     36        * storage/IDBRequest.h:
     37        * storage/IDBRequest.idl:
     38
    1392010-09-03  Bharathwaaj Srinivasan  <bharathwaaj.s@gmail.com>
    240
  • trunk/WebCore/storage/IDBAny.cpp

    r64828 r66726  
    3838namespace WebCore {
    3939
    40 PassRefPtr<IDBAny> IDBAny::create()
     40PassRefPtr<IDBAny> IDBAny::createInvalid()
    4141{
    4242    return adoptRef(new IDBAny());
     43}
     44
     45PassRefPtr<IDBAny> IDBAny::createNull()
     46{
     47    RefPtr<IDBAny> idbAny = adoptRef(new IDBAny());
     48    idbAny->setNull();
     49    return idbAny.release();
    4350}
    4451
     
    94101}
    95102
    96 void IDBAny::set()
     103void IDBAny::setNull()
    97104{
    98105    ASSERT(m_type == UndefinedType);
  • trunk/WebCore/storage/IDBAny.h

    r64828 r66726  
    4545class IDBAny : public RefCounted<IDBAny> {
    4646public:
    47     static PassRefPtr<IDBAny> create();
     47    static PassRefPtr<IDBAny> createInvalid();
     48    static PassRefPtr<IDBAny> createNull();
    4849    template<typename T>
    4950    static PassRefPtr<IDBAny> create(T* idbObject)
    5051    {
    51         RefPtr<IDBAny> any = IDBAny::create();
     52        RefPtr<IDBAny> any = IDBAny::createInvalid();
     53        any->set(idbObject);
     54        return any.release();
     55    }
     56    template<typename T>
     57    static PassRefPtr<IDBAny> create(PassRefPtr<T> idbObject)
     58    {
     59        RefPtr<IDBAny> any = IDBAny::createInvalid();
    5260        any->set(idbObject);
    5361        return any.release();
     
    7886
    7987    // Set can only be called once.
    80     void set(); // For "null".
     88    void setNull();
    8189    void set(PassRefPtr<IDBCursor>);
    8290    void set(PassRefPtr<IDBDatabase>);
  • trunk/WebCore/storage/IDBCursor.cpp

    r66473 r66726  
    3939namespace WebCore {
    4040
    41 IDBCursor::IDBCursor(PassRefPtr<IDBCursorBackendInterface> backend)
     41IDBCursor::IDBCursor(PassRefPtr<IDBCursorBackendInterface> backend, IDBRequest* request)
    4242    : m_backend(backend)
     43    , m_request(request)
    4344{
    4445}
     
    7071}
    7172
    72 PassRefPtr<IDBRequest> IDBCursor::continueFunction(ScriptExecutionContext* context, PassRefPtr<IDBKey> key)
     73void IDBCursor::continueFunction(PassRefPtr<IDBKey> key)
    7374{
    74     RefPtr<IDBRequest> request = IDBRequest::create(context, IDBAny::create(this));
    75     m_backend->continueFunction(key, request);
    76     return request.release();
     75    // FIXME: We're not using the context from when continue was called, which means the callback
     76    //        will be on the original context openCursor was called on. Is this right?
     77    if (m_request->resetReadyState())
     78        m_backend->continueFunction(key, m_request);
     79    // FIXME: Else throw?
    7780}
    7881
  • trunk/WebCore/storage/IDBCursor.h

    r64828 r66726  
    3232#include <wtf/RefCounted.h>
    3333#include <wtf/RefPtr.h>
    34 #include <wtf/Threading.h>
    3534
    3635namespace WebCore {
     
    4443class SerializedScriptValue;
    4544
    46 class IDBCursor : public ThreadSafeShared<IDBCursor> {
     45class IDBCursor : public RefCounted<IDBCursor> {
    4746public:
    4847    enum Direction {
     
    5251        PREV_NO_DUPLICATE = 3,
    5352    };
    54     static PassRefPtr<IDBCursor> create(PassRefPtr<IDBCursorBackendInterface> backend)
     53    static PassRefPtr<IDBCursor> create(PassRefPtr<IDBCursorBackendInterface> backend, IDBRequest* request)
    5554    {
    56         return adoptRef(new IDBCursor(backend));
     55        return adoptRef(new IDBCursor(backend, request));
    5756    }
    58     virtual ~IDBCursor();
     57    ~IDBCursor();
    5958
    6059    // Implement the IDL
    61     virtual unsigned short direction() const;
    62     virtual PassRefPtr<IDBKey> key() const;
    63     virtual PassRefPtr<IDBAny> value() const;
    64     virtual PassRefPtr<IDBRequest> update(ScriptExecutionContext*, PassRefPtr<SerializedScriptValue>);
    65     virtual PassRefPtr<IDBRequest> continueFunction(ScriptExecutionContext*, PassRefPtr<IDBKey> = 0);
    66     virtual PassRefPtr<IDBRequest> remove(ScriptExecutionContext*);
     60    unsigned short direction() const;
     61    PassRefPtr<IDBKey> key() const;
     62    PassRefPtr<IDBAny> value() const;
     63    PassRefPtr<IDBRequest> update(ScriptExecutionContext*, PassRefPtr<SerializedScriptValue>);
     64    void continueFunction(PassRefPtr<IDBKey> = 0);
     65    PassRefPtr<IDBRequest> remove(ScriptExecutionContext*);
    6766
    6867private:
    69     explicit IDBCursor(PassRefPtr<IDBCursorBackendInterface>);
     68    explicit IDBCursor(PassRefPtr<IDBCursorBackendInterface>, IDBRequest*);
    7069
    7170    RefPtr<IDBCursorBackendInterface> m_backend;
     71    RefPtr<IDBRequest> m_request;
    7272};
    7373
  • trunk/WebCore/storage/IDBCursor.idl

    r64828 r66726  
    3939
    4040        [CallWith=ScriptExecutionContext] IDBRequest update(in SerializedScriptValue value);
    41         [CallWith=ScriptExecutionContext, ImplementationFunction=continueFunction] IDBRequest continue(in [Optional] IDBKey key);
     41        [ImplementationFunction=continueFunction] void continue(in [Optional] IDBKey key);
    4242        [CallWith=ScriptExecutionContext] IDBRequest remove();
    4343    };
  • trunk/WebCore/storage/IDBRequest.cpp

    r64828 r66726  
    4949    : ActiveDOMObject(context, this)
    5050    , m_source(source)
    51     , m_result(IDBAny::create())
    5251    , m_timer(this, &IDBRequest::timerFired)
    5352    , m_aborted(false)
    54     , m_readyState(INITIAL)
     53    , m_readyState(LOADING)
    5554{
    5655}
     
    5857IDBRequest::~IDBRequest()
    5958{
    60     if (m_readyState != DONE)
    61         abort();
     59    abort();
     60}
     61
     62bool IDBRequest::resetReadyState()
     63{
     64    if (m_aborted)
     65        return false;
     66    ASSERT(m_readyState == DONE);
     67    m_readyState = LOADING;
     68    return true;
    6269}
    6370
    6471void IDBRequest::onError(PassRefPtr<IDBDatabaseError> error)
    6572{
    66     onEventCommon();
    67     m_error = error;
     73    scheduleEvent(0, error);
    6874}
    6975
    7076void IDBRequest::onSuccess()
    7177{
    72     onEventCommon();
    73     m_result->set();
     78    scheduleEvent(IDBAny::createNull(), 0);
    7479}
    7580
    7681void IDBRequest::onSuccess(PassRefPtr<IDBCursorBackendInterface> backend)
    7782{
    78     onEventCommon();
    79     m_result->set(IDBCursor::create(backend));
     83    scheduleEvent(IDBAny::create(IDBCursor::create(backend, this)), 0);
    8084}
    8185
    8286void IDBRequest::onSuccess(PassRefPtr<IDBDatabaseBackendInterface> backend)
    8387{
    84     onEventCommon();
    85     m_result->set(IDBDatabase::create(backend));
     88    scheduleEvent(IDBAny::create(IDBDatabase::create(backend)), 0);
    8689}
    8790
    8891void IDBRequest::onSuccess(PassRefPtr<IDBIndexBackendInterface> backend)
    8992{
    90     onEventCommon();
    91     m_result->set(IDBIndex::create(backend));
     93    scheduleEvent(IDBAny::create(IDBIndex::create(backend)), 0);
    9294}
    9395
    9496void IDBRequest::onSuccess(PassRefPtr<IDBKey> idbKey)
    9597{
    96     onEventCommon();
    97     m_result->set(idbKey);
     98    scheduleEvent(IDBAny::create(idbKey), 0);
    9899}
    99100
    100101void IDBRequest::onSuccess(PassRefPtr<IDBObjectStoreBackendInterface> backend)
    101102{
    102     onEventCommon();
    103     m_result->set(IDBObjectStore::create(backend));
     103    scheduleEvent(IDBAny::create(IDBObjectStore::create(backend)), 0);
    104104}
    105105
    106106void IDBRequest::onSuccess(PassRefPtr<SerializedScriptValue> serializedScriptValue)
    107107{
    108     onEventCommon();
    109     m_result->set(serializedScriptValue);
     108    scheduleEvent(IDBAny::create(serializedScriptValue), 0);
    110109}
    111110
     
    114113    m_timer.stop();
    115114    m_aborted = true;
     115    m_pendingEvents.clear();
     116
    116117    // FIXME: This should cancel any pending work being done in the backend.
    117118}
     
    141142void IDBRequest::timerFired(Timer<IDBRequest>*)
    142143{
    143     ASSERT(m_readyState == DONE);
    144144    ASSERT(m_selfRef);
    145145    ASSERT(!m_aborted);
     146    ASSERT(m_pendingEvents.size());
    146147
    147148    // We need to keep self-referencing ourself, otherwise it's possible we'll be deleted.
     
    150151    RefPtr<IDBRequest> selfRef = m_selfRef.release();
    151152
    152     if (m_error) {
    153         ASSERT(m_result->type() == IDBAny::UndefinedType);
    154         dispatchEvent(IDBErrorEvent::create(m_source, *m_error));
    155     } else {
    156         ASSERT(m_result->type() != IDBAny::UndefinedType);
    157         dispatchEvent(IDBSuccessEvent::create(m_source, m_result));
     153    Vector<PendingEvent> pendingEvents;
     154    pendingEvents.swap(m_pendingEvents);
     155    for (size_t i = 0; i < pendingEvents.size(); ++i) {
     156        PendingEvent pendingEvent = pendingEvents[i];
     157        if (pendingEvent.m_error) {
     158            ASSERT(!pendingEvent.m_result);
     159            dispatchEvent(IDBErrorEvent::create(m_source, *pendingEvent.m_error));
     160        } else {
     161            ASSERT(pendingEvent.m_result->type() != IDBAny::UndefinedType);
     162            dispatchEvent(IDBSuccessEvent::create(m_source, pendingEvent.m_result));
     163        }
    158164    }
    159165}
    160166
    161 void IDBRequest::onEventCommon()
     167void IDBRequest::scheduleEvent(PassRefPtr<IDBAny> result, PassRefPtr<IDBDatabaseError> error)
    162168{
    163169    ASSERT(m_readyState < DONE);
    164     ASSERT(m_result->type() == IDBAny::UndefinedType);
    165     ASSERT(!m_error);
    166     ASSERT(!m_selfRef);
    167     ASSERT(!m_timer.isActive());
     170    ASSERT(!!m_selfRef == m_timer.isActive());
    168171
    169172    if (m_aborted)
    170173        return;
    171174
     175    PendingEvent pendingEvent;
     176    pendingEvent.m_result = result;
     177    pendingEvent.m_error = error;
     178    m_pendingEvents.append(pendingEvent);
     179
    172180    m_readyState = DONE;
    173     m_selfRef = this;
    174     m_timer.startOneShot(0);
     181    if (!m_timer.isActive()) {
     182        m_selfRef = this;
     183        m_timer.startOneShot(0);
     184    }
    175185}
    176186
  • trunk/WebCore/storage/IDBRequest.h

    r64828 r66726  
    3939#include "IDBCallbacks.h"
    4040#include "Timer.h"
     41#include <wtf/Vector.h>
    4142
    4243namespace WebCore {
     
    5051    void abort();
    5152    enum ReadyState {
    52         INITIAL = 0,
    5353        LOADING = 1,
    5454        DONE = 2
    5555    };
    5656    unsigned short readyState() const { return m_readyState; }
    57     PassRefPtr<IDBDatabaseError> error() const { return m_error; }
    58     PassRefPtr<IDBAny> result() { return m_result; }
    5957    DEFINE_ATTRIBUTE_EVENT_LISTENER(success);
    6058    DEFINE_ATTRIBUTE_EVENT_LISTENER(error);
     59
     60    bool resetReadyState();
    6161
    6262    // IDBCallbacks
     
    8484
    8585    void timerFired(Timer<IDBRequest>*);
    86     void onEventCommon();
     86    void scheduleEvent(PassRefPtr<IDBAny> result, PassRefPtr<IDBDatabaseError>);
    8787
    8888    // EventTarget
     
    9494    RefPtr<IDBAny> m_source;
    9595
    96     RefPtr<IDBAny> m_result;
    97     RefPtr<IDBDatabaseError> m_error;
     96    struct PendingEvent {
     97        RefPtr<IDBAny> m_result;
     98        RefPtr<IDBDatabaseError> m_error;
     99    };
     100    Vector<PendingEvent> m_pendingEvents;
    98101
    99102    // Used to fire events asynchronously.
  • trunk/WebCore/storage/IDBRequest.idl

    r59602 r66726  
    3636
    3737        // States
    38         const unsigned short INITIAL = 0;
    3938        const unsigned short LOADING = 1;
    4039        const unsigned short DONE = 2;
    4140        readonly attribute unsigned short readyState;
    42 
    43         // Possible results
    44         readonly attribute IDBDatabaseError error;
    45         readonly attribute IDBAny result;
    4641
    4742        // Events
  • trunk/WebKit/chromium/ChangeLog

    r66720 r66726  
     12010-08-31  Jeremy Orlow  <jorlow@chromium.org>
     2
     3        Reviewed by Steve Block.
     4
     5        IDBCursor.continue() should reuse the .openCursor's IDBRequest object
     6        https://bugs.webkit.org/show_bug.cgi?id=44953
     7
     8        * src/WebIDBCallbacksImpl.cpp:
     9        (WebCore::WebIDBCallbacksImpl::onError):
     10        (WebCore::WebIDBCallbacksImpl::onSuccess):
     11
    1122010-09-02  Yury Semikhatsky  <yurys@chromium.org>
    213
  • trunk/WebKit/chromium/src/WebIDBCallbacksImpl.cpp

    r64828 r66726  
    5858{
    5959    m_callbacks->onError(error);
    60     m_callbacks.clear();
    6160}
    6261
     
    6463{
    6564    m_callbacks->onSuccess();
    66     m_callbacks.clear();
    6765}
    6866
     
    7068{
    7169    m_callbacks->onSuccess(IDBCursorBackendProxy::create(cursor));
    72     m_callbacks.clear();
    7370}
    7471
     
    7673{
    7774    m_callbacks->onSuccess(IDBDatabaseProxy::create(webKitInstance));
    78     m_callbacks.clear();
    7975}
    8076
     
    8278{
    8379    m_callbacks->onSuccess(key);
    84     m_callbacks.clear();
    8580}
    8681
     
    8883{
    8984    m_callbacks->onSuccess(IDBIndexBackendProxy::create(webKitInstance));
    90     m_callbacks.clear();
    9185}
    9286
     
    9488{
    9589    m_callbacks->onSuccess(IDBObjectStoreProxy::create(webKitInstance));
    96     m_callbacks.clear();
    9790}
    9891
     
    10093{
    10194    m_callbacks->onSuccess(serializedScriptValue);
    102     m_callbacks.clear();
    10395}
    10496
Note: See TracChangeset for help on using the changeset viewer.