7dab116de0890f07984ff7909c7fea8c19122ebd
[WebKit-https.git] / Source / WebCore / Modules / indexeddb / IDBTransaction.h
1 /*
2  * Copyright (C) 2015 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 "IDBActiveDOMObject.h"
32 #include "IDBError.h"
33 #include "IDBGetAllRecordsData.h"
34 #include "IDBGetRecordData.h"
35 #include "IDBKeyRangeData.h"
36 #include "IDBOpenDBRequest.h"
37 #include "IDBTransactionInfo.h"
38 #include "IDBTransactionMode.h"
39 #include "IndexedDB.h"
40 #include "Timer.h"
41 #include <wtf/Deque.h>
42 #include <wtf/HashMap.h>
43
44 namespace WebCore {
45
46 class DOMError;
47 class DOMStringList;
48 class IDBCursor;
49 class IDBCursorInfo;
50 class IDBDatabase;
51 class IDBIndex;
52 class IDBIndexInfo;
53 class IDBKey;
54 class IDBKeyData;
55 class IDBObjectStore;
56 class IDBObjectStoreInfo;
57 class IDBResultData;
58 class SerializedScriptValue;
59
60 struct IDBKeyRangeData;
61
62 namespace IDBClient {
63 class IDBConnectionProxy;
64 class TransactionOperation;
65 }
66
67 class IDBTransaction : public ThreadSafeRefCounted<IDBTransaction>, public EventTargetWithInlineData, public IDBActiveDOMObject {
68 public:
69     static Ref<IDBTransaction> create(IDBDatabase&, const IDBTransactionInfo&);
70     static Ref<IDBTransaction> create(IDBDatabase&, const IDBTransactionInfo&, IDBOpenDBRequest&);
71
72     ~IDBTransaction() final;
73
74     // IDBTransaction IDL
75     Ref<DOMStringList> objectStoreNames() const;
76     IDBTransactionMode mode() const { return m_info.mode(); }
77     IDBDatabase* db();
78     DOMError* error() const;
79     ExceptionOr<Ref<IDBObjectStore>> objectStore(const String& name);
80     ExceptionOr<void> abort();
81
82     EventTargetInterface eventTargetInterface() const final { return IDBTransactionEventTargetInterfaceType; }
83     ScriptExecutionContext* scriptExecutionContext() const final { return ActiveDOMObject::scriptExecutionContext(); }
84     void refEventTarget() final { ThreadSafeRefCounted::ref(); }
85     void derefEventTarget() final { ThreadSafeRefCounted::deref(); }
86     using EventTarget::dispatchEvent;
87     bool dispatchEvent(Event&) final;
88
89     using ThreadSafeRefCounted<IDBTransaction>::ref;
90     using ThreadSafeRefCounted<IDBTransaction>::deref;
91
92     const char* activeDOMObjectName() const final;
93     bool canSuspendForDocumentSuspension() const final;
94     bool hasPendingActivity() const final;
95     void stop() final;
96
97     const IDBTransactionInfo& info() const { return m_info; }
98     IDBDatabase& database() { return m_database.get(); }
99     const IDBDatabase& database() const { return m_database.get(); }
100     IDBDatabaseInfo* originalDatabaseInfo() const { return m_info.originalDatabaseInfo(); }
101
102     void didStart(const IDBError&);
103     void didAbort(const IDBError&);
104     void didCommit(const IDBError&);
105
106     bool isVersionChange() const { return mode() == IDBTransactionMode::Versionchange; }
107     bool isReadOnly() const { return mode() == IDBTransactionMode::Readonly; }
108     bool isActive() const;
109
110     Ref<IDBObjectStore> createObjectStore(const IDBObjectStoreInfo&);
111     void renameObjectStore(IDBObjectStore&, const String& newName);
112     std::unique_ptr<IDBIndex> createIndex(IDBObjectStore&, const IDBIndexInfo&);
113     void renameIndex(IDBIndex&, const String& newName);
114
115     Ref<IDBRequest> requestPutOrAdd(JSC::ExecState&, IDBObjectStore&, IDBKey*, SerializedScriptValue&, IndexedDB::ObjectStoreOverwriteMode);
116     Ref<IDBRequest> requestGetRecord(JSC::ExecState&, IDBObjectStore&, const IDBGetRecordData&);
117     Ref<IDBRequest> requestGetAllObjectStoreRecords(JSC::ExecState&, IDBObjectStore&, const IDBKeyRangeData&, IndexedDB::GetAllType, Optional<uint32_t> count);
118     Ref<IDBRequest> requestGetAllIndexRecords(JSC::ExecState&, IDBIndex&, const IDBKeyRangeData&, IndexedDB::GetAllType, Optional<uint32_t> count);
119     Ref<IDBRequest> requestDeleteRecord(JSC::ExecState&, IDBObjectStore&, const IDBKeyRangeData&);
120     Ref<IDBRequest> requestClearObjectStore(JSC::ExecState&, IDBObjectStore&);
121     Ref<IDBRequest> requestCount(JSC::ExecState&, IDBObjectStore&, const IDBKeyRangeData&);
122     Ref<IDBRequest> requestCount(JSC::ExecState&, IDBIndex&, const IDBKeyRangeData&);
123     Ref<IDBRequest> requestGetValue(JSC::ExecState&, IDBIndex&, const IDBKeyRangeData&);
124     Ref<IDBRequest> requestGetKey(JSC::ExecState&, IDBIndex&, const IDBKeyRangeData&);
125     Ref<IDBRequest> requestOpenCursor(JSC::ExecState&, IDBObjectStore&, const IDBCursorInfo&);
126     Ref<IDBRequest> requestOpenCursor(JSC::ExecState&, IDBIndex&, const IDBCursorInfo&);
127     void iterateCursor(IDBCursor&, const IDBKeyData&, unsigned long count);
128
129     void deleteObjectStore(const String& objectStoreName);
130     void deleteIndex(uint64_t objectStoreIdentifier, const String& indexName);
131
132     void addRequest(IDBRequest&);
133     void removeRequest(IDBRequest&);
134
135     void abortDueToFailedRequest(DOMError&);
136
137     void activate();
138     void deactivate();
139
140     void operationDidComplete(IDBClient::TransactionOperation&);
141
142     bool isFinishedOrFinishing() const;
143     bool isFinished() const { return m_state == IndexedDB::TransactionState::Finished; }
144
145     IDBClient::IDBConnectionProxy& connectionProxy();
146
147     void connectionClosedFromServer(const IDBError&);
148
149     void visitReferencedObjectStores(JSC::SlotVisitor&) const;
150
151 private:
152     IDBTransaction(IDBDatabase&, const IDBTransactionInfo&, IDBOpenDBRequest*);
153
154     void commit();
155
156     void internalAbort();
157     void notifyDidAbort(const IDBError&);
158     void finishAbortOrCommit();
159
160     void scheduleOperation(RefPtr<IDBClient::TransactionOperation>&&);
161     void operationTimerFired();
162
163     void fireOnComplete();
164     void fireOnAbort();
165     void enqueueEvent(Ref<Event>&&);
166
167     Ref<IDBRequest> requestIndexRecord(JSC::ExecState&, IDBIndex&, IndexedDB::IndexRecordType, const IDBKeyRangeData&);
168
169     void commitOnServer(IDBClient::TransactionOperation&);
170     void abortOnServerAndCancelRequests(IDBClient::TransactionOperation&);
171
172     void createObjectStoreOnServer(IDBClient::TransactionOperation&, const IDBObjectStoreInfo&);
173     void didCreateObjectStoreOnServer(const IDBResultData&);
174
175     void renameObjectStoreOnServer(IDBClient::TransactionOperation&, const uint64_t& objectStoreIdentifier, const String& newName);
176     void didRenameObjectStoreOnServer(const IDBResultData&);
177
178     void createIndexOnServer(IDBClient::TransactionOperation&, const IDBIndexInfo&);
179     void didCreateIndexOnServer(const IDBResultData&);
180
181     void renameIndexOnServer(IDBClient::TransactionOperation&, const uint64_t& objectStoreIdentifier, const uint64_t& indexIdentifier, const String& newName);
182     void didRenameIndexOnServer(const IDBResultData&);
183
184     void clearObjectStoreOnServer(IDBClient::TransactionOperation&, const uint64_t& objectStoreIdentifier);
185     void didClearObjectStoreOnServer(IDBRequest&, const IDBResultData&);
186
187     void putOrAddOnServer(IDBClient::TransactionOperation&, RefPtr<IDBKey>, RefPtr<SerializedScriptValue>, const IndexedDB::ObjectStoreOverwriteMode&);
188     void didPutOrAddOnServer(IDBRequest&, const IDBResultData&);
189
190     void getRecordOnServer(IDBClient::TransactionOperation&, const IDBGetRecordData&);
191     void didGetRecordOnServer(IDBRequest&, const IDBResultData&);
192
193     void getAllRecordsOnServer(IDBClient::TransactionOperation&, const IDBGetAllRecordsData&);
194     void didGetAllRecordsOnServer(IDBRequest&, const IDBResultData&);
195
196     void getCountOnServer(IDBClient::TransactionOperation&, const IDBKeyRangeData&);
197     void didGetCountOnServer(IDBRequest&, const IDBResultData&);
198
199     void deleteRecordOnServer(IDBClient::TransactionOperation&, const IDBKeyRangeData&);
200     void didDeleteRecordOnServer(IDBRequest&, const IDBResultData&);
201
202     void deleteObjectStoreOnServer(IDBClient::TransactionOperation&, const String& objectStoreName);
203     void didDeleteObjectStoreOnServer(const IDBResultData&);
204
205     void deleteIndexOnServer(IDBClient::TransactionOperation&, const uint64_t& objectStoreIdentifier, const String& indexName);
206     void didDeleteIndexOnServer(const IDBResultData&);
207
208     Ref<IDBRequest> doRequestOpenCursor(JSC::ExecState&, Ref<IDBCursor>&&);
209     void openCursorOnServer(IDBClient::TransactionOperation&, const IDBCursorInfo&);
210     void didOpenCursorOnServer(IDBRequest&, const IDBResultData&);
211
212     void iterateCursorOnServer(IDBClient::TransactionOperation&, const IDBKeyData&, const unsigned long& count);
213     void didIterateCursorOnServer(IDBRequest&, const IDBResultData&);
214
215     void transitionedToFinishing(IndexedDB::TransactionState);
216
217     void establishOnServer();
218
219     void scheduleOperationTimer();
220
221     Ref<IDBDatabase> m_database;
222     IDBTransactionInfo m_info;
223
224     IndexedDB::TransactionState m_state { IndexedDB::TransactionState::Inactive };
225     bool m_startedOnServer { false };
226
227     IDBError m_idbError;
228     RefPtr<DOMError> m_domError;
229
230     Timer m_operationTimer;
231     std::unique_ptr<Timer> m_activationTimer;
232
233     RefPtr<IDBOpenDBRequest> m_openDBRequest;
234
235     Deque<RefPtr<IDBClient::TransactionOperation>> m_transactionOperationQueue;
236     Deque<RefPtr<IDBClient::TransactionOperation>> m_abortQueue;
237     HashMap<IDBResourceIdentifier, RefPtr<IDBClient::TransactionOperation>> m_transactionOperationMap;
238
239     mutable Lock m_referencedObjectStoreLock;
240     HashMap<String, std::unique_ptr<IDBObjectStore>> m_referencedObjectStores;
241     HashMap<uint64_t, std::unique_ptr<IDBObjectStore>> m_deletedObjectStores;
242
243     HashSet<RefPtr<IDBRequest>> m_openRequests;
244
245     bool m_contextStopped { false };
246 };
247
248 class TransactionActivator {
249     WTF_MAKE_NONCOPYABLE(TransactionActivator);
250 public:
251     TransactionActivator(IDBTransaction* transaction)
252         : m_transaction(transaction)
253     {
254         if (m_transaction)
255             m_transaction->activate();
256     }
257
258     ~TransactionActivator()
259     {
260         if (m_transaction)
261             m_transaction->deactivate();
262     }
263
264 private:
265     IDBTransaction* m_transaction;
266 };
267
268 } // namespace WebCore
269
270 #endif // ENABLE(INDEXED_DATABASE)