Modern IDB: Pipe through cursor functions from client to server.
[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 TransactionOperation;
58
59 class IDBTransaction : public WebCore::IDBTransaction {
60 public:
61     static Ref<IDBTransaction> create(IDBDatabase&, const IDBTransactionInfo&);
62
63     virtual ~IDBTransaction() override final;
64
65     // IDBTransaction IDL
66     virtual const String& mode() const override final;
67     virtual WebCore::IDBDatabase* db() override final;
68     virtual RefPtr<DOMError> error() const override final;
69     virtual RefPtr<WebCore::IDBObjectStore> objectStore(const String& name, ExceptionCode&) override final;
70     virtual void abort(ExceptionCode&) override final;
71
72     virtual EventTargetInterface eventTargetInterface() const override final { return IDBTransactionEventTargetInterfaceType; }
73     virtual ScriptExecutionContext* scriptExecutionContext() const override final { return ActiveDOMObject::scriptExecutionContext(); }
74     virtual void refEventTarget() override final { ref(); }
75     virtual void derefEventTarget() override final { deref(); }
76     using EventTarget::dispatchEvent;
77     virtual bool dispatchEvent(Event&) override final;
78
79     virtual const char* activeDOMObjectName() const override final;
80     virtual bool canSuspendForPageCache() const override final;
81     virtual bool hasPendingActivity() const override final;
82
83     const IDBTransactionInfo info() const { return m_info; }
84     IDBDatabase& database() { return m_database.get(); }
85     const IDBDatabase& database() const { return m_database.get(); }
86     IDBDatabaseInfo* originalDatabaseInfo() const { return m_originalDatabaseInfo.get(); }
87
88     void didStart(const IDBError&);
89     void didAbort(const IDBError&);
90     void didCommit(const IDBError&);
91
92     bool isVersionChange() const { return m_info.mode() == IndexedDB::TransactionMode::VersionChange; }
93     bool isReadOnly() const { return m_info.mode() == IndexedDB::TransactionMode::ReadOnly; }
94     bool isActive() const;
95
96     Ref<IDBObjectStore> createObjectStore(const IDBObjectStoreInfo&);
97     Ref<IDBIndex> createIndex(IDBObjectStore&, const IDBIndexInfo&);
98
99     Ref<IDBRequest> requestPutOrAdd(ScriptExecutionContext&, IDBObjectStore&, IDBKey*, SerializedScriptValue&, IndexedDB::ObjectStoreOverwriteMode);
100     Ref<IDBRequest> requestGetRecord(ScriptExecutionContext&, IDBObjectStore&, const IDBKeyRangeData&);
101     Ref<IDBRequest> requestDeleteRecord(ScriptExecutionContext&, IDBObjectStore&, const IDBKeyRangeData&);
102     Ref<IDBRequest> requestClearObjectStore(ScriptExecutionContext&, IDBObjectStore&);
103     Ref<IDBRequest> requestCount(ScriptExecutionContext&, IDBObjectStore&, const IDBKeyRangeData&);
104     Ref<IDBRequest> requestCount(ScriptExecutionContext&, IDBIndex&, const IDBKeyRangeData&);
105     Ref<IDBRequest> requestGetValue(ScriptExecutionContext&, IDBIndex&, const IDBKeyRangeData&);
106     Ref<IDBRequest> requestGetKey(ScriptExecutionContext&, IDBIndex&, const IDBKeyRangeData&);
107     Ref<IDBRequest> requestOpenCursor(ScriptExecutionContext&, IDBObjectStore&, const IDBCursorInfo&);
108     Ref<IDBRequest> requestOpenCursor(ScriptExecutionContext&, IDBIndex&, const IDBCursorInfo&);
109     void iterateCursor(IDBCursor&, const IDBKeyData&, unsigned long count);
110
111     void deleteObjectStore(const String& objectStoreName);
112
113     void addRequest(IDBRequest&);
114     void removeRequest(IDBRequest&);
115
116     IDBConnectionToServer& serverConnection();
117
118     void activate();
119     void deactivate();
120
121     void operationDidComplete(TransactionOperation&);
122
123 private:
124     IDBTransaction(IDBDatabase&, const IDBTransactionInfo&);
125
126     bool isFinishedOrFinishing() const;
127
128     void commit();
129
130     void finishAbortOrCommit();
131
132     void scheduleOperation(RefPtr<TransactionOperation>&&);
133     void operationTimerFired();
134
135     void fireOnComplete();
136     void fireOnAbort();
137     void enqueueEvent(Ref<Event>&&);
138
139     Ref<IDBRequest> requestIndexRecord(ScriptExecutionContext&, IDBIndex&, IndexedDB::IndexRecordType, const IDBKeyRangeData&);
140
141     void commitOnServer(TransactionOperation&);
142     void abortOnServer(TransactionOperation&);
143
144     void createObjectStoreOnServer(TransactionOperation&, const IDBObjectStoreInfo&);
145     void didCreateObjectStoreOnServer(const IDBResultData&);
146
147     void createIndexOnServer(TransactionOperation&, const IDBIndexInfo&);
148     void didCreateIndexOnServer(const IDBResultData&);
149
150     void clearObjectStoreOnServer(TransactionOperation&, const uint64_t& objectStoreIdentifier);
151     void didClearObjectStoreOnServer(IDBRequest&, const IDBResultData&);
152
153     void putOrAddOnServer(TransactionOperation&, RefPtr<IDBKey>, RefPtr<SerializedScriptValue>, const IndexedDB::ObjectStoreOverwriteMode&);
154     void didPutOrAddOnServer(IDBRequest&, const IDBResultData&);
155
156     void getRecordOnServer(TransactionOperation&, const IDBKeyRangeData&);
157     void didGetRecordOnServer(IDBRequest&, const IDBResultData&);
158
159     void getCountOnServer(TransactionOperation&, const IDBKeyRangeData&);
160     void didGetCountOnServer(IDBRequest&, const IDBResultData&);
161
162     void deleteRecordOnServer(TransactionOperation&, const IDBKeyRangeData&);
163     void didDeleteRecordOnServer(IDBRequest&, const IDBResultData&);
164
165     void deleteObjectStoreOnServer(TransactionOperation&, const String& objectStoreName);
166     void didDeleteObjectStoreOnServer(const IDBResultData&);
167
168     Ref<IDBRequest> doRequestOpenCursor(ScriptExecutionContext&, Ref<IDBCursor>&&);
169     void openCursorOnServer(TransactionOperation&, const IDBCursorInfo&);
170     void didOpenCursorOnServer(IDBRequest&, const IDBResultData&);
171
172     void iterateCursorOnServer(TransactionOperation&, const IDBKeyData&, const unsigned long& count);
173     void didIterateCursorOnServer(IDBRequest&, const IDBResultData&);
174
175     void establishOnServer();
176
177     void scheduleOperationTimer();
178
179     Ref<IDBDatabase> m_database;
180     IDBTransactionInfo m_info;
181     std::unique_ptr<IDBDatabaseInfo> m_originalDatabaseInfo;
182
183     IndexedDB::TransactionState m_state { IndexedDB::TransactionState::Inactive };
184     bool m_startedOnServer { false };
185
186     IDBError m_idbError;
187
188     Timer m_operationTimer;
189     std::unique_ptr<Timer> m_activationTimer;
190
191     Deque<RefPtr<TransactionOperation>> m_transactionOperationQueue;
192     HashMap<IDBResourceIdentifier, RefPtr<TransactionOperation>> m_transactionOperationMap;
193
194     HashMap<String, RefPtr<IDBObjectStore>> m_referencedObjectStores;
195
196     HashSet<RefPtr<IDBRequest>> m_openRequests;
197 };
198
199 class TransactionActivator {
200     WTF_MAKE_NONCOPYABLE(TransactionActivator);
201 public:
202     TransactionActivator(IDBTransaction* transaction)
203         : m_transaction(transaction)
204     {
205         if (m_transaction)
206             m_transaction->activate();
207     }
208
209     ~TransactionActivator()
210     {
211         if (m_transaction)
212             m_transaction->deactivate();
213     }
214
215 private:
216     IDBTransaction* m_transaction;
217 };
218
219 } // namespace IDBClient
220 } // namespace WebCore
221
222 #endif // ENABLE(INDEXED_DATABASE)
223 #endif // IDBTransactionImpl_h