b761eb2651e8f95977f160c312d1dd536f690345
[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 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 "WebCoreArgumentCoders.h"
38 #include "WebProcess.h"
39 #include "WebToDatabaseProcessConnection.h"
40 #include <WebCore/IDBDatabaseMetadata.h>
41 #include <WebCore/IDBKeyRangeData.h>
42 #include <WebCore/SecurityOrigin.h>
43 #include <WebCore/SecurityOriginData.h>
44
45 using namespace WebCore;
46
47 namespace WebKit {
48
49 static uint64_t generateServerConnectionIdentifier()
50 {
51     ASSERT(RunLoop::isMain());
52     static uint64_t identifier = 0;
53     return ++identifier;
54 }
55
56 PassRefPtr<WebIDBServerConnection> WebIDBServerConnection::create(const String& databaseName, const SecurityOrigin& openingOrigin, const SecurityOrigin& mainFrameOrigin)
57 {
58     RefPtr<WebIDBServerConnection> result = adoptRef(new WebIDBServerConnection(databaseName, openingOrigin, mainFrameOrigin));
59     WebProcess::singleton().webToDatabaseProcessConnection()->registerWebIDBServerConnection(*result);
60     return result.release();
61 }
62
63 WebIDBServerConnection::WebIDBServerConnection(const String& databaseName, const SecurityOrigin& openingOrigin, const SecurityOrigin& mainFrameOrigin)
64     : m_serverConnectionIdentifier(generateServerConnectionIdentifier())
65     , m_databaseName(databaseName)
66     , m_openingOrigin(openingOrigin.isolatedCopy())
67     , m_mainFrameOrigin(mainFrameOrigin.isolatedCopy())
68 {
69     send(Messages::DatabaseToWebProcessConnection::EstablishIDBConnection(m_serverConnectionIdentifier));
70     send(Messages::DatabaseProcessIDBConnection::EstablishConnection(databaseName, SecurityOriginData::fromSecurityOrigin(openingOrigin), SecurityOriginData::fromSecurityOrigin(mainFrameOrigin)));
71 }
72
73 WebIDBServerConnection::~WebIDBServerConnection()
74 {
75     WebProcess::singleton().webToDatabaseProcessConnection()->removeWebIDBServerConnection(*this);
76
77     for (const auto& it : m_serverRequests)
78         it.value->requestAborted();
79 }
80
81 bool WebIDBServerConnection::isClosed()
82 {
83     // FIXME: Return real value here.
84     return true;
85 }
86
87 void WebIDBServerConnection::deleteDatabase(const String& name, BoolCallbackFunction successCallback)
88 {
89     RefPtr<AsyncRequest> serverRequest = AsyncRequestImpl<bool>::create(successCallback);
90
91     serverRequest->setAbortHandler([successCallback] {
92         successCallback(false);
93     });
94
95     uint64_t requestID = serverRequest->requestID();
96     ASSERT(!m_serverRequests.contains(requestID));
97     m_serverRequests.add(requestID, serverRequest.release());
98
99     LOG(IDB, "WebProcess deleteDatabase request ID %" PRIu64, requestID);
100
101     send(Messages::DatabaseProcessIDBConnection::DeleteDatabase(requestID, name));
102 }
103
104 void WebIDBServerConnection::didDeleteDatabase(uint64_t requestID, bool success)
105 {
106     LOG(IDB, "WebProcess didDeleteDatabase request ID %" PRIu64, requestID);
107
108     RefPtr<AsyncRequest> serverRequest = m_serverRequests.take(requestID);
109
110     if (!serverRequest)
111         return;
112
113     serverRequest->completeRequest(success);
114 }
115
116 void WebIDBServerConnection::getOrEstablishIDBDatabaseMetadata(GetIDBDatabaseMetadataFunction completionCallback)
117 {
118     RefPtr<AsyncRequest> serverRequest = AsyncRequestImpl<IDBDatabaseMetadata, bool>::create(completionCallback);
119
120     serverRequest->setAbortHandler([completionCallback] {
121         IDBDatabaseMetadata metadata;
122         completionCallback(metadata, false);
123     });
124
125     uint64_t requestID = serverRequest->requestID();
126     ASSERT(!m_serverRequests.contains(requestID));
127     m_serverRequests.add(requestID, serverRequest.release());
128
129     LOG(IDB, "WebProcess getOrEstablishIDBDatabaseMetadata request ID %" PRIu64, requestID);
130
131     send(Messages::DatabaseProcessIDBConnection::GetOrEstablishIDBDatabaseMetadata(requestID));
132 }
133
134 void WebIDBServerConnection::didGetOrEstablishIDBDatabaseMetadata(uint64_t requestID, bool success, const IDBDatabaseMetadata& metadata)
135 {
136     LOG(IDB, "WebProcess didGetOrEstablishIDBDatabaseMetadata request ID %" PRIu64, requestID);
137
138     RefPtr<AsyncRequest> serverRequest = m_serverRequests.take(requestID);
139
140     if (!serverRequest)
141         return;
142
143     serverRequest->completeRequest(metadata, success);
144 }
145
146 void WebIDBServerConnection::close()
147 {
148     LOG(IDB, "WebProcess close");
149
150     RefPtr<WebIDBServerConnection> protector(this);
151
152     for (auto& request : m_serverRequests)
153         request.value->requestAborted();
154
155     m_serverRequests.clear();
156
157     send(Messages::DatabaseProcessIDBConnection::Close());
158 }
159
160 void WebIDBServerConnection::openTransaction(int64_t transactionID, const HashSet<int64_t>& objectStoreIDs, IndexedDB::TransactionMode mode, BoolCallbackFunction successCallback)
161 {
162     RefPtr<AsyncRequest> serverRequest = AsyncRequestImpl<bool>::create(successCallback);
163
164     serverRequest->setAbortHandler([successCallback] {
165         successCallback(false);
166     });
167
168     uint64_t requestID = serverRequest->requestID();
169     ASSERT(!m_serverRequests.contains(requestID));
170     m_serverRequests.add(requestID, serverRequest.release());
171
172     LOG(IDB, "WebProcess openTransaction ID %" PRIi64 " (request ID %" PRIu64 ")", transactionID, requestID);
173
174     Vector<int64_t> objectStoreIDVector;
175     copyToVector(objectStoreIDs, objectStoreIDVector);
176     send(Messages::DatabaseProcessIDBConnection::OpenTransaction(requestID, transactionID, objectStoreIDVector, static_cast<uint64_t>(mode)));
177 }
178
179 void WebIDBServerConnection::didOpenTransaction(uint64_t requestID, bool success)
180 {
181     LOG(IDB, "WebProcess didOpenTransaction request ID %" PRIu64, requestID);
182
183     RefPtr<AsyncRequest> serverRequest = m_serverRequests.take(requestID);
184
185     if (!serverRequest)
186         return;
187
188     serverRequest->completeRequest(success);
189 }
190
191 void WebIDBServerConnection::beginTransaction(int64_t transactionID, std::function<void ()> completionCallback)
192 {
193     RefPtr<AsyncRequest> serverRequest = AsyncRequestImpl<>::create(completionCallback, completionCallback);
194
195     uint64_t requestID = serverRequest->requestID();
196     ASSERT(!m_serverRequests.contains(requestID));
197     m_serverRequests.add(requestID, serverRequest.release());
198
199     LOG(IDB, "WebProcess beginTransaction ID %" PRIi64 " (request ID %" PRIu64 ")", transactionID, requestID);
200
201     send(Messages::DatabaseProcessIDBConnection::BeginTransaction(requestID, transactionID));
202 }
203
204 void WebIDBServerConnection::didBeginTransaction(uint64_t requestID, bool)
205 {
206     LOG(IDB, "WebProcess didBeginTransaction request ID %" PRIu64, requestID);
207
208     RefPtr<AsyncRequest> serverRequest = m_serverRequests.take(requestID);
209
210     if (!serverRequest)
211         return;
212
213     serverRequest->completeRequest();
214 }
215
216 void WebIDBServerConnection::commitTransaction(int64_t transactionID, BoolCallbackFunction successCallback)
217 {
218     RefPtr<AsyncRequest> serverRequest = AsyncRequestImpl<bool>::create(successCallback);
219
220     serverRequest->setAbortHandler([successCallback] {
221         successCallback(false);
222     });
223
224     uint64_t requestID = serverRequest->requestID();
225     ASSERT(!m_serverRequests.contains(requestID));
226     m_serverRequests.add(requestID, serverRequest.release());
227
228     LOG(IDB, "WebProcess commitTransaction ID %" PRIi64 " (request ID %" PRIu64 ")", transactionID, requestID);
229
230     send(Messages::DatabaseProcessIDBConnection::CommitTransaction(requestID, transactionID));
231 }
232
233 void WebIDBServerConnection::didCommitTransaction(uint64_t requestID, bool success)
234 {
235     LOG(IDB, "WebProcess didCommitTransaction request ID %" PRIu64, requestID);
236
237     RefPtr<AsyncRequest> serverRequest = m_serverRequests.take(requestID);
238
239     if (!serverRequest)
240         return;
241
242     serverRequest->completeRequest(success);
243 }
244
245 void WebIDBServerConnection::resetTransaction(int64_t transactionID, std::function<void ()> completionCallback)
246 {
247     RefPtr<AsyncRequest> serverRequest = AsyncRequestImpl<>::create(completionCallback, completionCallback);
248
249     uint64_t requestID = serverRequest->requestID();
250     ASSERT(!m_serverRequests.contains(requestID));
251     m_serverRequests.add(requestID, serverRequest.release());
252
253     LOG(IDB, "WebProcess resetTransaction ID %" PRIi64 " (request ID %" PRIu64 ")", transactionID, requestID);
254
255     send(Messages::DatabaseProcessIDBConnection::ResetTransaction(requestID, transactionID));
256 }
257
258 void WebIDBServerConnection::didResetTransaction(uint64_t requestID, bool)
259 {
260     LOG(IDB, "WebProcess didResetTransaction request ID %" PRIu64, requestID);
261
262     RefPtr<AsyncRequest> serverRequest = m_serverRequests.take(requestID);
263
264     if (!serverRequest)
265         return;
266
267     serverRequest->completeRequest();
268 }
269
270 bool WebIDBServerConnection::resetTransactionSync(int64_t transactionID)
271 {
272     bool success;
273     sendSync(Messages::DatabaseProcessIDBConnection::ResetTransactionSync(transactionID), Messages::DatabaseProcessIDBConnection::ResetTransactionSync::Reply(success));
274     return success;
275 }
276
277 void WebIDBServerConnection::rollbackTransaction(int64_t transactionID, std::function<void ()> completionCallback)
278 {
279     RefPtr<AsyncRequest> serverRequest = AsyncRequestImpl<>::create(completionCallback, completionCallback);
280
281     uint64_t requestID = serverRequest->requestID();
282     ASSERT(!m_serverRequests.contains(requestID));
283     m_serverRequests.add(requestID, serverRequest.release());
284
285     LOG(IDB, "WebProcess rollbackTransaction ID %" PRIi64 " (request ID %" PRIu64 ")", transactionID, requestID);
286
287     send(Messages::DatabaseProcessIDBConnection::RollbackTransaction(requestID, transactionID));
288 }
289
290 void WebIDBServerConnection::didRollbackTransaction(uint64_t requestID, bool)
291 {
292     LOG(IDB, "WebProcess didRollbackTransaction request ID %" PRIu64, requestID);
293
294     RefPtr<AsyncRequest> serverRequest = m_serverRequests.take(requestID);
295
296     if (!serverRequest)
297         return;
298
299     serverRequest->completeRequest();
300 }
301
302 bool WebIDBServerConnection::rollbackTransactionSync(int64_t transactionID)
303 {
304     bool success;
305     sendSync(Messages::DatabaseProcessIDBConnection::RollbackTransactionSync(transactionID), Messages::DatabaseProcessIDBConnection::RollbackTransactionSync::Reply(success));
306     return success;
307 }
308
309 void WebIDBServerConnection::setIndexKeys(int64_t transactionID, int64_t databaseID, int64_t objectStoreID, const IDBObjectStoreMetadata&, IDBKey& primaryKey, const Vector<int64_t, 1>& indexIDs, const Vector<Vector<RefPtr<WebCore::IDBKey>>, 1>& indexKeys, std::function<void (PassRefPtr<IDBDatabaseError>)> completionCallback)
310 {
311 }
312
313 void WebIDBServerConnection::createObjectStore(IDBTransactionBackend& transaction, const CreateObjectStoreOperation& operation, std::function<void (PassRefPtr<IDBDatabaseError>)> completionCallback)
314 {
315     RefPtr<AsyncRequest> serverRequest = AsyncRequestImpl<PassRefPtr<IDBDatabaseError>>::create(completionCallback);
316
317     String objectStoreName = operation.objectStoreMetadata().name;
318     serverRequest->setAbortHandler([objectStoreName, completionCallback] {
319         completionCallback(IDBDatabaseError::create(IDBDatabaseException::UnknownError, String::format("Unknown error occured creating object store '%s'", objectStoreName.utf8().data())));
320     });
321
322     uint64_t requestID = serverRequest->requestID();
323     ASSERT(!m_serverRequests.contains(requestID));
324     m_serverRequests.add(requestID, serverRequest.release());
325
326     LOG(IDB, "WebProcess createObjectStore '%s' in transaction ID %" PRIi64 " (request ID %" PRIu64 ")", operation.objectStoreMetadata().name.utf8().data(), transaction.id(), requestID);
327
328     send(Messages::DatabaseProcessIDBConnection::CreateObjectStore(requestID, transaction.id(), operation.objectStoreMetadata()));
329 }
330
331 void WebIDBServerConnection::didCreateObjectStore(uint64_t requestID, bool success)
332 {
333     LOG(IDB, "WebProcess didCreateObjectStore request ID %" PRIu64, requestID);
334
335     RefPtr<AsyncRequest> serverRequest = m_serverRequests.take(requestID);
336
337     if (!serverRequest)
338         return;
339
340     serverRequest->completeRequest(success ? nullptr : IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Unknown error occured creating object store"));
341 }
342
343 void WebIDBServerConnection::createIndex(IDBTransactionBackend&transaction, const CreateIndexOperation& operation, std::function<void (PassRefPtr<IDBDatabaseError>)> completionCallback)
344 {
345     RefPtr<AsyncRequest> serverRequest = AsyncRequestImpl<PassRefPtr<IDBDatabaseError>>::create(completionCallback);
346
347     serverRequest->setAbortHandler([completionCallback] {
348         completionCallback(IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Unknown error occured creating index"));
349     });
350
351     uint64_t requestID = serverRequest->requestID();
352     ASSERT(!m_serverRequests.contains(requestID));
353     m_serverRequests.add(requestID, serverRequest.release());
354
355     LOG(IDB, "WebProcess create index request ID %" PRIu64, requestID);
356
357     send(Messages::DatabaseProcessIDBConnection::CreateIndex(requestID, transaction.id(), operation.objectStoreID(), operation.idbIndexMetadata()));
358 }
359
360 void WebIDBServerConnection::didCreateIndex(uint64_t requestID, bool success)
361 {
362     LOG(IDB, "WebProcess didCreateIndex request ID %" PRIu64, requestID);
363
364     RefPtr<AsyncRequest> serverRequest = m_serverRequests.take(requestID);
365
366     if (!serverRequest)
367         return;
368
369     serverRequest->completeRequest(success ? nullptr : IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Unknown error occured creating index"));
370 }
371
372 void WebIDBServerConnection::deleteIndex(IDBTransactionBackend&transaction, const DeleteIndexOperation& operation, std::function<void (PassRefPtr<IDBDatabaseError>)> completionCallback)
373 {
374     RefPtr<AsyncRequest> serverRequest = AsyncRequestImpl<PassRefPtr<IDBDatabaseError>>::create(completionCallback);
375
376     serverRequest->setAbortHandler([completionCallback] {
377         completionCallback(IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Unknown error occured deleting index"));
378     });
379
380     uint64_t requestID = serverRequest->requestID();
381     ASSERT(!m_serverRequests.contains(requestID));
382     m_serverRequests.add(requestID, serverRequest.release());
383
384     LOG(IDB, "WebProcess delete index request ID %" PRIu64, requestID);
385
386     send(Messages::DatabaseProcessIDBConnection::DeleteIndex(requestID, transaction.id(), operation.objectStoreID(), operation.idbIndexMetadata().id));
387 }
388
389 void WebIDBServerConnection::didDeleteIndex(uint64_t requestID, bool success)
390 {
391     LOG(IDB, "WebProcess didDeleteIndex request ID %" PRIu64, requestID);
392
393     RefPtr<AsyncRequest> serverRequest = m_serverRequests.take(requestID);
394
395     if (!serverRequest)
396         return;
397
398     serverRequest->completeRequest(success ? nullptr : IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Unknown error occured deleting index"));
399 }
400
401 void WebIDBServerConnection::get(IDBTransactionBackend& transaction, const GetOperation& operation, std::function<void (const IDBGetResult&, PassRefPtr<IDBDatabaseError>)> completionCallback)
402 {
403     RefPtr<AsyncRequest> serverRequest = AsyncRequestImpl<IDBGetResult, PassRefPtr<IDBDatabaseError>>::create(completionCallback);
404
405     serverRequest->setAbortHandler([completionCallback] {
406         completionCallback(IDBGetResult(), IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Unknown error occured getting record"));
407     });
408
409     uint64_t requestID = serverRequest->requestID();
410     ASSERT(!m_serverRequests.contains(requestID));
411     m_serverRequests.add(requestID, serverRequest.release());
412
413     LOG(IDB, "WebProcess get request ID %" PRIu64, requestID);
414
415     ASSERT(operation.keyRange());
416
417     send(Messages::DatabaseProcessIDBConnection::GetRecord(requestID, transaction.id(), operation.objectStoreID(), operation.indexID(), operation.keyRange(), static_cast<int64_t>(operation.cursorType())));
418 }
419
420 void WebIDBServerConnection::put(IDBTransactionBackend& transaction, const PutOperation& operation, std::function<void (PassRefPtr<IDBKey>, PassRefPtr<IDBDatabaseError>)> completionCallback)
421 {
422     RefPtr<AsyncRequest> serverRequest = AsyncRequestImpl<PassRefPtr<IDBKey>, PassRefPtr<IDBDatabaseError>>::create(completionCallback);
423
424     serverRequest->setAbortHandler([completionCallback] {
425         completionCallback(nullptr, IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Unknown error occured putting record"));
426     });
427
428     uint64_t requestID = serverRequest->requestID();
429     ASSERT(!m_serverRequests.contains(requestID));
430     m_serverRequests.add(requestID, serverRequest.release());
431
432     LOG(IDB, "WebProcess put request ID %" PRIu64, requestID);
433
434     ASSERT(operation.value());
435
436     IPC::DataReference value(reinterpret_cast<const uint8_t*>(operation.value()->data()), operation.value()->size());
437
438     Vector<Vector<IDBKeyData>> indexKeys;
439     for (const auto& keys : operation.indexKeys()) {
440         indexKeys.append(Vector<IDBKeyData>());
441         for (const auto& key : keys)
442             indexKeys.last().append(IDBKeyData(key.get()));
443     }
444
445     send(Messages::DatabaseProcessIDBConnection::PutRecord(requestID, transaction.id(), operation.objectStore().id, IDBKeyData(operation.key()), value, operation.putMode(), operation.indexIDs(), indexKeys));
446 }
447
448 void WebIDBServerConnection::didPutRecord(uint64_t requestID, const WebCore::IDBKeyData& resultKey, uint32_t errorCode, const String& errorMessage)
449 {
450     LOG(IDB, "WebProcess didPutRecord request ID %" PRIu64 " (error - %s)", requestID, errorMessage.utf8().data());
451
452     RefPtr<AsyncRequest> serverRequest = m_serverRequests.take(requestID);
453
454     if (!serverRequest)
455         return;
456
457     serverRequest->completeRequest(resultKey.isNull ? nullptr : resultKey.maybeCreateIDBKey(), errorCode ? IDBDatabaseError::create(errorCode, errorMessage) : nullptr);
458 }
459
460 void WebIDBServerConnection::didGetRecord(uint64_t requestID, const WebCore::IDBGetResult& getResult, uint32_t errorCode, const String& errorMessage)
461 {
462     LOG(IDB, "WebProcess didGetRecord request ID %" PRIu64 " (error - %s)", requestID, errorMessage.utf8().data());
463
464     RefPtr<AsyncRequest> serverRequest = m_serverRequests.take(requestID);
465
466     if (!serverRequest)
467         return;
468
469     serverRequest->completeRequest(getResult, errorCode ? IDBDatabaseError::create(errorCode, errorMessage) : nullptr);
470 }
471
472 void WebIDBServerConnection::didOpenCursor(uint64_t requestID, int64_t cursorID, const IDBKeyData& key, const IDBKeyData& primaryKey, const IPC::DataReference& valueData, uint32_t errorCode, const String& errorMessage)
473 {
474     LOG(IDB, "WebProcess didOpenCursor request ID %" PRIu64 " (error - %s)", requestID, errorMessage.utf8().data());
475
476     RefPtr<AsyncRequest> serverRequest = m_serverRequests.take(requestID);
477
478     if (!serverRequest)
479         return;
480
481     RefPtr<SharedBuffer> value = SharedBuffer::create(valueData.data(), valueData.size());
482     serverRequest->completeRequest(cursorID, key.maybeCreateIDBKey(), primaryKey.maybeCreateIDBKey(), value.release(), errorCode ? IDBDatabaseError::create(errorCode, errorMessage) : nullptr);
483 }
484
485 void WebIDBServerConnection::didAdvanceCursor(uint64_t requestID, const IDBKeyData& key, const IDBKeyData& primaryKey, const IPC::DataReference& valueData, uint32_t errorCode, const String& errorMessage)
486 {
487     LOG(IDB, "WebProcess didAdvanceCursor request ID %" PRIu64 " (error - %s)", requestID, errorMessage.utf8().data());
488
489     RefPtr<AsyncRequest> serverRequest = m_serverRequests.take(requestID);
490
491     if (!serverRequest)
492         return;
493
494     RefPtr<SharedBuffer> value = SharedBuffer::create(valueData.data(), valueData.size());
495     serverRequest->completeRequest(key.maybeCreateIDBKey(), primaryKey.maybeCreateIDBKey(), value.release(), errorCode ? IDBDatabaseError::create(errorCode, errorMessage) : nullptr);
496 }
497
498 void WebIDBServerConnection::didIterateCursor(uint64_t requestID, const IDBKeyData& key, const IDBKeyData& primaryKey, const IPC::DataReference& valueData, uint32_t errorCode, const String& errorMessage)
499 {
500     LOG(IDB, "WebProcess didIterateCursor request ID %" PRIu64 " (error - %s)", requestID, errorMessage.utf8().data());
501
502     RefPtr<AsyncRequest> serverRequest = m_serverRequests.take(requestID);
503
504     if (!serverRequest)
505         return;
506
507     RefPtr<SharedBuffer> value = SharedBuffer::create(valueData.data(), valueData.size());
508     serverRequest->completeRequest(key.maybeCreateIDBKey(), primaryKey.maybeCreateIDBKey(), value.release(), errorCode ? IDBDatabaseError::create(errorCode, errorMessage) : nullptr);
509 }
510
511 void WebIDBServerConnection::count(IDBTransactionBackend& transaction, const CountOperation& operation, std::function<void (int64_t, PassRefPtr<IDBDatabaseError>)> completionCallback)
512 {
513     RefPtr<AsyncRequest> serverRequest = AsyncRequestImpl<int64_t, PassRefPtr<IDBDatabaseError>>::create(completionCallback);
514
515     serverRequest->setAbortHandler([completionCallback] {
516         completionCallback(0, IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Unknown error occured getting count"));
517     });
518
519     uint64_t requestID = serverRequest->requestID();
520     ASSERT(!m_serverRequests.contains(requestID));
521     m_serverRequests.add(requestID, serverRequest.release());
522
523     LOG(IDB, "WebProcess count request ID %" PRIu64, requestID);
524
525     send(Messages::DatabaseProcessIDBConnection::Count(requestID, transaction.id(), operation.objectStoreID(), operation.indexID(), IDBKeyRangeData(operation.keyRange())));
526 }
527
528 void WebIDBServerConnection::didCount(uint64_t requestID, int64_t count, uint32_t errorCode, const String& errorMessage)
529 {
530     LOG(IDB, "WebProcess didCount %" PRIi64 " request ID %" PRIu64 " (error - %s)", count, requestID, errorMessage.utf8().data());
531
532     RefPtr<AsyncRequest> serverRequest = m_serverRequests.take(requestID);
533
534     if (!serverRequest)
535         return;
536
537     serverRequest->completeRequest(count, errorCode ? IDBDatabaseError::create(errorCode, errorMessage) : nullptr);
538 }
539
540 void WebIDBServerConnection::deleteRange(IDBTransactionBackend& transaction, const DeleteRangeOperation& operation, std::function<void (PassRefPtr<IDBDatabaseError>)> completionCallback)
541 {
542     RefPtr<AsyncRequest> serverRequest = AsyncRequestImpl<PassRefPtr<IDBDatabaseError>>::create(completionCallback);
543
544     serverRequest->setAbortHandler([completionCallback] {
545         completionCallback(IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Unknown error occured getting count"));
546     });
547
548     uint64_t requestID = serverRequest->requestID();
549     ASSERT(!m_serverRequests.contains(requestID));
550     m_serverRequests.add(requestID, serverRequest.release());
551
552     LOG(IDB, "WebProcess deleteRange request ID %" PRIu64, requestID);
553
554     send(Messages::DatabaseProcessIDBConnection::DeleteRange(requestID, transaction.id(), operation.objectStoreID(), IDBKeyRangeData(operation.keyRange())));
555 }
556
557 void WebIDBServerConnection::didDeleteRange(uint64_t requestID, uint32_t errorCode, const String& errorMessage)
558 {
559     LOG(IDB, "WebProcess didDeleteRange request ID %" PRIu64, requestID);
560
561     RefPtr<AsyncRequest> serverRequest = m_serverRequests.take(requestID);
562
563     if (!serverRequest)
564         return;
565
566     serverRequest->completeRequest(errorCode ? IDBDatabaseError::create(errorCode, errorMessage) : nullptr);
567 }
568
569 void WebIDBServerConnection::clearObjectStore(IDBTransactionBackend&, const ClearObjectStoreOperation& operation, std::function<void (PassRefPtr<IDBDatabaseError>)> completionCallback)
570 {
571     RefPtr<AsyncRequest> serverRequest = AsyncRequestImpl<PassRefPtr<IDBDatabaseError>>::create(completionCallback);
572
573     serverRequest->setAbortHandler([completionCallback] {
574         completionCallback(IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Unknown error occured clearing object store"));
575     });
576
577     uint64_t requestID = serverRequest->requestID();
578     ASSERT(!m_serverRequests.contains(requestID));
579     m_serverRequests.add(requestID, serverRequest.release());
580
581     LOG(IDB, "WebProcess clearObjectStore request ID %" PRIu64, requestID);
582
583     send(Messages::DatabaseProcessIDBConnection::ClearObjectStore(requestID, operation.transaction()->id(), operation.objectStoreID()));
584 }
585
586 void WebIDBServerConnection::didClearObjectStore(uint64_t requestID, bool success)
587 {
588     LOG(IDB, "WebProcess didClearObjectStore request ID %" PRIu64, requestID);
589
590     RefPtr<AsyncRequest> serverRequest = m_serverRequests.take(requestID);
591
592     if (!serverRequest)
593         return;
594
595     serverRequest->completeRequest(success ? nullptr : IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Unknown error occured clearing object store"));
596 }
597
598 void WebIDBServerConnection::deleteObjectStore(IDBTransactionBackend&, const DeleteObjectStoreOperation& operation, std::function<void (PassRefPtr<IDBDatabaseError>)> completionCallback)
599 {
600     RefPtr<AsyncRequest> serverRequest = AsyncRequestImpl<PassRefPtr<IDBDatabaseError>>::create(completionCallback);
601
602     serverRequest->setAbortHandler([completionCallback] {
603         completionCallback(IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Unknown error occured deleting object store"));
604     });
605
606     uint64_t requestID = serverRequest->requestID();
607     ASSERT(!m_serverRequests.contains(requestID));
608     m_serverRequests.add(requestID, serverRequest.release());
609
610     LOG(IDB, "WebProcess deleteObjectStore request ID %" PRIu64, requestID);
611
612     send(Messages::DatabaseProcessIDBConnection::DeleteObjectStore(requestID, operation.transaction()->id(), operation.objectStoreMetadata().id));
613 }
614
615 void WebIDBServerConnection::didDeleteObjectStore(uint64_t requestID, bool success)
616 {
617     LOG(IDB, "WebProcess didDeleteObjectStore request ID %" PRIu64, requestID);
618
619     RefPtr<AsyncRequest> serverRequest = m_serverRequests.take(requestID);
620
621     if (!serverRequest)
622         return;
623
624     serverRequest->completeRequest(success ? nullptr : IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Unknown error occured deleting object store"));
625 }
626
627 void WebIDBServerConnection::changeDatabaseVersion(IDBTransactionBackend&, const IDBDatabaseBackend::VersionChangeOperation& operation, std::function<void (PassRefPtr<IDBDatabaseError>)> completionCallback)
628 {
629     RefPtr<AsyncRequest> serverRequest = AsyncRequestImpl<PassRefPtr<IDBDatabaseError>>::create(completionCallback);
630
631     serverRequest->setAbortHandler([completionCallback] {
632         completionCallback(IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Unknown error occured changing database version"));
633     });
634
635     uint64_t requestID = serverRequest->requestID();
636     ASSERT(!m_serverRequests.contains(requestID));
637     m_serverRequests.add(requestID, serverRequest.release());
638
639     LOG(IDB, "WebProcess changeDatabaseVersion request ID %" PRIu64, requestID);
640
641     send(Messages::DatabaseProcessIDBConnection::ChangeDatabaseVersion(requestID, operation.transaction()->id(), static_cast<uint64_t>(operation.version())));
642 }
643
644 void WebIDBServerConnection::didChangeDatabaseVersion(uint64_t requestID, bool success)
645 {
646     LOG(IDB, "WebProcess didChangeDatabaseVersion request ID %" PRIu64, requestID);
647
648     RefPtr<AsyncRequest> serverRequest = m_serverRequests.take(requestID);
649
650     if (!serverRequest)
651         return;
652
653     serverRequest->completeRequest(success ? nullptr : IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Unknown error occured changing database version"));
654 }
655
656 void WebIDBServerConnection::openCursor(IDBTransactionBackend&, const OpenCursorOperation& operation, std::function<void (int64_t, PassRefPtr<IDBKey>, PassRefPtr<IDBKey>, PassRefPtr<SharedBuffer>, PassRefPtr<IDBDatabaseError>)> completionCallback)
657 {
658     RefPtr<AsyncRequest> serverRequest = AsyncRequestImpl<int64_t, PassRefPtr<IDBKey>, PassRefPtr<IDBKey>, PassRefPtr<SharedBuffer>, PassRefPtr<IDBDatabaseError>>::create(completionCallback);
659
660     serverRequest->setAbortHandler([completionCallback] {
661         completionCallback(0, nullptr, nullptr, nullptr, IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Unknown error occured opening database cursor"));
662     });
663
664     uint64_t requestID = serverRequest->requestID();
665     ASSERT(!m_serverRequests.contains(requestID));
666     m_serverRequests.add(requestID, serverRequest.release());
667
668     LOG(IDB, "WebProcess openCursor request ID %" PRIu64, requestID);
669
670     send(Messages::DatabaseProcessIDBConnection::OpenCursor(requestID, operation.transactionID(), operation.objectStoreID(), operation.indexID(), static_cast<int64_t>(operation.direction()), static_cast<int64_t>(operation.cursorType()), static_cast<int64_t>(operation.taskType()), operation.keyRange()));
671 }
672
673 void WebIDBServerConnection::cursorAdvance(IDBCursorBackend&, const CursorAdvanceOperation& operation, std::function<void (PassRefPtr<IDBKey>, PassRefPtr<IDBKey>, PassRefPtr<SharedBuffer>, PassRefPtr<IDBDatabaseError>)> completionCallback)
674 {
675     RefPtr<AsyncRequest> serverRequest = AsyncRequestImpl<PassRefPtr<IDBKey>, PassRefPtr<IDBKey>, PassRefPtr<SharedBuffer>, PassRefPtr<IDBDatabaseError>>::create(completionCallback);
676
677     serverRequest->setAbortHandler([completionCallback] {
678         completionCallback(nullptr, nullptr, nullptr, IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Unknown error occured advancing database cursor"));
679     });
680
681     uint64_t requestID = serverRequest->requestID();
682     ASSERT(!m_serverRequests.contains(requestID));
683     m_serverRequests.add(requestID, serverRequest.release());
684
685     LOG(IDB, "WebProcess cursorAdvance request ID %" PRIu64, requestID);
686
687     send(Messages::DatabaseProcessIDBConnection::CursorAdvance(requestID, operation.cursorID(), operation.count()));
688 }
689
690 void WebIDBServerConnection::cursorIterate(IDBCursorBackend&, const CursorIterationOperation& operation, std::function<void (PassRefPtr<IDBKey>, PassRefPtr<IDBKey>, PassRefPtr<SharedBuffer>, PassRefPtr<IDBDatabaseError>)> completionCallback)
691 {
692     RefPtr<AsyncRequest> serverRequest = AsyncRequestImpl<PassRefPtr<IDBKey>, PassRefPtr<IDBKey>, PassRefPtr<SharedBuffer>, PassRefPtr<IDBDatabaseError>>::create(completionCallback);
693
694     serverRequest->setAbortHandler([completionCallback] {
695         completionCallback(nullptr, nullptr, nullptr, IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Unknown error occured iterating database cursor"));
696     });
697
698     uint64_t requestID = serverRequest->requestID();
699     ASSERT(!m_serverRequests.contains(requestID));
700     m_serverRequests.add(requestID, serverRequest.release());
701
702     LOG(IDB, "WebProcess cursorIterate request ID %" PRIu64, requestID);
703
704     send(Messages::DatabaseProcessIDBConnection::CursorIterate(requestID, operation.cursorID(), operation.key()));
705 }
706
707 IPC::Connection* WebIDBServerConnection::messageSenderConnection()
708 {
709     return WebProcess::singleton().webToDatabaseProcessConnection()->connection();
710 }
711
712 } // namespace WebKit
713
714 #endif // ENABLE(INDEXED_DATABASE) && ENABLE(DATABASE_PROCESS)
715