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 "IDBGetAllResult.h" |
35 | #include "IDBGetResult.h" |
36 | #include "IDBKeyData.h" |
37 | #include "IDBResourceIdentifier.h" |
38 | #include "IDBValue.h" |
39 | #include "IndexedDB.h" |
40 | #include "JSValueInWrappedObject.h" |
41 | #include <JavaScriptCore/Strong.h> |
42 | #include <wtf/Function.h> |
43 | #include <wtf/Scope.h> |
44 | #include <wtf/WeakPtr.h> |
45 | |
46 | namespace WebCore { |
47 | |
48 | class DOMException; |
49 | class Event; |
50 | class IDBCursor; |
51 | class IDBDatabase; |
52 | class IDBIndex; |
53 | class IDBObjectStore; |
54 | class IDBResultData; |
55 | class IDBTransaction; |
56 | class ThreadSafeDataBuffer; |
57 | |
58 | namespace IDBClient { |
59 | class IDBConnectionProxy; |
60 | class IDBConnectionToServer; |
61 | } |
62 | |
63 | class IDBRequest : public EventTargetWithInlineData, public IDBActiveDOMObject, public RefCounted<IDBRequest>, public CanMakeWeakPtr<IDBRequest> { |
64 | WTF_MAKE_ISO_ALLOCATED(IDBRequest); |
65 | public: |
66 | enum class NullResultType { |
67 | Empty, |
68 | Undefined |
69 | }; |
70 | |
71 | static Ref<IDBRequest> create(ScriptExecutionContext&, IDBObjectStore&, IDBTransaction&); |
72 | static Ref<IDBRequest> create(ScriptExecutionContext&, IDBCursor&, IDBTransaction&); |
73 | static Ref<IDBRequest> create(ScriptExecutionContext&, IDBIndex&, IDBTransaction&); |
74 | static Ref<IDBRequest> createObjectStoreGet(ScriptExecutionContext&, IDBObjectStore&, IndexedDB::ObjectStoreRecordType, IDBTransaction&); |
75 | static Ref<IDBRequest> createIndexGet(ScriptExecutionContext&, IDBIndex&, IndexedDB::IndexRecordType, IDBTransaction&); |
76 | |
77 | const IDBResourceIdentifier& resourceIdentifier() const { return m_resourceIdentifier; } |
78 | |
79 | virtual ~IDBRequest(); |
80 | |
81 | using Result = Variant<RefPtr<IDBCursor>, RefPtr<IDBDatabase>, IDBKeyData, Vector<IDBKeyData>, IDBGetResult, IDBGetAllResult, uint64_t, NullResultType>; |
82 | ExceptionOr<Result> result() const; |
83 | JSValueInWrappedObject& resultWrapper() { return m_resultWrapper; } |
84 | JSValueInWrappedObject& cursorWrapper() { return m_cursorWrapper; } |
85 | |
86 | using Source = Variant<RefPtr<IDBObjectStore>, RefPtr<IDBIndex>, RefPtr<IDBCursor>>; |
87 | const Optional<Source>& source() const { return m_source; } |
88 | |
89 | ExceptionOr<DOMException*> error() const; |
90 | |
91 | RefPtr<IDBTransaction> transaction() const; |
92 | |
93 | enum class ReadyState { Pending, Done }; |
94 | ReadyState readyState() const { return m_readyState; } |
95 | |
96 | bool isDone() const { return m_readyState == ReadyState::Done; } |
97 | |
98 | uint64_t sourceObjectStoreIdentifier() const; |
99 | uint64_t sourceIndexIdentifier() const; |
100 | IndexedDB::ObjectStoreRecordType requestedObjectStoreRecordType() const; |
101 | IndexedDB::IndexRecordType requestedIndexRecordType() const; |
102 | |
103 | ScriptExecutionContext* scriptExecutionContext() const final { return ActiveDOMObject::scriptExecutionContext(); } |
104 | |
105 | using RefCounted::ref; |
106 | using RefCounted::deref; |
107 | |
108 | void completeRequestAndDispatchEvent(const IDBResultData&); |
109 | |
110 | void setResult(const IDBKeyData&); |
111 | void setResult(const Vector<IDBKeyData>&); |
112 | void setResultToStructuredClone(const IDBGetResult&); |
113 | void setResult(const IDBGetAllResult&); |
114 | void setResult(uint64_t); |
115 | void setResultToUndefined(); |
116 | |
117 | void willIterateCursor(IDBCursor&); |
118 | void didOpenOrIterateCursor(const IDBResultData&); |
119 | |
120 | const IDBCursor* pendingCursor() const { return m_pendingCursor.get(); } |
121 | |
122 | void setSource(IDBCursor&); |
123 | void setVersionChangeTransaction(IDBTransaction&); |
124 | |
125 | IndexedDB::RequestType requestType() const { return m_requestType; } |
126 | |
127 | bool hasPendingActivity() const final; |
128 | |
129 | protected: |
130 | IDBRequest(ScriptExecutionContext&, IDBClient::IDBConnectionProxy&); |
131 | |
132 | void enqueueEvent(Ref<Event>&&); |
133 | void dispatchEvent(Event&) override; |
134 | |
135 | void setResult(Ref<IDBDatabase>&&); |
136 | |
137 | IDBClient::IDBConnectionProxy& connectionProxy() { return m_connectionProxy.get(); } |
138 | |
139 | // FIXME: Protected data members aren't great for maintainability. |
140 | // Consider adding protected helper functions and making these private. |
141 | ReadyState m_readyState { ReadyState::Pending }; |
142 | RefPtr<IDBTransaction> m_transaction; |
143 | bool m_shouldExposeTransactionToDOM { true }; |
144 | RefPtr<DOMException> m_domError; |
145 | IndexedDB::RequestType m_requestType { IndexedDB::RequestType::Other }; |
146 | bool m_contextStopped { false }; |
147 | Event* m_openDatabaseSuccessEvent { nullptr }; |
148 | |
149 | private: |
150 | IDBRequest(ScriptExecutionContext&, IDBObjectStore&, IDBTransaction&); |
151 | IDBRequest(ScriptExecutionContext&, IDBCursor&, IDBTransaction&); |
152 | IDBRequest(ScriptExecutionContext&, IDBIndex&, IDBTransaction&); |
153 | IDBRequest(ScriptExecutionContext&, IDBObjectStore&, IndexedDB::ObjectStoreRecordType, IDBTransaction&); |
154 | IDBRequest(ScriptExecutionContext&, IDBIndex&, IndexedDB::IndexRecordType, IDBTransaction&); |
155 | |
156 | EventTargetInterface eventTargetInterface() const override; |
157 | |
158 | const char* activeDOMObjectName() const final; |
159 | bool canSuspendForDocumentSuspension() const final; |
160 | void stop() final; |
161 | virtual void cancelForStop(); |
162 | |
163 | void refEventTarget() final { RefCounted::ref(); } |
164 | void derefEventTarget() final { RefCounted::deref(); } |
165 | void uncaughtExceptionInEventHandler() final; |
166 | |
167 | virtual bool isOpenDBRequest() const { return false; } |
168 | |
169 | void onError(); |
170 | void onSuccess(); |
171 | |
172 | void clearWrappers(); |
173 | |
174 | IDBCursor* resultCursor(); |
175 | |
176 | IDBError m_idbError; |
177 | IDBResourceIdentifier m_resourceIdentifier; |
178 | |
179 | JSValueInWrappedObject m_resultWrapper; |
180 | JSValueInWrappedObject m_cursorWrapper; |
181 | Result m_result; |
182 | Optional<Source> m_source; |
183 | |
184 | bool m_hasPendingActivity { true }; |
185 | IndexedDB::ObjectStoreRecordType m_requestedObjectStoreRecordType { IndexedDB::ObjectStoreRecordType::ValueOnly }; |
186 | IndexedDB::IndexRecordType m_requestedIndexRecordType { IndexedDB::IndexRecordType::Key }; |
187 | |
188 | RefPtr<IDBCursor> m_pendingCursor; |
189 | |
190 | Ref<IDBClient::IDBConnectionProxy> m_connectionProxy; |
191 | |
192 | bool m_dispatchingEvent { false }; |
193 | bool m_hasUncaughtException { false }; |
194 | }; |
195 | |
196 | } // namespace WebCore |
197 | |
198 | #endif // ENABLE(INDEXED_DATABASE) |
199 | |