d5be99fd4dd942b148ecab505f36de2d459994df
[WebKit-https.git] / Source / WebCore / Modules / indexeddb / IDBRequest.h
1 /*
2  * Copyright (C) 2015, 2016 Apple 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  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #pragma once
27
28 #if ENABLE(INDEXED_DATABASE)
29
30 #include "EventTarget.h"
31 #include "ExceptionOr.h"
32 #include "IDBActiveDOMObject.h"
33 #include "IDBError.h"
34 #include "IDBKeyData.h"
35 #include "IDBResourceIdentifier.h"
36 #include "IDBValue.h"
37 #include "IndexedDB.h"
38 #include "JSValueInWrappedObject.h"
39 #include <JavaScriptCore/Strong.h>
40 #include <wtf/Function.h>
41 #include <wtf/Scope.h>
42 #include <wtf/WeakPtr.h>
43
44 namespace WebCore {
45
46 class DOMException;
47 class Event;
48 class IDBCursor;
49 class IDBDatabase;
50 class IDBIndex;
51 class IDBObjectStore;
52 class IDBResultData;
53 class IDBTransaction;
54 class ThreadSafeDataBuffer;
55
56 namespace IDBClient {
57 class IDBConnectionProxy;
58 class IDBConnectionToServer;
59 }
60
61 class IDBRequest : public EventTargetWithInlineData, public IDBActiveDOMObject, public RefCounted<IDBRequest>, public CanMakeWeakPtr<IDBRequest> {
62 public:
63     enum class NullResultType {
64         Empty,
65         Undefined
66     };
67
68     static Ref<IDBRequest> create(ScriptExecutionContext&, IDBObjectStore&, IDBTransaction&);
69     static Ref<IDBRequest> create(ScriptExecutionContext&, IDBCursor&, IDBTransaction&);
70     static Ref<IDBRequest> create(ScriptExecutionContext&, IDBIndex&, IDBTransaction&);
71     static Ref<IDBRequest> createObjectStoreGet(ScriptExecutionContext&, IDBObjectStore&, IndexedDB::ObjectStoreRecordType, IDBTransaction&);
72     static Ref<IDBRequest> createIndexGet(ScriptExecutionContext&, IDBIndex&, IndexedDB::IndexRecordType, IDBTransaction&);
73
74     const IDBResourceIdentifier& resourceIdentifier() const { return m_resourceIdentifier; }
75
76     virtual ~IDBRequest();
77
78     using Result = Variant<RefPtr<IDBCursor>, RefPtr<IDBDatabase>, IDBKeyData, Vector<IDBKeyData>, IDBValue, Vector<IDBValue>, uint64_t, NullResultType>;
79     ExceptionOr<Result> result() const;
80     JSValueInWrappedObject& resultWrapper() { return m_resultWrapper; }
81     JSValueInWrappedObject& cursorWrapper() { return m_cursorWrapper; }
82
83     using Source = Variant<RefPtr<IDBObjectStore>, RefPtr<IDBIndex>, RefPtr<IDBCursor>>;
84     const Optional<Source>& source() const { return m_source; }
85
86     ExceptionOr<DOMException*> error() const;
87
88     RefPtr<IDBTransaction> transaction() const;
89     
90     enum class ReadyState { Pending, Done };
91     ReadyState readyState() const { return m_readyState; }
92
93     bool isDone() const { return m_readyState == ReadyState::Done; }
94
95     uint64_t sourceObjectStoreIdentifier() const;
96     uint64_t sourceIndexIdentifier() const;
97     IndexedDB::ObjectStoreRecordType requestedObjectStoreRecordType() const;
98     IndexedDB::IndexRecordType requestedIndexRecordType() const;
99
100     ScriptExecutionContext* scriptExecutionContext() const final { return ActiveDOMObject::scriptExecutionContext(); }
101
102     using RefCounted::ref;
103     using RefCounted::deref;
104
105     void completeRequestAndDispatchEvent(const IDBResultData&);
106
107     void setResult(const IDBKeyData&);
108     void setResult(const Vector<IDBKeyData>&);
109     void setResult(const Vector<IDBValue>&);
110     void setResult(uint64_t);
111     void setResultToStructuredClone(const IDBValue&);
112     void setResultToUndefined();
113
114     void willIterateCursor(IDBCursor&);
115     void didOpenOrIterateCursor(const IDBResultData&);
116
117     const IDBCursor* pendingCursor() const { return m_pendingCursor.get(); }
118
119     void setSource(IDBCursor&);
120     void setVersionChangeTransaction(IDBTransaction&);
121
122     IndexedDB::RequestType requestType() const { return m_requestType; }
123
124     bool hasPendingActivity() const final;
125
126 protected:
127     IDBRequest(ScriptExecutionContext&, IDBClient::IDBConnectionProxy&);
128
129     void enqueueEvent(Ref<Event>&&);
130     void dispatchEvent(Event&) override;
131
132     void setResult(Ref<IDBDatabase>&&);
133
134     IDBClient::IDBConnectionProxy& connectionProxy() { return m_connectionProxy.get(); }
135
136     // FIXME: Protected data members aren't great for maintainability.
137     // Consider adding protected helper functions and making these private.
138     ReadyState m_readyState { ReadyState::Pending };
139     RefPtr<IDBTransaction> m_transaction;
140     bool m_shouldExposeTransactionToDOM { true };
141     RefPtr<DOMException> m_domError;
142     IndexedDB::RequestType m_requestType { IndexedDB::RequestType::Other };
143     bool m_contextStopped { false };
144     Event* m_openDatabaseSuccessEvent { nullptr };
145
146 private:
147     IDBRequest(ScriptExecutionContext&, IDBObjectStore&, IDBTransaction&);
148     IDBRequest(ScriptExecutionContext&, IDBCursor&, IDBTransaction&);
149     IDBRequest(ScriptExecutionContext&, IDBIndex&, IDBTransaction&);
150     IDBRequest(ScriptExecutionContext&, IDBObjectStore&, IndexedDB::ObjectStoreRecordType, IDBTransaction&);
151     IDBRequest(ScriptExecutionContext&, IDBIndex&, IndexedDB::IndexRecordType, IDBTransaction&);
152
153     EventTargetInterface eventTargetInterface() const override;
154
155     const char* activeDOMObjectName() const final;
156     bool canSuspendForDocumentSuspension() const final;
157     void stop() final;
158     virtual void cancelForStop();
159
160     void refEventTarget() final { RefCounted::ref(); }
161     void derefEventTarget() final { RefCounted::deref(); }
162     void uncaughtExceptionInEventHandler() final;
163
164     virtual bool isOpenDBRequest() const { return false; }
165
166     void onError();
167     void onSuccess();
168
169     void clearWrappers();
170
171     IDBCursor* resultCursor();
172
173     IDBError m_idbError;
174     IDBResourceIdentifier m_resourceIdentifier;
175
176     JSValueInWrappedObject m_resultWrapper;
177     JSValueInWrappedObject m_cursorWrapper;
178     Result m_result;
179     Optional<Source> m_source;
180
181     bool m_hasPendingActivity { true };
182     IndexedDB::ObjectStoreRecordType m_requestedObjectStoreRecordType { IndexedDB::ObjectStoreRecordType::ValueOnly };
183     IndexedDB::IndexRecordType m_requestedIndexRecordType { IndexedDB::IndexRecordType::Key };
184
185     RefPtr<IDBCursor> m_pendingCursor;
186
187     Ref<IDBClient::IDBConnectionProxy> m_connectionProxy;
188
189     bool m_dispatchingEvent { false };
190     bool m_hasUncaughtException { false };
191 };
192
193 } // namespace WebCore
194
195 #endif // ENABLE(INDEXED_DATABASE)