Modern IDB: Only fire blocked events after all open connections have handled their...
[WebKit-https.git] / Source / WebCore / Modules / indexeddb / shared / InProcessIDBServer.cpp
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 #include "config.h"
27 #include "InProcessIDBServer.h"
28
29 #if ENABLE(INDEXED_DATABASE)
30
31 #include "IDBConnectionToClient.h"
32 #include "IDBConnectionToServer.h"
33 #include "IDBCursorInfo.h"
34 #include "IDBKeyRangeData.h"
35 #include "IDBOpenDBRequestImpl.h"
36 #include "IDBRequestData.h"
37 #include "IDBResultData.h"
38 #include "Logging.h"
39 #include <wtf/RunLoop.h>
40
41 namespace WebCore {
42
43 Ref<InProcessIDBServer> InProcessIDBServer::create()
44 {
45     Ref<InProcessIDBServer> server = adoptRef(*new InProcessIDBServer);
46     server->m_server->registerConnection(server->connectionToClient());
47     return server;
48 }
49
50 InProcessIDBServer::InProcessIDBServer()
51     : m_server(IDBServer::IDBServer::create())
52 {
53     relaxAdoptionRequirement();
54     m_connectionToServer = IDBClient::IDBConnectionToServer::create(*this);
55     m_connectionToClient = IDBServer::IDBConnectionToClient::create(*this);
56 }
57
58 uint64_t InProcessIDBServer::identifier() const
59 {
60     // An instance of InProcessIDBServer always has a 1:1 relationship with its instance of IDBServer.
61     // Therefore the connection identifier between the two can always be "1".
62     return 1;
63 }
64
65 IDBClient::IDBConnectionToServer& InProcessIDBServer::connectionToServer() const
66 {
67     return *m_connectionToServer;
68 }
69
70 IDBServer::IDBConnectionToClient& InProcessIDBServer::connectionToClient() const
71 {
72     return *m_connectionToClient;
73 }
74
75 void InProcessIDBServer::deleteDatabase(IDBRequestData& requestData)
76 {
77     RefPtr<InProcessIDBServer> self(this);
78     RunLoop::current().dispatch([this, self, requestData] {
79         m_server->deleteDatabase(requestData);
80     });
81 }
82
83 void InProcessIDBServer::didDeleteDatabase(const IDBResultData& resultData)
84 {
85     RefPtr<InProcessIDBServer> self(this);
86     RunLoop::current().dispatch([this, self, resultData] {
87         m_connectionToServer->didDeleteDatabase(resultData);
88     });
89 }
90
91 void InProcessIDBServer::openDatabase(IDBRequestData& requestData)
92 {
93     RefPtr<InProcessIDBServer> self(this);
94     RunLoop::current().dispatch([this, self, requestData] {
95         m_server->openDatabase(requestData);
96     });
97 }
98
99 void InProcessIDBServer::didOpenDatabase(const IDBResultData& resultData)
100 {
101     RefPtr<InProcessIDBServer> self(this);
102     RunLoop::current().dispatch([this, self, resultData] {
103         m_connectionToServer->didOpenDatabase(resultData);
104     });
105 }
106
107 void InProcessIDBServer::didAbortTransaction(const IDBResourceIdentifier& transactionIdentifier, const IDBError& error)
108 {
109     RefPtr<InProcessIDBServer> self(this);
110     RunLoop::current().dispatch([this, self, transactionIdentifier, error] {
111         m_connectionToServer->didAbortTransaction(transactionIdentifier, error);
112     });
113 }
114
115 void InProcessIDBServer::didCommitTransaction(const IDBResourceIdentifier& transactionIdentifier, const IDBError& error)
116 {
117     RefPtr<InProcessIDBServer> self(this);
118     RunLoop::current().dispatch([this, self, transactionIdentifier, error] {
119         m_connectionToServer->didCommitTransaction(transactionIdentifier, error);
120     });
121 }
122
123 void InProcessIDBServer::didCreateObjectStore(const IDBResultData& resultData)
124 {
125     RefPtr<InProcessIDBServer> self(this);
126     RunLoop::current().dispatch([this, self, resultData] {
127         m_connectionToServer->didCreateObjectStore(resultData);
128     });
129 }
130
131 void InProcessIDBServer::didDeleteObjectStore(const IDBResultData& resultData)
132 {
133     RefPtr<InProcessIDBServer> self(this);
134     RunLoop::current().dispatch([this, self, resultData] {
135         m_connectionToServer->didDeleteObjectStore(resultData);
136     });
137 }
138
139 void InProcessIDBServer::didClearObjectStore(const IDBResultData& resultData)
140 {
141     RefPtr<InProcessIDBServer> self(this);
142     RunLoop::current().dispatch([this, self, resultData] {
143         m_connectionToServer->didClearObjectStore(resultData);
144     });
145 }
146
147 void InProcessIDBServer::didCreateIndex(const IDBResultData& resultData)
148 {
149     RefPtr<InProcessIDBServer> self(this);
150     RunLoop::current().dispatch([this, self, resultData] {
151         m_connectionToServer->didCreateIndex(resultData);
152     });
153 }
154
155 void InProcessIDBServer::didDeleteIndex(const IDBResultData& resultData)
156 {
157     RefPtr<InProcessIDBServer> self(this);
158     RunLoop::current().dispatch([this, self, resultData] {
159         m_connectionToServer->didDeleteIndex(resultData);
160     });
161 }
162
163 void InProcessIDBServer::didPutOrAdd(const IDBResultData& resultData)
164 {
165     RefPtr<InProcessIDBServer> self(this);
166     RunLoop::current().dispatch([this, self, resultData] {
167         m_connectionToServer->didPutOrAdd(resultData);
168     });
169 }
170
171 void InProcessIDBServer::didGetRecord(const IDBResultData& resultData)
172 {
173     RefPtr<InProcessIDBServer> self(this);
174     RunLoop::current().dispatch([this, self, resultData] {
175         m_connectionToServer->didGetRecord(resultData);
176     });
177 }
178
179 void InProcessIDBServer::didGetCount(const IDBResultData& resultData)
180 {
181     RefPtr<InProcessIDBServer> self(this);
182     RunLoop::current().dispatch([this, self, resultData] {
183         m_connectionToServer->didGetCount(resultData);
184     });
185 }
186
187 void InProcessIDBServer::didDeleteRecord(const IDBResultData& resultData)
188 {
189     RefPtr<InProcessIDBServer> self(this);
190     RunLoop::current().dispatch([this, self, resultData] {
191         m_connectionToServer->didDeleteRecord(resultData);
192     });
193 }
194
195 void InProcessIDBServer::didOpenCursor(const IDBResultData& resultData)
196 {
197     RefPtr<InProcessIDBServer> self(this);
198     RunLoop::current().dispatch([this, self, resultData] {
199         m_connectionToServer->didOpenCursor(resultData);
200     });
201 }
202
203 void InProcessIDBServer::didIterateCursor(const IDBResultData& resultData)
204 {
205     RefPtr<InProcessIDBServer> self(this);
206     RunLoop::current().dispatch([this, self, resultData] {
207         m_connectionToServer->didIterateCursor(resultData);
208     });
209 }
210
211 void InProcessIDBServer::abortTransaction(IDBResourceIdentifier& resourceIdentifier)
212 {
213     RefPtr<InProcessIDBServer> self(this);
214     RunLoop::current().dispatch([this, self, resourceIdentifier] {
215         m_server->abortTransaction(resourceIdentifier);
216     });
217 }
218
219 void InProcessIDBServer::commitTransaction(IDBResourceIdentifier& resourceIdentifier)
220 {
221     RefPtr<InProcessIDBServer> self(this);
222     RunLoop::current().dispatch([this, self, resourceIdentifier] {
223         m_server->commitTransaction(resourceIdentifier);
224     });
225 }
226
227 void InProcessIDBServer::didFinishHandlingVersionChangeTransaction(IDBResourceIdentifier& transactionIdentifier)
228 {
229     RefPtr<InProcessIDBServer> self(this);
230     RunLoop::current().dispatch([this, self, transactionIdentifier] {
231         m_server->didFinishHandlingVersionChangeTransaction(transactionIdentifier);
232     });
233 }
234
235 void InProcessIDBServer::createObjectStore(const IDBRequestData& resultData, const IDBObjectStoreInfo& info)
236 {
237     RefPtr<InProcessIDBServer> self(this);
238     RunLoop::current().dispatch([this, self, resultData, info] {
239         m_server->createObjectStore(resultData, info);
240     });
241 }
242
243 void InProcessIDBServer::deleteObjectStore(const IDBRequestData& requestData, const String& objectStoreName)
244 {
245     RefPtr<InProcessIDBServer> self(this);
246     RunLoop::current().dispatch([this, self, requestData, objectStoreName] {
247         m_server->deleteObjectStore(requestData, objectStoreName);
248     });
249 }
250
251 void InProcessIDBServer::clearObjectStore(const IDBRequestData& requestData, uint64_t objectStoreIdentifier)
252 {
253     RefPtr<InProcessIDBServer> self(this);
254     RunLoop::current().dispatch([this, self, requestData, objectStoreIdentifier] {
255         m_server->clearObjectStore(requestData, objectStoreIdentifier);
256     });
257 }
258
259 void InProcessIDBServer::createIndex(const IDBRequestData& requestData, const IDBIndexInfo& info)
260 {
261     RefPtr<InProcessIDBServer> self(this);
262     RunLoop::current().dispatch([this, self, requestData, info] {
263         m_server->createIndex(requestData, info);
264     });
265 }
266
267 void InProcessIDBServer::deleteIndex(const IDBRequestData& requestData, uint64_t objectStoreIdentifier, const String& indexName)
268 {
269     RefPtr<InProcessIDBServer> self(this);
270     RunLoop::current().dispatch([this, self, requestData, objectStoreIdentifier, indexName] {
271         m_server->deleteIndex(requestData, objectStoreIdentifier, indexName);
272     });
273 }
274
275 void InProcessIDBServer::putOrAdd(const IDBRequestData& requestData, IDBKey* key, SerializedScriptValue& value, const IndexedDB::ObjectStoreOverwriteMode overwriteMode)
276 {
277     RefPtr<InProcessIDBServer> self(this);
278     IDBKeyData keyData(key);
279     auto valueData = ThreadSafeDataBuffer::copyVector(value.data());
280
281     RunLoop::current().dispatch([this, self, requestData, keyData, valueData, overwriteMode] {
282         m_server->putOrAdd(requestData, keyData, valueData, overwriteMode);
283     });
284 }
285
286 void InProcessIDBServer::getRecord(const IDBRequestData& requestData, const IDBKeyRangeData& keyRangeData)
287 {
288     RefPtr<InProcessIDBServer> self(this);
289
290     RunLoop::current().dispatch([this, self, requestData, keyRangeData] {
291         m_server->getRecord(requestData, keyRangeData);
292     });
293 }
294
295 void InProcessIDBServer::getCount(const IDBRequestData& requestData, const IDBKeyRangeData& keyRangeData)
296 {
297     RefPtr<InProcessIDBServer> self(this);
298     RunLoop::current().dispatch([this, self, requestData, keyRangeData] {
299         m_server->getCount(requestData, keyRangeData);
300     });
301 }
302
303 void InProcessIDBServer::deleteRecord(const IDBRequestData& requestData, const IDBKeyRangeData& keyRangeData)
304 {
305     RefPtr<InProcessIDBServer> self(this);
306
307     RunLoop::current().dispatch([this, self, requestData, keyRangeData] {
308         m_server->deleteRecord(requestData, keyRangeData);
309     });
310 }
311
312 void InProcessIDBServer::openCursor(const IDBRequestData& requestData, const IDBCursorInfo& info)
313 {
314     RefPtr<InProcessIDBServer> self(this);
315
316     RunLoop::current().dispatch([this, self, requestData, info] {
317         m_server->openCursor(requestData, info);
318     });
319 }
320
321 void InProcessIDBServer::iterateCursor(const IDBRequestData& requestData, const IDBKeyData& key, unsigned long count)
322 {
323     RefPtr<InProcessIDBServer> self(this);
324
325     RunLoop::current().dispatch([this, self, requestData, key, count] {
326         m_server->iterateCursor(requestData, key, count);
327     });
328 }
329
330 void InProcessIDBServer::establishTransaction(uint64_t databaseConnectionIdentifier, const IDBTransactionInfo& info)
331 {
332     RefPtr<InProcessIDBServer> self(this);
333
334     RunLoop::current().dispatch([this, self, databaseConnectionIdentifier, info] {
335         m_server->establishTransaction(databaseConnectionIdentifier, info);
336     });
337 }
338
339 void InProcessIDBServer::fireVersionChangeEvent(IDBServer::UniqueIDBDatabaseConnection& connection, const IDBResourceIdentifier& requestIdentifier, uint64_t requestedVersion)
340 {
341     RefPtr<InProcessIDBServer> self(this);
342     uint64_t databaseConnectionIdentifier = connection.identifier();
343     RunLoop::current().dispatch([this, self, databaseConnectionIdentifier, requestIdentifier, requestedVersion] {
344         m_connectionToServer->fireVersionChangeEvent(databaseConnectionIdentifier, requestIdentifier, requestedVersion);
345     });
346 }
347
348 void InProcessIDBServer::didStartTransaction(const IDBResourceIdentifier& transactionIdentifier, const IDBError& error)
349 {
350     RefPtr<InProcessIDBServer> self(this);
351     RunLoop::current().dispatch([this, self, transactionIdentifier, error] {
352         m_connectionToServer->didStartTransaction(transactionIdentifier, error);
353     });
354 }
355
356 void InProcessIDBServer::notifyOpenDBRequestBlocked(const IDBResourceIdentifier& requestIdentifier, uint64_t oldVersion, uint64_t newVersion)
357 {
358     RefPtr<InProcessIDBServer> self(this);
359     RunLoop::current().dispatch([this, self, requestIdentifier, oldVersion, newVersion] {
360         m_connectionToServer->notifyOpenDBRequestBlocked(requestIdentifier, oldVersion, newVersion);
361     });
362 }
363
364 void InProcessIDBServer::databaseConnectionClosed(uint64_t databaseConnectionIdentifier)
365 {
366     RefPtr<InProcessIDBServer> self(this);
367     RunLoop::current().dispatch([this, self, databaseConnectionIdentifier] {
368         m_server->databaseConnectionClosed(databaseConnectionIdentifier);
369     });
370 }
371
372 void InProcessIDBServer::didFireVersionChangeEvent(uint64_t databaseConnectionIdentifier, const IDBResourceIdentifier& requestIdentifier)
373 {
374     RefPtr<InProcessIDBServer> self(this);
375     RunLoop::current().dispatch([this, self, databaseConnectionIdentifier, requestIdentifier] {
376         m_server->didFireVersionChangeEvent(databaseConnectionIdentifier, requestIdentifier);
377     });
378 }
379
380 } // namespace WebCore
381
382 #endif // ENABLE(INDEXED_DATABASE)