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