Modern IDB: storage/indexeddb/delete-in-upgradeneeded-close-in-versionchange.html...
[WebKit-https.git] / Source / WebCore / Modules / indexeddb / client / IDBTransactionImpl.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 #ifndef IDBTransactionImpl_h
27 #define IDBTransactionImpl_h
28
29 #if ENABLE(INDEXED_DATABASE)
30
31 #include "IDBDatabaseInfo.h"
32 #include "IDBError.h"
33 #include "IDBIndexImpl.h"
34 #include "IDBObjectStoreImpl.h"
35 #include "IDBTransaction.h"
36 #include "IDBTransactionInfo.h"
37 #include "IndexedDB.h"
38 #include "Timer.h"
39 #include <wtf/Deque.h>
40 #include <wtf/HashMap.h>
41
42 namespace WebCore {
43
44 class IDBCursorInfo;
45 class IDBIndexInfo;
46 class IDBKeyData;
47 class IDBObjectStoreInfo;
48 class IDBResultData;
49
50 struct IDBKeyRangeData;
51
52 namespace IDBClient {
53
54 class IDBCursor;
55 class IDBDatabase;
56 class IDBIndex;
57 class IDBOpenDBRequest;
58 class TransactionOperation;
59
60 class IDBTransaction : public WebCore::IDBTransaction {
61 public:
62     static Ref<IDBTransaction> create(IDBDatabase&, const IDBTransactionInfo&);
63     static Ref<IDBTransaction> create(IDBDatabase&, const IDBTransactionInfo&, IDBOpenDBRequest&);
64
65     virtual ~IDBTransaction() override final;
66
67     // IDBTransaction IDL
68     virtual const String& mode() const override final;
69     virtual WebCore::IDBDatabase* db() override final;
70     virtual RefPtr<DOMError> error() const override final;
71     virtual RefPtr<WebCore::IDBObjectStore> objectStore(const String& name, ExceptionCodeWithMessage&) override final;
72     virtual void abort(ExceptionCodeWithMessage&) override final;
73
74     virtual EventTargetInterface eventTargetInterface() const override final { return IDBTransactionEventTargetInterfaceType; }
75     virtual ScriptExecutionContext* scriptExecutionContext() const override final { return ActiveDOMObject::scriptExecutionContext(); }
76     virtual void refEventTarget() override final { ref(); }
77     virtual void derefEventTarget() override final { deref(); }
78     using EventTarget::dispatchEvent;
79     virtual bool dispatchEvent(Event&) override final;
80
81     virtual const char* activeDOMObjectName() const override final;
82     virtual bool canSuspendForDocumentSuspension() const override final;
83     virtual bool hasPendingActivity() const override final;
84     virtual void stop() override final;
85
86     const IDBTransactionInfo& info() const { return m_info; }
87     IDBDatabase& database() { return m_database.get(); }
88     const IDBDatabase& database() const { return m_database.get(); }
89     IDBDatabaseInfo* originalDatabaseInfo() const { return m_info.originalDatabaseInfo(); }
90
91     void didStart(const IDBError&);
92     void didAbort(const IDBError&);
93     void didCommit(const IDBError&);
94
95     bool isVersionChange() const { return m_info.mode() == IndexedDB::TransactionMode::VersionChange; }
96     bool isReadOnly() const { return m_info.mode() == IndexedDB::TransactionMode::ReadOnly; }
97     bool isActive() const;
98
99     Ref<IDBObjectStore> createObjectStore(const IDBObjectStoreInfo&);
100     Ref<IDBIndex> createIndex(IDBObjectStore&, const IDBIndexInfo&);
101
102     Ref<IDBRequest> requestPutOrAdd(ScriptExecutionContext&, IDBObjectStore&, IDBKey*, SerializedScriptValue&, IndexedDB::ObjectStoreOverwriteMode);
103     Ref<IDBRequest> requestGetRecord(ScriptExecutionContext&, IDBObjectStore&, const IDBKeyRangeData&);
104     Ref<IDBRequest> requestDeleteRecord(ScriptExecutionContext&, IDBObjectStore&, const IDBKeyRangeData&);
105     Ref<IDBRequest> requestClearObjectStore(ScriptExecutionContext&, IDBObjectStore&);
106     Ref<IDBRequest> requestCount(ScriptExecutionContext&, IDBObjectStore&, const IDBKeyRangeData&);
107     Ref<IDBRequest> requestCount(ScriptExecutionContext&, IDBIndex&, const IDBKeyRangeData&);
108     Ref<IDBRequest> requestGetValue(ScriptExecutionContext&, IDBIndex&, const IDBKeyRangeData&);
109     Ref<IDBRequest> requestGetKey(ScriptExecutionContext&, IDBIndex&, const IDBKeyRangeData&);
110     Ref<IDBRequest> requestOpenCursor(ScriptExecutionContext&, IDBObjectStore&, const IDBCursorInfo&);
111     Ref<IDBRequest> requestOpenCursor(ScriptExecutionContext&, IDBIndex&, const IDBCursorInfo&);
112     void iterateCursor(IDBCursor&, const IDBKeyData&, unsigned long count);
113
114     void deleteObjectStore(const String& objectStoreName);
115     void deleteIndex(uint64_t objectStoreIdentifier, const String& indexName);
116
117     void addRequest(IDBRequest&);
118     void removeRequest(IDBRequest&);
119
120     void abortDueToFailedRequest(DOMError&);
121
122     IDBConnectionToServer& serverConnection();
123
124     void activate();
125     void deactivate();
126
127     void operationDidComplete(TransactionOperation&);
128
129     bool isFinishedOrFinishing() const;
130     bool isFinished() const { return m_state == IndexedDB::TransactionState::Finished; }
131
132 private:
133     IDBTransaction(IDBDatabase&, const IDBTransactionInfo&, IDBOpenDBRequest*);
134
135     void commit();
136
137     void notifyDidAbort(const IDBError&);
138     void finishAbortOrCommit();
139
140     void scheduleOperation(RefPtr<TransactionOperation>&&);
141     void operationTimerFired();
142
143     void fireOnComplete();
144     void fireOnAbort();
145     void enqueueEvent(Ref<Event>&&);
146
147     Ref<IDBRequest> requestIndexRecord(ScriptExecutionContext&, IDBIndex&, IndexedDB::IndexRecordType, const IDBKeyRangeData&);
148
149     void commitOnServer(TransactionOperation&);
150     void abortOnServerAndCancelRequests(TransactionOperation&);
151
152     void createObjectStoreOnServer(TransactionOperation&, const IDBObjectStoreInfo&);
153     void didCreateObjectStoreOnServer(const IDBResultData&);
154
155     void createIndexOnServer(TransactionOperation&, const IDBIndexInfo&);
156     void didCreateIndexOnServer(const IDBResultData&);
157
158     void clearObjectStoreOnServer(TransactionOperation&, const uint64_t& objectStoreIdentifier);
159     void didClearObjectStoreOnServer(IDBRequest&, const IDBResultData&);
160
161     void putOrAddOnServer(TransactionOperation&, RefPtr<IDBKey>, RefPtr<SerializedScriptValue>, const IndexedDB::ObjectStoreOverwriteMode&);
162     void didPutOrAddOnServer(IDBRequest&, const IDBResultData&);
163
164     void getRecordOnServer(TransactionOperation&, const IDBKeyRangeData&);
165     void didGetRecordOnServer(IDBRequest&, const IDBResultData&);
166
167     void getCountOnServer(TransactionOperation&, const IDBKeyRangeData&);
168     void didGetCountOnServer(IDBRequest&, const IDBResultData&);
169
170     void deleteRecordOnServer(TransactionOperation&, const IDBKeyRangeData&);
171     void didDeleteRecordOnServer(IDBRequest&, const IDBResultData&);
172
173     void deleteObjectStoreOnServer(TransactionOperation&, const String& objectStoreName);
174     void didDeleteObjectStoreOnServer(const IDBResultData&);
175
176     void deleteIndexOnServer(TransactionOperation&, const uint64_t& objectStoreIdentifier, const String& indexName);
177     void didDeleteIndexOnServer(const IDBResultData&);
178
179     Ref<IDBRequest> doRequestOpenCursor(ScriptExecutionContext&, Ref<IDBCursor>&&);
180     void openCursorOnServer(TransactionOperation&, const IDBCursorInfo&);
181     void didOpenCursorOnServer(IDBRequest&, const IDBResultData&);
182
183     void iterateCursorOnServer(TransactionOperation&, const IDBKeyData&, const unsigned long& count);
184     void didIterateCursorOnServer(IDBRequest&, const IDBResultData&);
185
186     void establishOnServer();
187
188     void scheduleOperationTimer();
189
190     Ref<IDBDatabase> m_database;
191     IDBTransactionInfo m_info;
192
193     IndexedDB::TransactionState m_state { IndexedDB::TransactionState::Inactive };
194     bool m_startedOnServer { false };
195
196     IDBError m_idbError;
197     RefPtr<DOMError> m_domError;
198
199     Timer m_operationTimer;
200     std::unique_ptr<Timer> m_activationTimer;
201
202     RefPtr<IDBOpenDBRequest> m_openDBRequest;
203
204     Deque<RefPtr<TransactionOperation>> m_transactionOperationQueue;
205     Deque<RefPtr<TransactionOperation>> m_abortQueue;
206     HashMap<IDBResourceIdentifier, RefPtr<TransactionOperation>> m_transactionOperationMap;
207
208     HashMap<String, RefPtr<IDBObjectStore>> m_referencedObjectStores;
209
210     HashSet<RefPtr<IDBRequest>> m_openRequests;
211
212     bool m_contextStopped { false };
213 };
214
215 class TransactionActivator {
216     WTF_MAKE_NONCOPYABLE(TransactionActivator);
217 public:
218     TransactionActivator(IDBTransaction* transaction)
219         : m_transaction(transaction)
220     {
221         if (m_transaction)
222             m_transaction->activate();
223     }
224
225     ~TransactionActivator()
226     {
227         if (m_transaction)
228             m_transaction->deactivate();
229     }
230
231 private:
232     IDBTransaction* m_transaction;
233 };
234
235 } // namespace IDBClient
236 } // namespace WebCore
237
238 #endif // ENABLE(INDEXED_DATABASE)
239 #endif // IDBTransactionImpl_h