Changeset 66726 in webkit
- Timestamp:
- Sep 3, 2010 5:53:44 AM (14 years ago)
- Location:
- trunk
- Files:
-
- 13 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r66724 r66726 1 2010-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 1 10 2010-09-03 Anton Muhin <antonm@chromium.org> 2 11 -
trunk/LayoutTests/storage/indexeddb/objectstore-cursor.html
r66473 r66726 196 196 testWithinBounds(); 197 197 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(); 202 199 } 203 200 -
trunk/WebCore/ChangeLog
r66723 r66726 1 2010-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 1 39 2010-09-03 Bharathwaaj Srinivasan <bharathwaaj.s@gmail.com> 2 40 -
trunk/WebCore/storage/IDBAny.cpp
r64828 r66726 38 38 namespace WebCore { 39 39 40 PassRefPtr<IDBAny> IDBAny::create ()40 PassRefPtr<IDBAny> IDBAny::createInvalid() 41 41 { 42 42 return adoptRef(new IDBAny()); 43 } 44 45 PassRefPtr<IDBAny> IDBAny::createNull() 46 { 47 RefPtr<IDBAny> idbAny = adoptRef(new IDBAny()); 48 idbAny->setNull(); 49 return idbAny.release(); 43 50 } 44 51 … … 94 101 } 95 102 96 void IDBAny::set ()103 void IDBAny::setNull() 97 104 { 98 105 ASSERT(m_type == UndefinedType); -
trunk/WebCore/storage/IDBAny.h
r64828 r66726 45 45 class IDBAny : public RefCounted<IDBAny> { 46 46 public: 47 static PassRefPtr<IDBAny> create(); 47 static PassRefPtr<IDBAny> createInvalid(); 48 static PassRefPtr<IDBAny> createNull(); 48 49 template<typename T> 49 50 static PassRefPtr<IDBAny> create(T* idbObject) 50 51 { 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(); 52 60 any->set(idbObject); 53 61 return any.release(); … … 78 86 79 87 // Set can only be called once. 80 void set (); // For "null".88 void setNull(); 81 89 void set(PassRefPtr<IDBCursor>); 82 90 void set(PassRefPtr<IDBDatabase>); -
trunk/WebCore/storage/IDBCursor.cpp
r66473 r66726 39 39 namespace WebCore { 40 40 41 IDBCursor::IDBCursor(PassRefPtr<IDBCursorBackendInterface> backend )41 IDBCursor::IDBCursor(PassRefPtr<IDBCursorBackendInterface> backend, IDBRequest* request) 42 42 : m_backend(backend) 43 , m_request(request) 43 44 { 44 45 } … … 70 71 } 71 72 72 PassRefPtr<IDBRequest> IDBCursor::continueFunction(ScriptExecutionContext* context,PassRefPtr<IDBKey> key)73 void IDBCursor::continueFunction(PassRefPtr<IDBKey> key) 73 74 { 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? 77 80 } 78 81 -
trunk/WebCore/storage/IDBCursor.h
r64828 r66726 32 32 #include <wtf/RefCounted.h> 33 33 #include <wtf/RefPtr.h> 34 #include <wtf/Threading.h>35 34 36 35 namespace WebCore { … … 44 43 class SerializedScriptValue; 45 44 46 class IDBCursor : public ThreadSafeShared<IDBCursor> {45 class IDBCursor : public RefCounted<IDBCursor> { 47 46 public: 48 47 enum Direction { … … 52 51 PREV_NO_DUPLICATE = 3, 53 52 }; 54 static PassRefPtr<IDBCursor> create(PassRefPtr<IDBCursorBackendInterface> backend )53 static PassRefPtr<IDBCursor> create(PassRefPtr<IDBCursorBackendInterface> backend, IDBRequest* request) 55 54 { 56 return adoptRef(new IDBCursor(backend ));55 return adoptRef(new IDBCursor(backend, request)); 57 56 } 58 virtual~IDBCursor();57 ~IDBCursor(); 59 58 60 59 // Implement the IDL 61 virtualunsigned short direction() const;62 virtualPassRefPtr<IDBKey> key() const;63 virtualPassRefPtr<IDBAny> value() const;64 virtualPassRefPtr<IDBRequest> update(ScriptExecutionContext*, PassRefPtr<SerializedScriptValue>);65 v irtual PassRefPtr<IDBRequest> continueFunction(ScriptExecutionContext*,PassRefPtr<IDBKey> = 0);66 virtualPassRefPtr<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*); 67 66 68 67 private: 69 explicit IDBCursor(PassRefPtr<IDBCursorBackendInterface> );68 explicit IDBCursor(PassRefPtr<IDBCursorBackendInterface>, IDBRequest*); 70 69 71 70 RefPtr<IDBCursorBackendInterface> m_backend; 71 RefPtr<IDBRequest> m_request; 72 72 }; 73 73 -
trunk/WebCore/storage/IDBCursor.idl
r64828 r66726 39 39 40 40 [CallWith=ScriptExecutionContext] IDBRequest update(in SerializedScriptValue value); 41 [ CallWith=ScriptExecutionContext, ImplementationFunction=continueFunction] IDBRequestcontinue(in [Optional] IDBKey key);41 [ImplementationFunction=continueFunction] void continue(in [Optional] IDBKey key); 42 42 [CallWith=ScriptExecutionContext] IDBRequest remove(); 43 43 }; -
trunk/WebCore/storage/IDBRequest.cpp
r64828 r66726 49 49 : ActiveDOMObject(context, this) 50 50 , m_source(source) 51 , m_result(IDBAny::create())52 51 , m_timer(this, &IDBRequest::timerFired) 53 52 , m_aborted(false) 54 , m_readyState( INITIAL)53 , m_readyState(LOADING) 55 54 { 56 55 } … … 58 57 IDBRequest::~IDBRequest() 59 58 { 60 if (m_readyState != DONE) 61 abort(); 59 abort(); 60 } 61 62 bool IDBRequest::resetReadyState() 63 { 64 if (m_aborted) 65 return false; 66 ASSERT(m_readyState == DONE); 67 m_readyState = LOADING; 68 return true; 62 69 } 63 70 64 71 void IDBRequest::onError(PassRefPtr<IDBDatabaseError> error) 65 72 { 66 onEventCommon(); 67 m_error = error; 73 scheduleEvent(0, error); 68 74 } 69 75 70 76 void IDBRequest::onSuccess() 71 77 { 72 onEventCommon(); 73 m_result->set(); 78 scheduleEvent(IDBAny::createNull(), 0); 74 79 } 75 80 76 81 void IDBRequest::onSuccess(PassRefPtr<IDBCursorBackendInterface> backend) 77 82 { 78 onEventCommon(); 79 m_result->set(IDBCursor::create(backend)); 83 scheduleEvent(IDBAny::create(IDBCursor::create(backend, this)), 0); 80 84 } 81 85 82 86 void IDBRequest::onSuccess(PassRefPtr<IDBDatabaseBackendInterface> backend) 83 87 { 84 onEventCommon(); 85 m_result->set(IDBDatabase::create(backend)); 88 scheduleEvent(IDBAny::create(IDBDatabase::create(backend)), 0); 86 89 } 87 90 88 91 void IDBRequest::onSuccess(PassRefPtr<IDBIndexBackendInterface> backend) 89 92 { 90 onEventCommon(); 91 m_result->set(IDBIndex::create(backend)); 93 scheduleEvent(IDBAny::create(IDBIndex::create(backend)), 0); 92 94 } 93 95 94 96 void IDBRequest::onSuccess(PassRefPtr<IDBKey> idbKey) 95 97 { 96 onEventCommon(); 97 m_result->set(idbKey); 98 scheduleEvent(IDBAny::create(idbKey), 0); 98 99 } 99 100 100 101 void IDBRequest::onSuccess(PassRefPtr<IDBObjectStoreBackendInterface> backend) 101 102 { 102 onEventCommon(); 103 m_result->set(IDBObjectStore::create(backend)); 103 scheduleEvent(IDBAny::create(IDBObjectStore::create(backend)), 0); 104 104 } 105 105 106 106 void IDBRequest::onSuccess(PassRefPtr<SerializedScriptValue> serializedScriptValue) 107 107 { 108 onEventCommon(); 109 m_result->set(serializedScriptValue); 108 scheduleEvent(IDBAny::create(serializedScriptValue), 0); 110 109 } 111 110 … … 114 113 m_timer.stop(); 115 114 m_aborted = true; 115 m_pendingEvents.clear(); 116 116 117 // FIXME: This should cancel any pending work being done in the backend. 117 118 } … … 141 142 void IDBRequest::timerFired(Timer<IDBRequest>*) 142 143 { 143 ASSERT(m_readyState == DONE);144 144 ASSERT(m_selfRef); 145 145 ASSERT(!m_aborted); 146 ASSERT(m_pendingEvents.size()); 146 147 147 148 // We need to keep self-referencing ourself, otherwise it's possible we'll be deleted. … … 150 151 RefPtr<IDBRequest> selfRef = m_selfRef.release(); 151 152 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 } 158 164 } 159 165 } 160 166 161 void IDBRequest:: onEventCommon()167 void IDBRequest::scheduleEvent(PassRefPtr<IDBAny> result, PassRefPtr<IDBDatabaseError> error) 162 168 { 163 169 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()); 168 171 169 172 if (m_aborted) 170 173 return; 171 174 175 PendingEvent pendingEvent; 176 pendingEvent.m_result = result; 177 pendingEvent.m_error = error; 178 m_pendingEvents.append(pendingEvent); 179 172 180 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 } 175 185 } 176 186 -
trunk/WebCore/storage/IDBRequest.h
r64828 r66726 39 39 #include "IDBCallbacks.h" 40 40 #include "Timer.h" 41 #include <wtf/Vector.h> 41 42 42 43 namespace WebCore { … … 50 51 void abort(); 51 52 enum ReadyState { 52 INITIAL = 0,53 53 LOADING = 1, 54 54 DONE = 2 55 55 }; 56 56 unsigned short readyState() const { return m_readyState; } 57 PassRefPtr<IDBDatabaseError> error() const { return m_error; }58 PassRefPtr<IDBAny> result() { return m_result; }59 57 DEFINE_ATTRIBUTE_EVENT_LISTENER(success); 60 58 DEFINE_ATTRIBUTE_EVENT_LISTENER(error); 59 60 bool resetReadyState(); 61 61 62 62 // IDBCallbacks … … 84 84 85 85 void timerFired(Timer<IDBRequest>*); 86 void onEventCommon();86 void scheduleEvent(PassRefPtr<IDBAny> result, PassRefPtr<IDBDatabaseError>); 87 87 88 88 // EventTarget … … 94 94 RefPtr<IDBAny> m_source; 95 95 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; 98 101 99 102 // Used to fire events asynchronously. -
trunk/WebCore/storage/IDBRequest.idl
r59602 r66726 36 36 37 37 // States 38 const unsigned short INITIAL = 0;39 38 const unsigned short LOADING = 1; 40 39 const unsigned short DONE = 2; 41 40 readonly attribute unsigned short readyState; 42 43 // Possible results44 readonly attribute IDBDatabaseError error;45 readonly attribute IDBAny result;46 41 47 42 // Events -
trunk/WebKit/chromium/ChangeLog
r66720 r66726 1 2010-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 1 12 2010-09-02 Yury Semikhatsky <yurys@chromium.org> 2 13 -
trunk/WebKit/chromium/src/WebIDBCallbacksImpl.cpp
r64828 r66726 58 58 { 59 59 m_callbacks->onError(error); 60 m_callbacks.clear();61 60 } 62 61 … … 64 63 { 65 64 m_callbacks->onSuccess(); 66 m_callbacks.clear();67 65 } 68 66 … … 70 68 { 71 69 m_callbacks->onSuccess(IDBCursorBackendProxy::create(cursor)); 72 m_callbacks.clear();73 70 } 74 71 … … 76 73 { 77 74 m_callbacks->onSuccess(IDBDatabaseProxy::create(webKitInstance)); 78 m_callbacks.clear();79 75 } 80 76 … … 82 78 { 83 79 m_callbacks->onSuccess(key); 84 m_callbacks.clear();85 80 } 86 81 … … 88 83 { 89 84 m_callbacks->onSuccess(IDBIndexBackendProxy::create(webKitInstance)); 90 m_callbacks.clear();91 85 } 92 86 … … 94 88 { 95 89 m_callbacks->onSuccess(IDBObjectStoreProxy::create(webKitInstance)); 96 m_callbacks.clear();97 90 } 98 91 … … 100 93 { 101 94 m_callbacks->onSuccess(serializedScriptValue); 102 m_callbacks.clear();103 95 } 104 96
Note: See TracChangeset
for help on using the changeset viewer.