807a423030ffcf68b727a1dee060b440e87989fd
[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 "IDBGetRecordData.h"
35 #include "IDBIterateCursorData.h"
36 #include "IDBKeyRangeData.h"
37 #include "IDBOpenDBRequest.h"
38 #include "IDBRequestData.h"
39 #include "IDBResultData.h"
40 #include "IDBValue.h"
41 #include "Logging.h"
42 #include "ProcessIdentifier.h"
43 #include <wtf/FileSystem.h>
44 #include <wtf/RunLoop.h>
45
46 namespace WebCore {
47
48 Ref<InProcessIDBServer> InProcessIDBServer::create(PAL::SessionID sessionID)
49 {
50     Ref<InProcessIDBServer> server = adoptRef(*new InProcessIDBServer(sessionID));
51     server->m_server->registerConnection(server->connectionToClient());
52     return server;
53 }
54
55 Ref<InProcessIDBServer> InProcessIDBServer::create(PAL::SessionID sessionID, const String& databaseDirectoryPath)
56 {
57     Ref<InProcessIDBServer> server = adoptRef(*new InProcessIDBServer(sessionID, databaseDirectoryPath));
58     server->m_server->registerConnection(server->connectionToClient());
59     return server;
60 }
61
62 InProcessIDBServer::~InProcessIDBServer() = default;
63
64 StorageQuotaManager* InProcessIDBServer::quotaManager(const ClientOrigin& origin)
65 {
66     return m_quotaManagers.ensure(origin, [] {
67         return makeUnique<StorageQuotaManager>(StorageQuotaManager::defaultQuota(), [](uint64_t quota, uint64_t currentSpace, uint64_t spaceIncrease, auto callback) {
68             callback(quota + currentSpace + spaceIncrease);
69         });
70     }).iterator->value.get();
71 }
72
73 static inline IDBServer::IDBServer::QuotaManagerGetter storageQuotaManagerGetter(InProcessIDBServer& server)
74 {
75     return [weakServer = makeWeakPtr(server)](PAL::SessionID, const auto& origin) {
76         return weakServer ? weakServer->quotaManager(origin) : nullptr;
77     };
78 }
79
80 InProcessIDBServer::InProcessIDBServer(PAL::SessionID sessionID)
81     : m_server(IDBServer::IDBServer::create(sessionID, *this, storageQuotaManagerGetter(*this)))
82 {
83     relaxAdoptionRequirement();
84     m_connectionToServer = IDBClient::IDBConnectionToServer::create(*this);
85     m_connectionToClient = IDBServer::IDBConnectionToClient::create(*this);
86 }
87
88 InProcessIDBServer::InProcessIDBServer(PAL::SessionID sessionID, const String& databaseDirectoryPath)
89     : m_server(IDBServer::IDBServer::create(sessionID, databaseDirectoryPath, *this, storageQuotaManagerGetter(*this)))
90 {
91     relaxAdoptionRequirement();
92     m_connectionToServer = IDBClient::IDBConnectionToServer::create(*this);
93     m_connectionToClient = IDBServer::IDBConnectionToClient::create(*this);
94 }
95
96 IDBConnectionIdentifier InProcessIDBServer::identifier() const
97 {
98     // An instance of InProcessIDBServer always has a 1:1 relationship with its instance of IDBServer.
99     // Therefore the connection identifier between the two can always be "1".
100     return Process::identifier();
101 }
102
103 IDBClient::IDBConnectionToServer& InProcessIDBServer::connectionToServer() const
104 {
105     return *m_connectionToServer;
106 }
107
108 IDBServer::IDBConnectionToClient& InProcessIDBServer::connectionToClient() const
109 {
110     return *m_connectionToClient;
111 }
112
113 void InProcessIDBServer::deleteDatabase(const IDBRequestData& requestData)
114 {
115     RunLoop::current().dispatch([this, protectedThis = makeRef(*this), requestData] {
116         m_server->deleteDatabase(requestData);
117     });
118 }
119
120 void InProcessIDBServer::didDeleteDatabase(const IDBResultData& resultData)
121 {
122     RunLoop::current().dispatch([this, protectedThis = makeRef(*this), resultData] {
123         m_connectionToServer->didDeleteDatabase(resultData);
124     });
125 }
126
127 void InProcessIDBServer::openDatabase(const IDBRequestData& requestData)
128 {
129     RunLoop::current().dispatch([this, protectedThis = makeRef(*this), requestData] {
130         m_server->openDatabase(requestData);
131     });
132 }
133
134 void InProcessIDBServer::didOpenDatabase(const IDBResultData& resultData)
135 {
136     RunLoop::current().dispatch([this, protectedThis = makeRef(*this), resultData] {
137         m_connectionToServer->didOpenDatabase(resultData);
138     });
139 }
140
141 void InProcessIDBServer::didAbortTransaction(const IDBResourceIdentifier& transactionIdentifier, const IDBError& error)
142 {
143     RunLoop::current().dispatch([this, protectedThis = makeRef(*this), transactionIdentifier, error] {
144         m_connectionToServer->didAbortTransaction(transactionIdentifier, error);
145     });
146 }
147
148 void InProcessIDBServer::didCommitTransaction(const IDBResourceIdentifier& transactionIdentifier, const IDBError& error)
149 {
150     RunLoop::current().dispatch([this, protectedThis = makeRef(*this), transactionIdentifier, error] {
151         m_connectionToServer->didCommitTransaction(transactionIdentifier, error);
152     });
153 }
154
155 void InProcessIDBServer::didCreateObjectStore(const IDBResultData& resultData)
156 {
157     RunLoop::current().dispatch([this, protectedThis = makeRef(*this), resultData] {
158         m_connectionToServer->didCreateObjectStore(resultData);
159     });
160 }
161
162 void InProcessIDBServer::didDeleteObjectStore(const IDBResultData& resultData)
163 {
164     RunLoop::current().dispatch([this, protectedThis = makeRef(*this), resultData] {
165         m_connectionToServer->didDeleteObjectStore(resultData);
166     });
167 }
168
169 void InProcessIDBServer::didRenameObjectStore(const IDBResultData& resultData)
170 {
171     RunLoop::current().dispatch([this, protectedThis = makeRef(*this), resultData] {
172         m_connectionToServer->didRenameObjectStore(resultData);
173     });
174 }
175
176 void InProcessIDBServer::didClearObjectStore(const IDBResultData& resultData)
177 {
178     RunLoop::current().dispatch([this, protectedThis = makeRef(*this), resultData] {
179         m_connectionToServer->didClearObjectStore(resultData);
180     });
181 }
182
183 void InProcessIDBServer::didCreateIndex(const IDBResultData& resultData)
184 {
185     RunLoop::current().dispatch([this, protectedThis = makeRef(*this), resultData] {
186         m_connectionToServer->didCreateIndex(resultData);
187     });
188 }
189
190 void InProcessIDBServer::didDeleteIndex(const IDBResultData& resultData)
191 {
192     RunLoop::current().dispatch([this, protectedThis = makeRef(*this), resultData] {
193         m_connectionToServer->didDeleteIndex(resultData);
194     });
195 }
196
197 void InProcessIDBServer::didRenameIndex(const IDBResultData& resultData)
198 {
199     RunLoop::current().dispatch([this, protectedThis = makeRef(*this), resultData] {
200         m_connectionToServer->didRenameIndex(resultData);
201     });
202 }
203
204 void InProcessIDBServer::didPutOrAdd(const IDBResultData& resultData)
205 {
206     RunLoop::current().dispatch([this, protectedThis = makeRef(*this), resultData] {
207         m_connectionToServer->didPutOrAdd(resultData);
208     });
209 }
210
211 void InProcessIDBServer::didGetRecord(const IDBResultData& resultData)
212 {
213     RunLoop::current().dispatch([this, protectedThis = makeRef(*this), resultData] {
214         m_connectionToServer->didGetRecord(resultData);
215     });
216 }
217
218 void InProcessIDBServer::didGetAllRecords(const IDBResultData& resultData)
219 {
220     RunLoop::current().dispatch([this, protectedThis = makeRef(*this), resultData] {
221         m_connectionToServer->didGetAllRecords(resultData);
222     });
223 }
224
225 void InProcessIDBServer::didGetCount(const IDBResultData& resultData)
226 {
227     RunLoop::current().dispatch([this, protectedThis = makeRef(*this), resultData] {
228         m_connectionToServer->didGetCount(resultData);
229     });
230 }
231
232 void InProcessIDBServer::didDeleteRecord(const IDBResultData& resultData)
233 {
234     RunLoop::current().dispatch([this, protectedThis = makeRef(*this), resultData] {
235         m_connectionToServer->didDeleteRecord(resultData);
236     });
237 }
238
239 void InProcessIDBServer::didOpenCursor(const IDBResultData& resultData)
240 {
241     RunLoop::current().dispatch([this, protectedThis = makeRef(*this), resultData] {
242         m_connectionToServer->didOpenCursor(resultData);
243     });
244 }
245
246 void InProcessIDBServer::didIterateCursor(const IDBResultData& resultData)
247 {
248     RunLoop::current().dispatch([this, protectedThis = makeRef(*this), resultData] {
249         m_connectionToServer->didIterateCursor(resultData);
250     });
251 }
252
253 void InProcessIDBServer::abortTransaction(const IDBResourceIdentifier& resourceIdentifier)
254 {
255     RunLoop::current().dispatch([this, protectedThis = makeRef(*this), resourceIdentifier] {
256         m_server->abortTransaction(resourceIdentifier);
257     });
258 }
259
260 void InProcessIDBServer::commitTransaction(const IDBResourceIdentifier& resourceIdentifier)
261 {
262     RunLoop::current().dispatch([this, protectedThis = makeRef(*this), resourceIdentifier] {
263         m_server->commitTransaction(resourceIdentifier);
264     });
265 }
266
267 void InProcessIDBServer::didFinishHandlingVersionChangeTransaction(uint64_t databaseConnectionIdentifier, const IDBResourceIdentifier& transactionIdentifier)
268 {
269     RunLoop::current().dispatch([this, protectedThis = makeRef(*this), databaseConnectionIdentifier, transactionIdentifier] {
270         m_server->didFinishHandlingVersionChangeTransaction(databaseConnectionIdentifier, transactionIdentifier);
271     });
272 }
273
274 void InProcessIDBServer::createObjectStore(const IDBRequestData& resultData, const IDBObjectStoreInfo& info)
275 {
276     RunLoop::current().dispatch([this, protectedThis = makeRef(*this), resultData, info] {
277         m_server->createObjectStore(resultData, info);
278     });
279 }
280
281 void InProcessIDBServer::deleteObjectStore(const IDBRequestData& requestData, const String& objectStoreName)
282 {
283     RunLoop::current().dispatch([this, protectedThis = makeRef(*this), requestData, objectStoreName] {
284         m_server->deleteObjectStore(requestData, objectStoreName);
285     });
286 }
287
288 void InProcessIDBServer::renameObjectStore(const IDBRequestData& requestData, uint64_t objectStoreIdentifier, const String& newName)
289 {
290     RunLoop::current().dispatch([this, protectedThis = makeRef(*this), requestData, objectStoreIdentifier, newName] {
291         m_server->renameObjectStore(requestData, objectStoreIdentifier, newName);
292     });
293 }
294
295 void InProcessIDBServer::clearObjectStore(const IDBRequestData& requestData, uint64_t objectStoreIdentifier)
296 {
297     RunLoop::current().dispatch([this, protectedThis = makeRef(*this), requestData, objectStoreIdentifier] {
298         m_server->clearObjectStore(requestData, objectStoreIdentifier);
299     });
300 }
301
302 void InProcessIDBServer::createIndex(const IDBRequestData& requestData, const IDBIndexInfo& info)
303 {
304     RunLoop::current().dispatch([this, protectedThis = makeRef(*this), requestData, info] {
305         m_server->createIndex(requestData, info);
306     });
307 }
308
309 void InProcessIDBServer::deleteIndex(const IDBRequestData& requestData, uint64_t objectStoreIdentifier, const String& indexName)
310 {
311     RunLoop::current().dispatch([this, protectedThis = makeRef(*this), requestData, objectStoreIdentifier, indexName] {
312         m_server->deleteIndex(requestData, objectStoreIdentifier, indexName);
313     });
314 }
315
316 void InProcessIDBServer::renameIndex(const IDBRequestData& requestData, uint64_t objectStoreIdentifier, uint64_t indexIdentifier, const String& newName)
317 {
318     RunLoop::current().dispatch([this, protectedThis = makeRef(*this), requestData, objectStoreIdentifier, indexIdentifier, newName] {
319         m_server->renameIndex(requestData, objectStoreIdentifier, indexIdentifier, newName);
320     });
321 }
322
323 void InProcessIDBServer::putOrAdd(const IDBRequestData& requestData, const IDBKeyData& keyData, const IDBValue& value, const IndexedDB::ObjectStoreOverwriteMode overwriteMode)
324 {
325     RunLoop::current().dispatch([this, protectedThis = makeRef(*this), requestData, keyData, value, overwriteMode] {
326         m_server->putOrAdd(requestData, keyData, value, overwriteMode);
327     });
328 }
329
330 void InProcessIDBServer::getRecord(const IDBRequestData& requestData, const IDBGetRecordData& getRecordData)
331 {
332     RunLoop::current().dispatch([this, protectedThis = makeRef(*this), requestData, getRecordData] {
333         m_server->getRecord(requestData, getRecordData);
334     });
335 }
336
337 void InProcessIDBServer::getAllRecords(const IDBRequestData& requestData, const IDBGetAllRecordsData& getAllRecordsData)
338 {
339     RunLoop::current().dispatch([this, protectedThis = makeRef(*this), requestData, getAllRecordsData] {
340         m_server->getAllRecords(requestData, getAllRecordsData);
341     });
342 }
343
344 void InProcessIDBServer::getCount(const IDBRequestData& requestData, const IDBKeyRangeData& keyRangeData)
345 {
346     RunLoop::current().dispatch([this, protectedThis = makeRef(*this), requestData, keyRangeData] {
347         m_server->getCount(requestData, keyRangeData);
348     });
349 }
350
351 void InProcessIDBServer::deleteRecord(const IDBRequestData& requestData, const IDBKeyRangeData& keyRangeData)
352 {
353     RunLoop::current().dispatch([this, protectedThis = makeRef(*this), requestData, keyRangeData] {
354         m_server->deleteRecord(requestData, keyRangeData);
355     });
356 }
357
358 void InProcessIDBServer::openCursor(const IDBRequestData& requestData, const IDBCursorInfo& info)
359 {
360     RunLoop::current().dispatch([this, protectedThis = makeRef(*this), requestData, info] {
361         m_server->openCursor(requestData, info);
362     });
363 }
364
365 void InProcessIDBServer::iterateCursor(const IDBRequestData& requestData, const IDBIterateCursorData& data)
366 {
367     RunLoop::current().dispatch([this, protectedThis = makeRef(*this), requestData, data] {
368         m_server->iterateCursor(requestData, data);
369     });
370 }
371
372 void InProcessIDBServer::establishTransaction(uint64_t databaseConnectionIdentifier, const IDBTransactionInfo& info)
373 {
374     RunLoop::current().dispatch([this, protectedThis = makeRef(*this), databaseConnectionIdentifier, info] {
375         m_server->establishTransaction(databaseConnectionIdentifier, info);
376     });
377 }
378
379 void InProcessIDBServer::fireVersionChangeEvent(IDBServer::UniqueIDBDatabaseConnection& connection, const IDBResourceIdentifier& requestIdentifier, uint64_t requestedVersion)
380 {
381     RunLoop::current().dispatch([this, protectedThis = makeRef(*this), databaseConnectionIdentifier = connection.identifier(), requestIdentifier, requestedVersion] {
382         m_connectionToServer->fireVersionChangeEvent(databaseConnectionIdentifier, requestIdentifier, requestedVersion);
383     });
384 }
385
386 void InProcessIDBServer::didStartTransaction(const IDBResourceIdentifier& transactionIdentifier, const IDBError& error)
387 {
388     RunLoop::current().dispatch([this, protectedThis = makeRef(*this), transactionIdentifier, error] {
389         m_connectionToServer->didStartTransaction(transactionIdentifier, error);
390     });
391 }
392
393 void InProcessIDBServer::didCloseFromServer(IDBServer::UniqueIDBDatabaseConnection& connection, const IDBError& error)
394 {
395     RunLoop::current().dispatch([this, protectedThis = makeRef(*this), databaseConnectionIdentifier = connection.identifier(), error] {
396         m_connectionToServer->didCloseFromServer(databaseConnectionIdentifier, error);
397     });
398 }
399
400 void InProcessIDBServer::notifyOpenDBRequestBlocked(const IDBResourceIdentifier& requestIdentifier, uint64_t oldVersion, uint64_t newVersion)
401 {
402     RunLoop::current().dispatch([this, protectedThis = makeRef(*this), requestIdentifier, oldVersion, newVersion] {
403         m_connectionToServer->notifyOpenDBRequestBlocked(requestIdentifier, oldVersion, newVersion);
404     });
405 }
406
407 void InProcessIDBServer::databaseConnectionPendingClose(uint64_t databaseConnectionIdentifier)
408 {
409     RunLoop::current().dispatch([this, protectedThis = makeRef(*this), databaseConnectionIdentifier] {
410         m_server->databaseConnectionPendingClose(databaseConnectionIdentifier);
411     });
412 }
413
414 void InProcessIDBServer::databaseConnectionClosed(uint64_t databaseConnectionIdentifier)
415 {
416     RunLoop::current().dispatch([this, protectedThis = makeRef(*this), databaseConnectionIdentifier] {
417         m_server->databaseConnectionClosed(databaseConnectionIdentifier);
418     });
419 }
420
421 void InProcessIDBServer::abortOpenAndUpgradeNeeded(uint64_t databaseConnectionIdentifier, const IDBResourceIdentifier& transactionIdentifier)
422 {
423     RunLoop::current().dispatch([this, protectedThis = makeRef(*this), databaseConnectionIdentifier, transactionIdentifier] {
424         m_server->abortOpenAndUpgradeNeeded(databaseConnectionIdentifier, transactionIdentifier);
425     });
426 }
427
428 void InProcessIDBServer::didFireVersionChangeEvent(uint64_t databaseConnectionIdentifier, const IDBResourceIdentifier& requestIdentifier)
429 {
430     RunLoop::current().dispatch([this, protectedThis = makeRef(*this), databaseConnectionIdentifier, requestIdentifier] {
431         m_server->didFireVersionChangeEvent(databaseConnectionIdentifier, requestIdentifier);
432     });
433 }
434
435 void InProcessIDBServer::openDBRequestCancelled(const IDBRequestData& requestData)
436 {
437     RunLoop::current().dispatch([this, protectedThis = makeRef(*this), requestData] {
438         m_server->openDBRequestCancelled(requestData);
439     });
440 }
441
442 void InProcessIDBServer::confirmDidCloseFromServer(uint64_t databaseConnectionIdentifier)
443 {
444     RunLoop::current().dispatch([this, protectedThis = makeRef(*this), databaseConnectionIdentifier] {
445         m_server->confirmDidCloseFromServer(databaseConnectionIdentifier);
446     });
447 }
448
449 void InProcessIDBServer::getAllDatabaseNames(const SecurityOriginData& mainFrameOrigin, const SecurityOriginData& openingOrigin, uint64_t callbackID)
450 {
451     RunLoop::current().dispatch([this, protectedThis = makeRef(*this), mainFrameOrigin, openingOrigin, callbackID] {
452         m_server->getAllDatabaseNames(m_connectionToServer->identifier(), mainFrameOrigin, openingOrigin, callbackID);
453     });
454 }
455
456 void InProcessIDBServer::didGetAllDatabaseNames(uint64_t callbackID, const Vector<String>& databaseNames)
457 {
458     RunLoop::current().dispatch([this, protectedThis = makeRef(*this), callbackID, databaseNames] {
459         m_connectionToServer->didGetAllDatabaseNames(callbackID, databaseNames);
460     });
461 }
462
463 void InProcessIDBServer::accessToTemporaryFileComplete(const String& path)
464 {
465     FileSystem::deleteFile(path);
466 }
467
468 } // namespace WebCore
469
470 #endif // ENABLE(INDEXED_DATABASE)