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