f909cddcbfe5bcb0b39bc34e2239b37ed2d77350
[WebKit-https.git] / Source / WebKit2 / WebProcess / Databases / IndexedDB / WebIDBServerConnection.cpp
1 /*
2  * Copyright (C) 2013 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. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  *
25  */
26
27 #include "config.h"
28 #include "WebIDBServerConnection.h"
29
30 #if ENABLE(INDEXED_DATABASE) && ENABLE(DATABASE_PROCESS)
31
32 #include "AsyncRequest.h"
33 #include "DataReference.h"
34 #include "DatabaseProcessIDBConnectionMessages.h"
35 #include "DatabaseToWebProcessConnectionMessages.h"
36 #include "Logging.h"
37 #include "SecurityOriginData.h"
38 #include "WebProcess.h"
39 #include "WebToDatabaseProcessConnection.h"
40 #include <WebCore/IDBDatabaseMetadata.h>
41 #include <WebCore/SecurityOrigin.h>
42
43 using namespace WebCore;
44
45 namespace WebKit {
46
47 static uint64_t generateServerConnectionIdentifier()
48 {
49     ASSERT(isMainThread());
50     static uint64_t identifier = 0;
51     return ++identifier;
52 }
53
54 PassRefPtr<WebIDBServerConnection> WebIDBServerConnection::create(const String& databaseName, const SecurityOrigin& openingOrigin, const SecurityOrigin& mainFrameOrigin)
55 {
56     RefPtr<WebIDBServerConnection> result = adoptRef(new WebIDBServerConnection(databaseName, openingOrigin, mainFrameOrigin));
57     WebProcess::shared().webToDatabaseProcessConnection()->registerWebIDBServerConnection(*result);
58     return result.release();
59 }
60
61 WebIDBServerConnection::WebIDBServerConnection(const String& databaseName, const SecurityOrigin& openingOrigin, const SecurityOrigin& mainFrameOrigin)
62     : m_serverConnectionIdentifier(generateServerConnectionIdentifier())
63     , m_databaseName(databaseName)
64     , m_openingOrigin(*openingOrigin.isolatedCopy())
65     , m_mainFrameOrigin(*mainFrameOrigin.isolatedCopy())
66 {
67     send(Messages::DatabaseToWebProcessConnection::EstablishIDBConnection(m_serverConnectionIdentifier));
68     send(Messages::DatabaseProcessIDBConnection::EstablishConnection(databaseName, SecurityOriginData::fromSecurityOrigin(&openingOrigin), SecurityOriginData::fromSecurityOrigin(&mainFrameOrigin)));
69 }
70
71 WebIDBServerConnection::~WebIDBServerConnection()
72 {
73     WebProcess::shared().webToDatabaseProcessConnection()->removeWebIDBServerConnection(*this);
74
75     for (const auto& it : m_serverRequests)
76         it.value->requestAborted();
77 }
78
79 bool WebIDBServerConnection::isClosed()
80 {
81     // FIXME: Return real value here.
82     return true;
83 }
84
85 void WebIDBServerConnection::deleteDatabase(const String& name, BoolCallbackFunction successCallback)
86 {
87 }
88
89 void WebIDBServerConnection::getOrEstablishIDBDatabaseMetadata(GetIDBDatabaseMetadataFunction completionCallback)
90 {
91     RefPtr<AsyncRequest> serverRequest = AsyncRequestImpl<const IDBDatabaseMetadata&, bool>::create(completionCallback);
92
93     serverRequest->setAbortHandler([completionCallback]() {
94         IDBDatabaseMetadata metadata;
95         completionCallback(metadata, false);
96     });
97
98     uint64_t requestID = serverRequest->requestID();
99     ASSERT(!m_serverRequests.contains(requestID));
100     m_serverRequests.add(requestID, serverRequest.release());
101
102     LOG(IDB, "WebProcess getOrEstablishIDBDatabaseMetadata request ID %llu", requestID);
103
104     send(Messages::DatabaseProcessIDBConnection::GetOrEstablishIDBDatabaseMetadata(requestID));
105 }
106
107 void WebIDBServerConnection::didGetOrEstablishIDBDatabaseMetadata(uint64_t requestID, bool success, const IDBDatabaseMetadata& metadata)
108 {
109     LOG(IDB, "WebProcess didGetOrEstablishIDBDatabaseMetadata request ID %llu", requestID);
110
111     RefPtr<AsyncRequest> serverRequest = m_serverRequests.take(requestID);
112
113     if (!serverRequest)
114         return;
115
116     serverRequest->completeRequest(metadata, success);
117 }
118
119 void WebIDBServerConnection::close()
120 {
121 }
122
123 void WebIDBServerConnection::openTransaction(int64_t transactionID, const HashSet<int64_t>& objectStoreIDs, IndexedDB::TransactionMode mode, BoolCallbackFunction successCallback)
124 {
125     RefPtr<AsyncRequest> serverRequest = AsyncRequestImpl<bool>::create(successCallback);
126
127     serverRequest->setAbortHandler([successCallback]() {
128         successCallback(false);
129     });
130
131     uint64_t requestID = serverRequest->requestID();
132     ASSERT(!m_serverRequests.contains(requestID));
133     m_serverRequests.add(requestID, serverRequest.release());
134
135     LOG(IDB, "WebProcess openTransaction ID %lli (request ID %llu)", transactionID, requestID);
136
137     Vector<int64_t> objectStoreIDVector;
138     copyToVector(objectStoreIDs, objectStoreIDVector);
139     send(Messages::DatabaseProcessIDBConnection::OpenTransaction(requestID, transactionID, objectStoreIDVector, static_cast<uint64_t>(mode)));
140 }
141
142 void WebIDBServerConnection::didOpenTransaction(uint64_t requestID, bool success)
143 {
144     LOG(IDB, "WebProcess didOpenTransaction request ID %llu", requestID);
145
146     RefPtr<AsyncRequest> serverRequest = m_serverRequests.take(requestID);
147
148     if (!serverRequest)
149         return;
150
151     serverRequest->completeRequest(success);
152 }
153
154 void WebIDBServerConnection::beginTransaction(int64_t transactionID, std::function<void()> completionCallback)
155 {
156     RefPtr<AsyncRequest> serverRequest = AsyncRequestImpl<>::create(completionCallback, completionCallback);
157
158     uint64_t requestID = serverRequest->requestID();
159     ASSERT(!m_serverRequests.contains(requestID));
160     m_serverRequests.add(requestID, serverRequest.release());
161
162     LOG(IDB, "WebProcess beginTransaction ID %lli (request ID %llu)", transactionID, requestID);
163
164     send(Messages::DatabaseProcessIDBConnection::BeginTransaction(requestID, transactionID));
165 }
166
167 void WebIDBServerConnection::didBeginTransaction(uint64_t requestID, bool)
168 {
169     LOG(IDB, "WebProcess didBeginTransaction request ID %llu", requestID);
170
171     RefPtr<AsyncRequest> serverRequest = m_serverRequests.take(requestID);
172
173     if (!serverRequest)
174         return;
175
176     serverRequest->completeRequest();
177 }
178
179 void WebIDBServerConnection::commitTransaction(int64_t transactionID, BoolCallbackFunction successCallback)
180 {
181     RefPtr<AsyncRequest> serverRequest = AsyncRequestImpl<bool>::create(successCallback);
182
183     serverRequest->setAbortHandler([successCallback]() {
184         successCallback(false);
185     });
186
187     uint64_t requestID = serverRequest->requestID();
188     ASSERT(!m_serverRequests.contains(requestID));
189     m_serverRequests.add(requestID, serverRequest.release());
190
191     LOG(IDB, "WebProcess commitTransaction ID %lli (request ID %llu)", transactionID, requestID);
192
193     send(Messages::DatabaseProcessIDBConnection::CommitTransaction(requestID, transactionID));
194 }
195
196 void WebIDBServerConnection::didCommitTransaction(uint64_t requestID, bool success)
197 {
198     LOG(IDB, "WebProcess didCommitTransaction request ID %llu", requestID);
199
200     RefPtr<AsyncRequest> serverRequest = m_serverRequests.take(requestID);
201
202     if (!serverRequest)
203         return;
204
205     serverRequest->completeRequest(success);
206 }
207
208 void WebIDBServerConnection::resetTransaction(int64_t transactionID, std::function<void()> completionCallback)
209 {
210     RefPtr<AsyncRequest> serverRequest = AsyncRequestImpl<>::create(completionCallback, completionCallback);
211
212     uint64_t requestID = serverRequest->requestID();
213     ASSERT(!m_serverRequests.contains(requestID));
214     m_serverRequests.add(requestID, serverRequest.release());
215
216     LOG(IDB, "WebProcess resetTransaction ID %lli (request ID %llu)", transactionID, requestID);
217
218     send(Messages::DatabaseProcessIDBConnection::ResetTransaction(requestID, transactionID));
219 }
220
221 void WebIDBServerConnection::didResetTransaction(uint64_t requestID, bool)
222 {
223     LOG(IDB, "WebProcess didResetTransaction request ID %llu", requestID);
224
225     RefPtr<AsyncRequest> serverRequest = m_serverRequests.take(requestID);
226
227     if (!serverRequest)
228         return;
229
230     serverRequest->completeRequest();
231 }
232
233 void WebIDBServerConnection::rollbackTransaction(int64_t transactionID, std::function<void()> completionCallback)
234 {
235     RefPtr<AsyncRequest> serverRequest = AsyncRequestImpl<>::create(completionCallback, completionCallback);
236
237     uint64_t requestID = serverRequest->requestID();
238     ASSERT(!m_serverRequests.contains(requestID));
239     m_serverRequests.add(requestID, serverRequest.release());
240
241     LOG(IDB, "WebProcess rollbackTransaction ID %lli (request ID %llu)", transactionID, requestID);
242
243     send(Messages::DatabaseProcessIDBConnection::RollbackTransaction(requestID, transactionID));
244 }
245
246 void WebIDBServerConnection::didRollbackTransaction(uint64_t requestID, bool)
247 {
248     LOG(IDB, "WebProcess didRollbackTransaction request ID %llu", requestID);
249
250     RefPtr<AsyncRequest> serverRequest = m_serverRequests.take(requestID);
251
252     if (!serverRequest)
253         return;
254
255     serverRequest->completeRequest();
256 }
257
258 void WebIDBServerConnection::setIndexKeys(int64_t transactionID, int64_t databaseID, int64_t objectStoreID, const IDBObjectStoreMetadata&, IDBKey& primaryKey, const Vector<int64_t>& indexIDs, const Vector<Vector<RefPtr<IDBKey>>>& indexKeys, std::function<void(PassRefPtr<IDBDatabaseError>)> completionCallback)
259 {
260 }
261
262 void WebIDBServerConnection::createObjectStore(IDBTransactionBackend& transaction, const CreateObjectStoreOperation& operation, std::function<void(PassRefPtr<IDBDatabaseError>)> completionCallback)
263 {
264     RefPtr<AsyncRequest> serverRequest = AsyncRequestImpl<PassRefPtr<IDBDatabaseError>>::create(completionCallback);
265
266     String objectStoreName = operation.objectStoreMetadata().name;
267     serverRequest->setAbortHandler([objectStoreName, completionCallback]() {
268         completionCallback(IDBDatabaseError::create(IDBDatabaseException::UnknownError, String::format("Unknown error occured creating object store '%s'", objectStoreName.utf8().data())));
269     });
270
271     uint64_t requestID = serverRequest->requestID();
272     ASSERT(!m_serverRequests.contains(requestID));
273     m_serverRequests.add(requestID, serverRequest.release());
274
275     LOG(IDB, "WebProcess createObjectStore '%s' in transaction ID %llu (request ID %llu)", operation.objectStoreMetadata().name.utf8().data(), transaction.id(), requestID);
276
277     send(Messages::DatabaseProcessIDBConnection::CreateObjectStore(requestID, transaction.id(), operation.objectStoreMetadata()));
278 }
279
280 void WebIDBServerConnection::didCreateObjectStore(uint64_t requestID, bool success)
281 {
282     LOG(IDB, "WebProcess didCreateObjectStore request ID %llu", requestID);
283
284     RefPtr<AsyncRequest> serverRequest = m_serverRequests.take(requestID);
285
286     if (!serverRequest)
287         return;
288
289     serverRequest->completeRequest(success ? nullptr : IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Unknown error occured creating object store"));
290 }
291
292 void WebIDBServerConnection::createIndex(IDBTransactionBackend&, const CreateIndexOperation&, std::function<void(PassRefPtr<IDBDatabaseError>)> completionCallback)
293 {
294 }
295
296 void WebIDBServerConnection::deleteIndex(IDBTransactionBackend&, const DeleteIndexOperation&, std::function<void(PassRefPtr<IDBDatabaseError>)> completionCallback)
297 {
298 }
299
300 void WebIDBServerConnection::get(IDBTransactionBackend&, const GetOperation&, std::function<void(const IDBGetResult&, PassRefPtr<IDBDatabaseError>)> completionCallback)
301 {
302 }
303
304 void WebIDBServerConnection::put(IDBTransactionBackend& transaction, const PutOperation& operation, std::function<void(PassRefPtr<IDBKey>, PassRefPtr<IDBDatabaseError>)> completionCallback)
305 {
306     RefPtr<AsyncRequest> serverRequest = AsyncRequestImpl<PassRefPtr<IDBKey>, PassRefPtr<IDBDatabaseError>>::create(completionCallback);
307
308     serverRequest->setAbortHandler([completionCallback]() {
309         completionCallback(nullptr, IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Unknown error occured putting record"));
310     });
311
312     uint64_t requestID = serverRequest->requestID();
313     ASSERT(!m_serverRequests.contains(requestID));
314     m_serverRequests.add(requestID, serverRequest.release());
315
316     LOG(IDB, "WebProcess put request ID %llu", requestID);
317
318     ASSERT(operation.key());
319     ASSERT(operation.value());
320
321     IPC::DataReference value(reinterpret_cast<const uint8_t*>(operation.value()->data()), operation.value()->size());
322
323     Vector<Vector<IDBKeyData>> indexKeys;
324     for (auto keys : operation.indexKeys()) {
325         indexKeys.append(Vector<IDBKeyData>());
326         for (auto key : keys)
327             indexKeys.last().append(IDBKeyData(key.get()));
328     }
329
330     send(Messages::DatabaseProcessIDBConnection::PutRecord(requestID, transaction.id(), operation.objectStore().id, IDBKeyData(operation.key()), value, operation.putMode(), operation.indexIDs(), indexKeys));
331 }
332
333 void WebIDBServerConnection::didPutRecord(uint64_t requestID, const WebCore::IDBKeyData& resultKey, uint32_t errorCode, const String& errorMessage)
334 {
335     LOG(IDB, "WebProcess didPutRecord request ID %llu (error - %s)", requestID, errorMessage.utf8().data());
336
337     RefPtr<AsyncRequest> serverRequest = m_serverRequests.take(requestID);
338
339     if (!serverRequest)
340         return;
341
342     serverRequest->completeRequest(resultKey.isNull ? nullptr : resultKey.maybeCreateIDBKey(), errorCode ? IDBDatabaseError::create(errorCode, errorMessage) : nullptr);
343 }
344
345 void WebIDBServerConnection::openCursor(IDBTransactionBackend&, const OpenCursorOperation&, std::function<void(PassRefPtr<IDBDatabaseError>)> completionCallback)
346 {
347 }
348
349 void WebIDBServerConnection::count(IDBTransactionBackend&, const CountOperation&, std::function<void(PassRefPtr<IDBDatabaseError>)> completionCallback)
350 {
351 }
352
353 void WebIDBServerConnection::deleteRange(IDBTransactionBackend&, const DeleteRangeOperation&, std::function<void(PassRefPtr<IDBDatabaseError>)> completionCallback)
354 {
355 }
356
357 void WebIDBServerConnection::clearObjectStore(IDBTransactionBackend&, const ClearObjectStoreOperation&, std::function<void(PassRefPtr<IDBDatabaseError>)> completionCallback)
358 {
359 }
360
361 void WebIDBServerConnection::deleteObjectStore(IDBTransactionBackend&, const DeleteObjectStoreOperation& operation, std::function<void(PassRefPtr<IDBDatabaseError>)> completionCallback)
362 {
363     RefPtr<AsyncRequest> serverRequest = AsyncRequestImpl<PassRefPtr<IDBDatabaseError>>::create(completionCallback);
364
365     serverRequest->setAbortHandler([completionCallback]() {
366         completionCallback(IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Unknown error occured deleting object store"));
367     });
368
369     uint64_t requestID = serverRequest->requestID();
370     ASSERT(!m_serverRequests.contains(requestID));
371     m_serverRequests.add(requestID, serverRequest.release());
372
373     LOG(IDB, "WebProcess deleteObjectStore request ID %llu", requestID);
374
375     send(Messages::DatabaseProcessIDBConnection::DeleteObjectStore(requestID, operation.transaction()->id(), operation.objectStoreMetadata().id));
376 }
377
378 void WebIDBServerConnection::didDeleteObjectStore(uint64_t requestID, bool success)
379 {
380     LOG(IDB, "WebProcess didDeleteObjectStore request ID %llu", requestID);
381
382     RefPtr<AsyncRequest> serverRequest = m_serverRequests.take(requestID);
383
384     if (!serverRequest)
385         return;
386
387     serverRequest->completeRequest(success ? nullptr : IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Unknown error occured deleting object store"));
388 }
389
390 void WebIDBServerConnection::changeDatabaseVersion(IDBTransactionBackend&, const IDBDatabaseBackend::VersionChangeOperation& operation, std::function<void(PassRefPtr<IDBDatabaseError>)> completionCallback)
391 {
392     RefPtr<AsyncRequest> serverRequest = AsyncRequestImpl<PassRefPtr<IDBDatabaseError>>::create(completionCallback);
393
394     serverRequest->setAbortHandler([completionCallback]() {
395         completionCallback(IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Unknown error occured changing database version"));
396     });
397
398     uint64_t requestID = serverRequest->requestID();
399     ASSERT(!m_serverRequests.contains(requestID));
400     m_serverRequests.add(requestID, serverRequest.release());
401
402     LOG(IDB, "WebProcess changeDatabaseVersion request ID %llu", requestID);
403
404     send(Messages::DatabaseProcessIDBConnection::ChangeDatabaseVersion(requestID, operation.transaction()->id(), static_cast<uint64_t>(operation.version())));
405 }
406
407 void WebIDBServerConnection::didChangeDatabaseVersion(uint64_t requestID, bool success)
408 {
409     LOG(IDB, "WebProcess didChangeDatabaseVersion request ID %llu", requestID);
410
411     RefPtr<AsyncRequest> serverRequest = m_serverRequests.take(requestID);
412
413     if (!serverRequest)
414         return;
415
416     serverRequest->completeRequest(success ? nullptr : IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Unknown error occured changing database version"));
417 }
418
419 void WebIDBServerConnection::cursorAdvance(IDBCursorBackend&, const CursorAdvanceOperation&, std::function<void()> completionCallback)
420 {
421 }
422
423 void WebIDBServerConnection::cursorIterate(IDBCursorBackend&, const CursorIterationOperation&, std::function<void()> completionCallback)
424 {
425 }
426
427 void WebIDBServerConnection::cursorPrefetchIteration(IDBCursorBackend&, const CursorPrefetchIterationOperation&, std::function<void()> completionCallback)
428 {
429 }
430
431 void WebIDBServerConnection::cursorPrefetchReset(IDBCursorBackend&, int usedPrefetches)
432 {
433 }
434
435 IPC::Connection* WebIDBServerConnection::messageSenderConnection()
436 {
437     return WebProcess::shared().webToDatabaseProcessConnection()->connection();
438 }
439
440 } // namespace WebKit
441
442 #endif // ENABLE(INDEXED_DATABASE) && ENABLE(DATABASE_PROCESS)
443