12708e690c0757b63080aba4310011c4f6a4c29a
[WebKit-https.git] / Source / WebCore / Modules / indexeddb / server / UniqueIDBDatabase.cpp
1 /*
2  * Copyright (C) 2015, 2016 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 "UniqueIDBDatabase.h"
28
29 #if ENABLE(INDEXED_DATABASE)
30
31 #include "IDBCursorInfo.h"
32 #include "IDBGetAllRecordsData.h"
33 #include "IDBGetAllResult.h"
34 #include "IDBGetRecordData.h"
35 #include "IDBIterateCursorData.h"
36 #include "IDBKeyRangeData.h"
37 #include "IDBResultData.h"
38 #include "IDBServer.h"
39 #include "IDBTransactionInfo.h"
40 #include "IDBValue.h"
41 #include "Logging.h"
42 #include "ScopeGuard.h"
43 #include "SerializedScriptValue.h"
44 #include "UniqueIDBDatabaseConnection.h"
45 #include <heap/HeapInlines.h>
46 #include <runtime/AuxiliaryBarrierInlines.h>
47 #include <runtime/StructureInlines.h>
48 #include <wtf/MainThread.h>
49 #include <wtf/NeverDestroyed.h>
50 #include <wtf/ThreadSafeRefCounted.h>
51
52 using namespace JSC;
53
54 namespace WebCore {
55 namespace IDBServer {
56
57 UniqueIDBDatabase::UniqueIDBDatabase(IDBServer& server, const IDBDatabaseIdentifier& identifier)
58     : m_server(server)
59     , m_identifier(identifier)
60     , m_operationAndTransactionTimer(*this, &UniqueIDBDatabase::operationAndTransactionTimerFired)
61 {
62     LOG(IndexedDB, "UniqueIDBDatabase::UniqueIDBDatabase() (%p) %s", this, m_identifier.debugString().utf8().data());
63 }
64
65 UniqueIDBDatabase::~UniqueIDBDatabase()
66 {
67     LOG(IndexedDB, "UniqueIDBDatabase::~UniqueIDBDatabase() (%p) %s", this, m_identifier.debugString().utf8().data());
68     ASSERT(isMainThread());
69     ASSERT(!hasAnyPendingCallbacks());
70     ASSERT(!hasUnfinishedTransactions());
71     ASSERT(m_pendingTransactions.isEmpty());
72     ASSERT(m_openDatabaseConnections.isEmpty());
73     ASSERT(m_clientClosePendingDatabaseConnections.isEmpty());
74     ASSERT(m_serverClosePendingDatabaseConnections.isEmpty());
75     ASSERT(!m_queuedTaskCount);
76 }
77
78 const IDBDatabaseInfo& UniqueIDBDatabase::info() const
79 {
80     RELEASE_ASSERT(m_databaseInfo);
81     return *m_databaseInfo;
82 }
83
84 void UniqueIDBDatabase::openDatabaseConnection(IDBConnectionToClient& connection, const IDBRequestData& requestData)
85 {
86     LOG(IndexedDB, "UniqueIDBDatabase::openDatabaseConnection");
87     ASSERT(!m_hardClosedForUserDelete);
88
89     m_pendingOpenDBRequests.add(ServerOpenDBRequest::create(connection, requestData));
90
91     // An open operation is already in progress, so we can't possibly handle this one yet.
92     if (m_isOpeningBackingStore)
93         return;
94
95     handleDatabaseOperations();
96 }
97
98 bool UniqueIDBDatabase::hasAnyPendingCallbacks() const
99 {
100     return !m_errorCallbacks.isEmpty()
101         || !m_keyDataCallbacks.isEmpty()
102         || !m_getResultCallbacks.isEmpty()
103         || !m_getAllResultsCallbacks.isEmpty()
104         || !m_countCallbacks.isEmpty();
105 }
106
107 bool UniqueIDBDatabase::isVersionChangeInProgress()
108 {
109 #if !LOG_DISABLED
110     if (m_versionChangeTransaction)
111         ASSERT(m_versionChangeDatabaseConnection);
112 #endif
113
114     return m_versionChangeDatabaseConnection;
115 }
116
117 void UniqueIDBDatabase::performCurrentOpenOperation()
118 {
119     LOG(IndexedDB, "(main) UniqueIDBDatabase::performCurrentOpenOperation (%p)", this);
120
121     ASSERT(m_currentOpenDBRequest);
122     ASSERT(m_currentOpenDBRequest->isOpenRequest());
123
124     if (!m_databaseInfo) {
125         if (!m_isOpeningBackingStore) {
126             m_isOpeningBackingStore = true;
127             postDatabaseTask(createCrossThreadTask(*this, &UniqueIDBDatabase::openBackingStore, m_identifier));
128         }
129
130         return;
131     }
132
133     // If we previously started a version change operation but were blocked by having open connections,
134     // we might now be unblocked.
135     if (m_versionChangeDatabaseConnection) {
136         if (!m_versionChangeTransaction && !hasAnyOpenConnections())
137             startVersionChangeTransaction();
138         return;
139     }
140
141     // 3.3.1 Opening a database
142     // If requested version is undefined, then let requested version be 1 if db was created in the previous step,
143     // or the current version of db otherwise.
144     uint64_t requestedVersion = m_currentOpenDBRequest->requestData().requestedVersion();
145     if (!requestedVersion)
146         requestedVersion = m_databaseInfo->version() ? m_databaseInfo->version() : 1;
147
148     // 3.3.1 Opening a database
149     // If the database version higher than the requested version, abort these steps and return a VersionError.
150     if (requestedVersion < m_databaseInfo->version()) {
151         auto result = IDBResultData::error(m_currentOpenDBRequest->requestData().requestIdentifier(), IDBError(IDBDatabaseException::VersionError));
152         m_currentOpenDBRequest->connection().didOpenDatabase(result);
153         m_currentOpenDBRequest = nullptr;
154
155         return;
156     }
157
158     if (!m_backingStoreOpenError.isNull()) {
159         auto result = IDBResultData::error(m_currentOpenDBRequest->requestData().requestIdentifier(), m_backingStoreOpenError);
160         m_currentOpenDBRequest->connection().didOpenDatabase(result);
161         m_currentOpenDBRequest = nullptr;
162
163         return;
164     }
165
166     Ref<UniqueIDBDatabaseConnection> connection = UniqueIDBDatabaseConnection::create(*this, *m_currentOpenDBRequest);
167
168     if (requestedVersion == m_databaseInfo->version()) {
169         auto* rawConnection = &connection.get();
170         addOpenDatabaseConnection(WTFMove(connection));
171
172         auto result = IDBResultData::openDatabaseSuccess(m_currentOpenDBRequest->requestData().requestIdentifier(), *rawConnection);
173         m_currentOpenDBRequest->connection().didOpenDatabase(result);
174         m_currentOpenDBRequest = nullptr;
175
176         return;
177     }
178
179     ASSERT(!m_versionChangeDatabaseConnection);
180     m_versionChangeDatabaseConnection = WTFMove(connection);
181
182     // 3.3.7 "versionchange" transaction steps
183     // If there's no other open connections to this database, the version change process can begin immediately.
184     if (!hasAnyOpenConnections()) {
185         startVersionChangeTransaction();
186         return;
187     }
188
189     // Otherwise we have to notify all those open connections and wait for them to close.
190     maybeNotifyConnectionsOfVersionChange();
191 }
192
193 void UniqueIDBDatabase::performCurrentDeleteOperation()
194 {
195     ASSERT(isMainThread());
196     LOG(IndexedDB, "(main) UniqueIDBDatabase::performCurrentDeleteOperation - %s", m_identifier.debugString().utf8().data());
197
198     ASSERT(m_currentOpenDBRequest);
199     ASSERT(m_currentOpenDBRequest->isDeleteRequest());
200
201     if (m_deleteBackingStoreInProgress)
202         return;
203
204     if (hasAnyOpenConnections()) {
205         maybeNotifyConnectionsOfVersionChange();
206         return;
207     }
208
209     if (hasUnfinishedTransactions())
210         return;
211
212     ASSERT(!hasAnyPendingCallbacks());
213     ASSERT(m_pendingTransactions.isEmpty());
214     ASSERT(m_openDatabaseConnections.isEmpty());
215
216     // It's possible to have multiple delete requests queued up in a row.
217     // In that scenario only the first request will actually have to delete the database.
218     // Subsequent requests can immediately notify their completion.
219
220     if (!m_deleteBackingStoreInProgress) {
221         if (!m_databaseInfo && m_mostRecentDeletedDatabaseInfo)
222             didDeleteBackingStore(0);
223         else {
224             m_deleteBackingStoreInProgress = true;
225             postDatabaseTask(createCrossThreadTask(*this, &UniqueIDBDatabase::deleteBackingStore, m_identifier));
226         }
227     }
228 }
229
230 void UniqueIDBDatabase::deleteBackingStore(const IDBDatabaseIdentifier& identifier)
231 {
232     ASSERT(!isMainThread());
233     LOG(IndexedDB, "(db) UniqueIDBDatabase::deleteBackingStore");
234
235     uint64_t deletedVersion = 0;
236
237     if (m_backingStore) {
238         m_backingStore->deleteBackingStore();
239         m_backingStore = nullptr;
240         m_backingStoreSupportsSimultaneousTransactions = false;
241         m_backingStoreIsEphemeral = false;
242     } else {
243         auto backingStore = m_server.createBackingStore(identifier);
244
245         IDBDatabaseInfo databaseInfo;
246         auto error = backingStore->getOrEstablishDatabaseInfo(databaseInfo);
247         if (!error.isNull())
248             LOG_ERROR("Error getting database info from database %s that we are trying to delete", identifier.debugString().utf8().data());
249
250         deletedVersion = databaseInfo.version();
251         backingStore->deleteBackingStore();
252     }
253
254     postDatabaseTaskReply(createCrossThreadTask(*this, &UniqueIDBDatabase::didDeleteBackingStore, deletedVersion));
255 }
256
257 void UniqueIDBDatabase::performUnconditionalDeleteBackingStore()
258 {
259     ASSERT(!isMainThread());
260     LOG(IndexedDB, "(db) UniqueIDBDatabase::performUnconditionalDeleteBackingStore");
261
262     if (!m_backingStore)
263         return;
264
265     m_backingStore->deleteBackingStore();
266     m_backingStore = nullptr;
267     m_backingStoreSupportsSimultaneousTransactions = false;
268     m_backingStoreIsEphemeral = false;
269 }
270
271 void UniqueIDBDatabase::didDeleteBackingStore(uint64_t deletedVersion)
272 {
273     ASSERT(isMainThread());
274     LOG(IndexedDB, "(main) UniqueIDBDatabase::didDeleteBackingStore");
275
276     ASSERT(!hasAnyPendingCallbacks());
277     ASSERT(!hasUnfinishedTransactions());
278     ASSERT(m_pendingTransactions.isEmpty());
279     ASSERT(m_openDatabaseConnections.isEmpty());
280
281     // It's possible that the openDBRequest was cancelled from client-side after the delete was already dispatched to the backingstore.
282     // So it's okay if we don't have a currentOpenDBRequest, but if we do it has to be a deleteRequest.
283     ASSERT(!m_currentOpenDBRequest || m_currentOpenDBRequest->isDeleteRequest());
284
285     if (m_databaseInfo)
286         m_mostRecentDeletedDatabaseInfo = WTFMove(m_databaseInfo);
287
288     // If this UniqueIDBDatabase was brought into existence for the purpose of deleting the file on disk,
289     // we won't have a m_mostRecentDeletedDatabaseInfo. In that case, we'll manufacture one using the
290     // passed in deletedVersion argument.
291     if (!m_mostRecentDeletedDatabaseInfo)
292         m_mostRecentDeletedDatabaseInfo = std::make_unique<IDBDatabaseInfo>(m_identifier.databaseName(), deletedVersion);
293
294     if (m_currentOpenDBRequest) {
295         m_currentOpenDBRequest->notifyDidDeleteDatabase(*m_mostRecentDeletedDatabaseInfo);
296         m_currentOpenDBRequest = nullptr;
297     }
298
299     m_deleteBackingStoreInProgress = false;
300
301     if (m_clientClosePendingDatabaseConnections.isEmpty() && m_pendingOpenDBRequests.isEmpty()) {
302         m_server.closeUniqueIDBDatabase(*this);
303         return;
304     }
305
306     invokeOperationAndTransactionTimer();
307 }
308
309 void UniqueIDBDatabase::didPerformUnconditionalDeleteBackingStore()
310 {
311     // This function is a placeholder so the database thread can message back to the main thread.
312     ASSERT(m_hardClosedForUserDelete);
313 }
314
315 void UniqueIDBDatabase::handleDatabaseOperations()
316 {
317     ASSERT(isMainThread());
318     LOG(IndexedDB, "(main) UniqueIDBDatabase::handleDatabaseOperations - There are %u pending", m_pendingOpenDBRequests.size());
319     ASSERT(!m_hardClosedForUserDelete);
320
321     if (m_deleteBackingStoreInProgress)
322         return;
323
324     if (m_versionChangeDatabaseConnection || m_versionChangeTransaction || m_currentOpenDBRequest) {
325         // We can't start any new open-database operations right now, but we might be able to start handling a delete operation.
326         if (!m_currentOpenDBRequest && !m_pendingOpenDBRequests.isEmpty() && m_pendingOpenDBRequests.first()->isDeleteRequest())
327             m_currentOpenDBRequest = m_pendingOpenDBRequests.takeFirst();
328
329         // Some operations (such as the first open operation after a delete) require multiple passes to completely handle
330         if (m_currentOpenDBRequest)
331             handleCurrentOperation();
332
333         return;
334     }
335
336     if (m_pendingOpenDBRequests.isEmpty())
337         return;
338
339     m_currentOpenDBRequest = m_pendingOpenDBRequests.takeFirst();
340     LOG(IndexedDB, "UniqueIDBDatabase::handleDatabaseOperations - Popped an operation, now there are %u pending", m_pendingOpenDBRequests.size());
341
342     handleCurrentOperation();
343 }
344
345 void UniqueIDBDatabase::handleCurrentOperation()
346 {
347     LOG(IndexedDB, "(main) UniqueIDBDatabase::handleCurrentOperation");
348     ASSERT(!m_hardClosedForUserDelete);
349     ASSERT(m_currentOpenDBRequest);
350
351     RefPtr<UniqueIDBDatabase> protectedThis(this);
352
353     if (m_currentOpenDBRequest->isOpenRequest())
354         performCurrentOpenOperation();
355     else if (m_currentOpenDBRequest->isDeleteRequest())
356         performCurrentDeleteOperation();
357     else
358         ASSERT_NOT_REACHED();
359
360     if (!m_currentOpenDBRequest)
361         invokeOperationAndTransactionTimer();
362 }
363
364 bool UniqueIDBDatabase::hasAnyOpenConnections() const
365 {
366     return !m_openDatabaseConnections.isEmpty();
367 }
368
369 static uint64_t generateUniqueCallbackIdentifier()
370 {
371     ASSERT(isMainThread());
372     static uint64_t currentID = 0;
373     return ++currentID;
374 }
375
376 uint64_t UniqueIDBDatabase::storeCallbackOrFireError(ErrorCallback callback)
377 {
378     if (m_hardClosedForUserDelete) {
379         callback(IDBError::userDeleteError());
380         return 0;
381     }
382
383     uint64_t identifier = generateUniqueCallbackIdentifier();
384     ASSERT(!m_errorCallbacks.contains(identifier));
385     m_errorCallbacks.add(identifier, callback);
386     return identifier;
387 }
388
389 uint64_t UniqueIDBDatabase::storeCallbackOrFireError(KeyDataCallback callback)
390 {
391     if (m_hardClosedForUserDelete) {
392         callback(IDBError::userDeleteError(), { });
393         return 0;
394     }
395
396     uint64_t identifier = generateUniqueCallbackIdentifier();
397     ASSERT(!m_keyDataCallbacks.contains(identifier));
398     m_keyDataCallbacks.add(identifier, callback);
399     return identifier;
400 }
401
402 uint64_t UniqueIDBDatabase::storeCallbackOrFireError(GetResultCallback callback)
403 {
404     if (m_hardClosedForUserDelete) {
405         callback(IDBError::userDeleteError(), { });
406         return 0;
407     }
408
409     uint64_t identifier = generateUniqueCallbackIdentifier();
410     ASSERT(!m_getResultCallbacks.contains(identifier));
411     m_getResultCallbacks.add(identifier, callback);
412     return identifier;
413 }
414
415 uint64_t UniqueIDBDatabase::storeCallbackOrFireError(GetAllResultsCallback callback)
416 {
417     if (m_hardClosedForUserDelete) {
418         callback(IDBError::userDeleteError(), { });
419         return 0;
420     }
421
422     uint64_t identifier = generateUniqueCallbackIdentifier();
423     ASSERT(!m_getAllResultsCallbacks.contains(identifier));
424     m_getAllResultsCallbacks.add(identifier, callback);
425     return identifier;
426 }
427
428 uint64_t UniqueIDBDatabase::storeCallbackOrFireError(CountCallback callback)
429 {
430     if (m_hardClosedForUserDelete) {
431         callback(IDBError::userDeleteError(), 0);
432         return 0;
433     }
434
435     uint64_t identifier = generateUniqueCallbackIdentifier();
436     ASSERT(!m_countCallbacks.contains(identifier));
437     m_countCallbacks.add(identifier, callback);
438     return identifier;
439 }
440
441 void UniqueIDBDatabase::handleDelete(IDBConnectionToClient& connection, const IDBRequestData& requestData)
442 {
443     LOG(IndexedDB, "(main) UniqueIDBDatabase::handleDelete");
444     ASSERT(!m_hardClosedForUserDelete);
445
446     m_pendingOpenDBRequests.add(ServerOpenDBRequest::create(connection, requestData));
447     handleDatabaseOperations();
448 }
449
450 void UniqueIDBDatabase::startVersionChangeTransaction()
451 {
452     LOG(IndexedDB, "(main) UniqueIDBDatabase::startVersionChangeTransaction");
453
454     ASSERT(!m_versionChangeTransaction);
455     ASSERT(m_currentOpenDBRequest);
456     ASSERT(m_currentOpenDBRequest->isOpenRequest());
457     ASSERT(m_versionChangeDatabaseConnection);
458
459     auto operation = WTFMove(m_currentOpenDBRequest);
460
461     uint64_t requestedVersion = operation->requestData().requestedVersion();
462     if (!requestedVersion)
463         requestedVersion = m_databaseInfo->version() ? m_databaseInfo->version() : 1;
464
465     addOpenDatabaseConnection(*m_versionChangeDatabaseConnection);
466
467     m_versionChangeTransaction = &m_versionChangeDatabaseConnection->createVersionChangeTransaction(requestedVersion);
468     m_databaseInfo->setVersion(requestedVersion);
469
470     m_inProgressTransactions.set(m_versionChangeTransaction->info().identifier(), m_versionChangeTransaction);
471     postDatabaseTask(createCrossThreadTask(*this, &UniqueIDBDatabase::beginTransactionInBackingStore, m_versionChangeTransaction->info()));
472
473     auto result = IDBResultData::openDatabaseUpgradeNeeded(operation->requestData().requestIdentifier(), *m_versionChangeTransaction);
474     operation->connection().didOpenDatabase(result);
475 }
476
477 void UniqueIDBDatabase::beginTransactionInBackingStore(const IDBTransactionInfo& info)
478 {
479     LOG(IndexedDB, "(db) UniqueIDBDatabase::beginTransactionInBackingStore");
480     m_backingStore->beginTransaction(info);
481 }
482
483 void UniqueIDBDatabase::maybeNotifyConnectionsOfVersionChange()
484 {
485     ASSERT(m_currentOpenDBRequest);
486
487     if (m_currentOpenDBRequest->hasNotifiedConnectionsOfVersionChange())
488         return;
489
490     uint64_t newVersion = m_currentOpenDBRequest->isOpenRequest() ? m_currentOpenDBRequest->requestData().requestedVersion() : 0;
491     auto requestIdentifier = m_currentOpenDBRequest->requestData().requestIdentifier();
492
493     LOG(IndexedDB, "(main) UniqueIDBDatabase::notifyConnectionsOfVersionChange - %" PRIu64, newVersion);
494
495     // 3.3.7 "versionchange" transaction steps
496     // Fire a versionchange event at each connection in m_openDatabaseConnections that is open.
497     // The event must not be fired on connections which has the closePending flag set.
498     HashSet<uint64_t> connectionIdentifiers;
499     for (auto connection : m_openDatabaseConnections) {
500         if (connection->closePending())
501             continue;
502
503         connection->fireVersionChangeEvent(requestIdentifier, newVersion);
504         connectionIdentifiers.add(connection->identifier());
505     }
506
507     m_currentOpenDBRequest->notifiedConnectionsOfVersionChange(WTFMove(connectionIdentifiers));
508 }
509
510 void UniqueIDBDatabase::notifyCurrentRequestConnectionClosedOrFiredVersionChangeEvent(uint64_t connectionIdentifier)
511 {
512     LOG(IndexedDB, "UniqueIDBDatabase::notifyCurrentRequestConnectionClosedOrFiredVersionChangeEvent - %" PRIu64, connectionIdentifier);
513
514     ASSERT(m_currentOpenDBRequest);
515
516     m_currentOpenDBRequest->connectionClosedOrFiredVersionChangeEvent(connectionIdentifier);
517
518     if (m_currentOpenDBRequest->hasConnectionsPendingVersionChangeEvent())
519         return;
520
521     if (!hasAnyOpenConnections()) {
522         invokeOperationAndTransactionTimer();
523         return;
524     }
525
526     if (m_currentOpenDBRequest->hasNotifiedBlocked())
527         return;
528
529     // Since all open connections have fired their version change events but not all of them have closed,
530     // this request is officially blocked.
531     m_currentOpenDBRequest->notifyRequestBlocked(m_databaseInfo->version());
532 }
533
534 void UniqueIDBDatabase::didFireVersionChangeEvent(UniqueIDBDatabaseConnection& connection, const IDBResourceIdentifier& requestIdentifier)
535 {
536     LOG(IndexedDB, "UniqueIDBDatabase::didFireVersionChangeEvent");
537
538     if (!m_currentOpenDBRequest)
539         return;
540
541     ASSERT_UNUSED(requestIdentifier, m_currentOpenDBRequest->requestData().requestIdentifier() == requestIdentifier);
542
543     notifyCurrentRequestConnectionClosedOrFiredVersionChangeEvent(connection.identifier());
544 }
545
546 void UniqueIDBDatabase::openDBRequestCancelled(const IDBResourceIdentifier& requestIdentifier)
547 {
548     LOG(IndexedDB, "UniqueIDBDatabase::openDBRequestCancelled - %s", requestIdentifier.loggingString().utf8().data());
549
550     if (m_currentOpenDBRequest && m_currentOpenDBRequest->requestData().requestIdentifier() == requestIdentifier)
551         m_currentOpenDBRequest = nullptr;
552
553     if (m_versionChangeDatabaseConnection && m_versionChangeDatabaseConnection->openRequestIdentifier() == requestIdentifier) {
554         ASSERT(!m_versionChangeTransaction || m_versionChangeTransaction->databaseConnection().openRequestIdentifier() == requestIdentifier);
555         ASSERT(!m_versionChangeTransaction || &m_versionChangeTransaction->databaseConnection() == m_versionChangeDatabaseConnection);
556
557         connectionClosedFromClient(*m_versionChangeDatabaseConnection);
558     }
559
560     for (auto& request : m_pendingOpenDBRequests) {
561         if (request->requestData().requestIdentifier() == requestIdentifier) {
562             m_pendingOpenDBRequests.remove(request);
563             return;
564         }
565     }
566 }
567
568 void UniqueIDBDatabase::addOpenDatabaseConnection(Ref<UniqueIDBDatabaseConnection>&& connection)
569 {
570     ASSERT(!m_openDatabaseConnections.contains(&connection.get()));
571     m_openDatabaseConnections.add(adoptRef(connection.leakRef()));
572 }
573
574 void UniqueIDBDatabase::openBackingStore(const IDBDatabaseIdentifier& identifier)
575 {
576     ASSERT(!isMainThread());
577     LOG(IndexedDB, "(db) UniqueIDBDatabase::openBackingStore (%p)", this);
578
579     ASSERT(!m_backingStore);
580     m_backingStore = m_server.createBackingStore(identifier);
581     m_backingStoreSupportsSimultaneousTransactions = m_backingStore->supportsSimultaneousTransactions();
582     m_backingStoreIsEphemeral = m_backingStore->isEphemeral();
583
584     IDBDatabaseInfo databaseInfo;
585     auto error = m_backingStore->getOrEstablishDatabaseInfo(databaseInfo);
586
587     postDatabaseTaskReply(createCrossThreadTask(*this, &UniqueIDBDatabase::didOpenBackingStore, databaseInfo, error));
588 }
589
590 void UniqueIDBDatabase::didOpenBackingStore(const IDBDatabaseInfo& info, const IDBError& error)
591 {
592     ASSERT(isMainThread());
593     LOG(IndexedDB, "(main) UniqueIDBDatabase::didOpenBackingStore");
594     
595     m_databaseInfo = std::make_unique<IDBDatabaseInfo>(info);
596     m_backingStoreOpenError = error;
597
598     ASSERT(m_isOpeningBackingStore);
599     m_isOpeningBackingStore = false;
600
601     handleDatabaseOperations();
602 }
603
604 void UniqueIDBDatabase::createObjectStore(UniqueIDBDatabaseTransaction& transaction, const IDBObjectStoreInfo& info, ErrorCallback callback)
605 {
606     ASSERT(isMainThread());
607     LOG(IndexedDB, "(main) UniqueIDBDatabase::createObjectStore");
608
609     uint64_t callbackID = storeCallbackOrFireError(callback);
610     if (!callbackID)
611         return;
612
613     postDatabaseTask(createCrossThreadTask(*this, &UniqueIDBDatabase::performCreateObjectStore, callbackID, transaction.info().identifier(), info));
614 }
615
616 void UniqueIDBDatabase::performCreateObjectStore(uint64_t callbackIdentifier, const IDBResourceIdentifier& transactionIdentifier, const IDBObjectStoreInfo& info)
617 {
618     ASSERT(!isMainThread());
619     LOG(IndexedDB, "(db) UniqueIDBDatabase::performCreateObjectStore");
620
621     ASSERT(m_backingStore);
622     m_backingStore->createObjectStore(transactionIdentifier, info);
623
624     IDBError error;
625     postDatabaseTaskReply(createCrossThreadTask(*this, &UniqueIDBDatabase::didPerformCreateObjectStore, callbackIdentifier, error, info));
626 }
627
628 void UniqueIDBDatabase::didPerformCreateObjectStore(uint64_t callbackIdentifier, const IDBError& error, const IDBObjectStoreInfo& info)
629 {
630     ASSERT(isMainThread());
631     LOG(IndexedDB, "(main) UniqueIDBDatabase::didPerformCreateObjectStore");
632
633     if (error.isNull())
634         m_databaseInfo->addExistingObjectStore(info);
635
636     performErrorCallback(callbackIdentifier, error);
637 }
638
639 void UniqueIDBDatabase::deleteObjectStore(UniqueIDBDatabaseTransaction& transaction, const String& objectStoreName, ErrorCallback callback)
640 {
641     ASSERT(isMainThread());
642     LOG(IndexedDB, "(main) UniqueIDBDatabase::deleteObjectStore");
643
644     uint64_t callbackID = storeCallbackOrFireError(callback);
645     if (!callbackID)
646         return;
647
648     auto* info = m_databaseInfo->infoForExistingObjectStore(objectStoreName);
649     if (!info) {
650         performErrorCallback(callbackID, { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to delete non-existant object store") });
651         return;
652     }
653
654     postDatabaseTask(createCrossThreadTask(*this, &UniqueIDBDatabase::performDeleteObjectStore, callbackID, transaction.info().identifier(), info->identifier()));
655 }
656
657 void UniqueIDBDatabase::performDeleteObjectStore(uint64_t callbackIdentifier, const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier)
658 {
659     ASSERT(!isMainThread());
660     LOG(IndexedDB, "(db) UniqueIDBDatabase::performDeleteObjectStore");
661
662     ASSERT(m_backingStore);
663     m_backingStore->deleteObjectStore(transactionIdentifier, objectStoreIdentifier);
664
665     IDBError error;
666     postDatabaseTaskReply(createCrossThreadTask(*this, &UniqueIDBDatabase::didPerformDeleteObjectStore, callbackIdentifier, error, objectStoreIdentifier));
667 }
668
669 void UniqueIDBDatabase::didPerformDeleteObjectStore(uint64_t callbackIdentifier, const IDBError& error, uint64_t objectStoreIdentifier)
670 {
671     ASSERT(isMainThread());
672     LOG(IndexedDB, "(main) UniqueIDBDatabase::didPerformDeleteObjectStore");
673
674     if (error.isNull())
675         m_databaseInfo->deleteObjectStore(objectStoreIdentifier);
676
677     performErrorCallback(callbackIdentifier, error);
678 }
679
680 void UniqueIDBDatabase::renameObjectStore(UniqueIDBDatabaseTransaction& transaction, uint64_t objectStoreIdentifier, const String& newName, ErrorCallback callback)
681 {
682     ASSERT(isMainThread());
683     LOG(IndexedDB, "(main) UniqueIDBDatabase::renameObjectStore");
684
685     uint64_t callbackID = storeCallbackOrFireError(callback);
686     if (!callbackID)
687         return;
688
689     auto* info = m_databaseInfo->infoForExistingObjectStore(objectStoreIdentifier);
690     if (!info) {
691         performErrorCallback(callbackID, { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to rename non-existant object store") });
692         return;
693     }
694
695     postDatabaseTask(createCrossThreadTask(*this, &UniqueIDBDatabase::performRenameObjectStore, callbackID, transaction.info().identifier(), objectStoreIdentifier, newName));
696 }
697
698 void UniqueIDBDatabase::performRenameObjectStore(uint64_t callbackIdentifier, const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, const String& newName)
699 {
700     ASSERT(!isMainThread());
701     LOG(IndexedDB, "(db) UniqueIDBDatabase::performRenameObjectStore");
702
703     ASSERT(m_backingStore);
704     m_backingStore->renameObjectStore(transactionIdentifier, objectStoreIdentifier, newName);
705
706     IDBError error;
707     postDatabaseTaskReply(createCrossThreadTask(*this, &UniqueIDBDatabase::didPerformRenameObjectStore, callbackIdentifier, error, objectStoreIdentifier, newName));
708 }
709
710 void UniqueIDBDatabase::didPerformRenameObjectStore(uint64_t callbackIdentifier, const IDBError& error, uint64_t objectStoreIdentifier, const String& newName)
711 {
712     ASSERT(isMainThread());
713     LOG(IndexedDB, "(main) UniqueIDBDatabase::didPerformRenameObjectStore");
714
715     if (error.isNull())
716         m_databaseInfo->renameObjectStore(objectStoreIdentifier, newName);
717
718     performErrorCallback(callbackIdentifier, error);
719 }
720
721 void UniqueIDBDatabase::clearObjectStore(UniqueIDBDatabaseTransaction& transaction, uint64_t objectStoreIdentifier, ErrorCallback callback)
722 {
723     ASSERT(isMainThread());
724     LOG(IndexedDB, "(main) UniqueIDBDatabase::clearObjectStore");
725
726     uint64_t callbackID = storeCallbackOrFireError(callback);
727     if (!callbackID)
728         return;
729     postDatabaseTask(createCrossThreadTask(*this, &UniqueIDBDatabase::performClearObjectStore, callbackID, transaction.info().identifier(), objectStoreIdentifier));
730 }
731
732 void UniqueIDBDatabase::performClearObjectStore(uint64_t callbackIdentifier, const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier)
733 {
734     ASSERT(!isMainThread());
735     LOG(IndexedDB, "(db) UniqueIDBDatabase::performClearObjectStore");
736
737     ASSERT(m_backingStore);
738     m_backingStore->clearObjectStore(transactionIdentifier, objectStoreIdentifier);
739
740     IDBError error;
741     postDatabaseTaskReply(createCrossThreadTask(*this, &UniqueIDBDatabase::didPerformClearObjectStore, callbackIdentifier, error));
742 }
743
744 void UniqueIDBDatabase::didPerformClearObjectStore(uint64_t callbackIdentifier, const IDBError& error)
745 {
746     ASSERT(isMainThread());
747     LOG(IndexedDB, "(main) UniqueIDBDatabase::didPerformClearObjectStore");
748
749     performErrorCallback(callbackIdentifier, error);
750 }
751
752 void UniqueIDBDatabase::createIndex(UniqueIDBDatabaseTransaction& transaction, const IDBIndexInfo& info, ErrorCallback callback)
753 {
754     ASSERT(isMainThread());
755     LOG(IndexedDB, "(main) UniqueIDBDatabase::createIndex");
756
757     uint64_t callbackID = storeCallbackOrFireError(callback);
758     if (!callbackID)
759         return;
760     postDatabaseTask(createCrossThreadTask(*this, &UniqueIDBDatabase::performCreateIndex, callbackID, transaction.info().identifier(), info));
761 }
762
763 void UniqueIDBDatabase::performCreateIndex(uint64_t callbackIdentifier, const IDBResourceIdentifier& transactionIdentifier, const IDBIndexInfo& info)
764 {
765     ASSERT(!isMainThread());
766     LOG(IndexedDB, "(db) UniqueIDBDatabase::performCreateIndex");
767
768     ASSERT(m_backingStore);
769     IDBError error = m_backingStore->createIndex(transactionIdentifier, info);
770
771     postDatabaseTaskReply(createCrossThreadTask(*this, &UniqueIDBDatabase::didPerformCreateIndex, callbackIdentifier, error, info));
772 }
773
774 void UniqueIDBDatabase::didPerformCreateIndex(uint64_t callbackIdentifier, const IDBError& error, const IDBIndexInfo& info)
775 {
776     ASSERT(isMainThread());
777     LOG(IndexedDB, "(main) UniqueIDBDatabase::didPerformCreateIndex");
778
779     if (error.isNull()) {
780         ASSERT(m_databaseInfo);
781         auto* objectStoreInfo = m_databaseInfo->infoForExistingObjectStore(info.objectStoreIdentifier());
782         ASSERT(objectStoreInfo);
783         objectStoreInfo->addExistingIndex(info);
784     }
785
786     performErrorCallback(callbackIdentifier, error);
787 }
788
789 void UniqueIDBDatabase::deleteIndex(UniqueIDBDatabaseTransaction& transaction, uint64_t objectStoreIdentifier, const String& indexName, ErrorCallback callback)
790 {
791     ASSERT(isMainThread());
792     LOG(IndexedDB, "(main) UniqueIDBDatabase::deleteIndex");
793
794     uint64_t callbackID = storeCallbackOrFireError(callback);
795     if (!callbackID)
796         return;
797
798     auto* objectStoreInfo = m_databaseInfo->infoForExistingObjectStore(objectStoreIdentifier);
799     if (!objectStoreInfo) {
800         performErrorCallback(callbackID, { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to delete index from non-existant object store") });
801         return;
802     }
803
804     auto* indexInfo = objectStoreInfo->infoForExistingIndex(indexName);
805     if (!indexInfo) {
806         performErrorCallback(callbackID, { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to delete non-existant index") });
807         return;
808     }
809
810     postDatabaseTask(createCrossThreadTask(*this, &UniqueIDBDatabase::performDeleteIndex, callbackID, transaction.info().identifier(), objectStoreIdentifier, indexInfo->identifier()));
811 }
812
813 void UniqueIDBDatabase::performDeleteIndex(uint64_t callbackIdentifier, const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, const uint64_t indexIdentifier)
814 {
815     ASSERT(!isMainThread());
816     LOG(IndexedDB, "(db) UniqueIDBDatabase::performDeleteIndex");
817
818     ASSERT(m_backingStore);
819     m_backingStore->deleteIndex(transactionIdentifier, objectStoreIdentifier, indexIdentifier);
820
821     IDBError error;
822     postDatabaseTaskReply(createCrossThreadTask(*this, &UniqueIDBDatabase::didPerformDeleteIndex, callbackIdentifier, error, objectStoreIdentifier, indexIdentifier));
823 }
824
825 void UniqueIDBDatabase::didPerformDeleteIndex(uint64_t callbackIdentifier, const IDBError& error, uint64_t objectStoreIdentifier, uint64_t indexIdentifier)
826 {
827     ASSERT(isMainThread());
828     LOG(IndexedDB, "(main) UniqueIDBDatabase::didPerformDeleteIndex");
829
830     if (error.isNull()) {
831         auto* objectStoreInfo = m_databaseInfo->infoForExistingObjectStore(objectStoreIdentifier);
832         if (objectStoreInfo)
833             objectStoreInfo->deleteIndex(indexIdentifier);
834     }
835
836     performErrorCallback(callbackIdentifier, error);
837 }
838
839 void UniqueIDBDatabase::renameIndex(UniqueIDBDatabaseTransaction& transaction, uint64_t objectStoreIdentifier, uint64_t indexIdentifier, const String& newName, ErrorCallback callback)
840 {
841     ASSERT(isMainThread());
842     LOG(IndexedDB, "(main) UniqueIDBDatabase::renameIndex");
843
844     uint64_t callbackID = storeCallbackOrFireError(callback);
845     if (!callbackID)
846         return;
847
848     auto* objectStoreInfo = m_databaseInfo->infoForExistingObjectStore(objectStoreIdentifier);
849     if (!objectStoreInfo) {
850         performErrorCallback(callbackID, { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to rename index in non-existant object store") });
851         return;
852     }
853
854     auto* indexInfo = objectStoreInfo->infoForExistingIndex(indexIdentifier);
855     if (!indexInfo) {
856         performErrorCallback(callbackID, { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to rename non-existant index") });
857         return;
858     }
859
860     postDatabaseTask(createCrossThreadTask(*this, &UniqueIDBDatabase::performRenameIndex, callbackID, transaction.info().identifier(), objectStoreIdentifier, indexIdentifier, newName));
861 }
862
863 void UniqueIDBDatabase::performRenameIndex(uint64_t callbackIdentifier, const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, uint64_t indexIdentifier, const String& newName)
864 {
865     ASSERT(!isMainThread());
866     LOG(IndexedDB, "(db) UniqueIDBDatabase::performRenameIndex");
867
868     ASSERT(m_backingStore);
869     m_backingStore->renameIndex(transactionIdentifier, objectStoreIdentifier, indexIdentifier, newName);
870
871     IDBError error;
872     postDatabaseTaskReply(createCrossThreadTask(*this, &UniqueIDBDatabase::didPerformRenameIndex, callbackIdentifier, error, objectStoreIdentifier, indexIdentifier, newName));
873 }
874
875 void UniqueIDBDatabase::didPerformRenameIndex(uint64_t callbackIdentifier, const IDBError& error, uint64_t objectStoreIdentifier, uint64_t indexIdentifier, const String& newName)
876 {
877     ASSERT(isMainThread());
878     LOG(IndexedDB, "(main) UniqueIDBDatabase::didPerformRenameIndex");
879
880     if (error.isNull()) {
881         auto* objectStoreInfo = m_databaseInfo->infoForExistingObjectStore(objectStoreIdentifier);
882         ASSERT(objectStoreInfo);
883         if (objectStoreInfo) {
884             auto* indexInfo = objectStoreInfo->infoForExistingIndex(indexIdentifier);
885             ASSERT(indexInfo);
886             indexInfo->rename(newName);
887         }
888     }
889
890     performErrorCallback(callbackIdentifier, error);
891 }
892
893 void UniqueIDBDatabase::putOrAdd(const IDBRequestData& requestData, const IDBKeyData& keyData, const IDBValue& value, IndexedDB::ObjectStoreOverwriteMode overwriteMode, KeyDataCallback callback)
894 {
895     ASSERT(isMainThread());
896     LOG(IndexedDB, "(main) UniqueIDBDatabase::putOrAdd");
897
898     uint64_t callbackID = storeCallbackOrFireError(callback);
899     if (!callbackID)
900         return;
901     postDatabaseTask(createCrossThreadTask(*this, &UniqueIDBDatabase::performPutOrAdd, callbackID, requestData.transactionIdentifier(), requestData.objectStoreIdentifier(), keyData, value, overwriteMode));
902 }
903
904 VM& UniqueIDBDatabase::databaseThreadVM()
905 {
906     ASSERT(!isMainThread());
907     static VM* vm = &VM::create().leakRef();
908     return *vm;
909 }
910
911 ExecState& UniqueIDBDatabase::databaseThreadExecState()
912 {
913     ASSERT(!isMainThread());
914
915     static NeverDestroyed<Strong<JSGlobalObject>> globalObject(databaseThreadVM(), JSGlobalObject::create(databaseThreadVM(), JSGlobalObject::createStructure(databaseThreadVM(), jsNull())));
916
917     RELEASE_ASSERT(globalObject.get()->globalExec());
918     return *globalObject.get()->globalExec();
919 }
920
921 void UniqueIDBDatabase::performPutOrAdd(uint64_t callbackIdentifier, const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, const IDBKeyData& keyData, const IDBValue& originalRecordValue, IndexedDB::ObjectStoreOverwriteMode overwriteMode)
922 {
923     ASSERT(!isMainThread());
924     LOG(IndexedDB, "(db) UniqueIDBDatabase::performPutOrAdd");
925
926     ASSERT(m_backingStore);
927     ASSERT(objectStoreIdentifier);
928
929     IDBKeyData usedKey;
930     IDBError error;
931
932     auto* objectStoreInfo = m_backingStore->infoForObjectStore(objectStoreIdentifier);
933     if (!objectStoreInfo) {
934         error = IDBError(IDBDatabaseException::InvalidStateError, ASCIILiteral("Object store cannot be found in the backing store"));
935         postDatabaseTaskReply(createCrossThreadTask(*this, &UniqueIDBDatabase::didPerformPutOrAdd, callbackIdentifier, error, usedKey));
936         return;
937     }
938
939     bool usedKeyIsGenerated = false;
940     ScopeGuard generatedKeyResetter;
941     if (objectStoreInfo->autoIncrement() && !keyData.isValid()) {
942         uint64_t keyNumber;
943         error = m_backingStore->generateKeyNumber(transactionIdentifier, objectStoreIdentifier, keyNumber);
944         if (!error.isNull()) {
945             postDatabaseTaskReply(createCrossThreadTask(*this, &UniqueIDBDatabase::didPerformPutOrAdd, callbackIdentifier, error, usedKey));
946             return;
947         }
948         
949         usedKey.setNumberValue(keyNumber);
950         usedKeyIsGenerated = true;
951         generatedKeyResetter.enable([this, transactionIdentifier, objectStoreIdentifier, keyNumber]() {
952             m_backingStore->revertGeneratedKeyNumber(transactionIdentifier, objectStoreIdentifier, keyNumber);
953         });
954     } else
955         usedKey = keyData;
956
957     if (overwriteMode == IndexedDB::ObjectStoreOverwriteMode::NoOverwrite) {
958         bool keyExists;
959         error = m_backingStore->keyExistsInObjectStore(transactionIdentifier, objectStoreIdentifier, usedKey, keyExists);
960         if (error.isNull() && keyExists)
961             error = IDBError(IDBDatabaseException::ConstraintError, ASCIILiteral("Key already exists in the object store"));
962
963         if (!error.isNull()) {
964             postDatabaseTaskReply(createCrossThreadTask(*this, &UniqueIDBDatabase::didPerformPutOrAdd, callbackIdentifier, error, usedKey));
965             return;
966         }
967     }
968
969     // 3.4.1.2 Object Store Storage Operation
970     // If ObjectStore has a key path and the key is autogenerated, then inject the key into the value
971     // using steps to assign a key to a value using a key path.
972     ThreadSafeDataBuffer injectedRecordValue;
973     if (usedKeyIsGenerated && objectStoreInfo->keyPath()) {
974         VM& vm = databaseThreadVM();
975         JSLockHolder locker(vm);
976         auto scope = DECLARE_THROW_SCOPE(vm);
977
978         auto value = deserializeIDBValueToJSValue(databaseThreadExecState(), originalRecordValue.data());
979         if (value.isUndefined()) {
980             postDatabaseTaskReply(createCrossThreadTask(*this, &UniqueIDBDatabase::didPerformPutOrAdd, callbackIdentifier, IDBError(IDBDatabaseException::ConstraintError, ASCIILiteral("Unable to deserialize record value for record key injection")), usedKey));
981             return;
982         }
983
984         if (!injectIDBKeyIntoScriptValue(databaseThreadExecState(), usedKey, value, objectStoreInfo->keyPath().value())) {
985             postDatabaseTaskReply(createCrossThreadTask(*this, &UniqueIDBDatabase::didPerformPutOrAdd, callbackIdentifier, IDBError(IDBDatabaseException::ConstraintError, ASCIILiteral("Unable to inject record key into record value")), usedKey));
986             return;
987         }
988
989         auto serializedValue = SerializedScriptValue::create(databaseThreadExecState(), value);
990         if (UNLIKELY(scope.exception())) {
991             postDatabaseTaskReply(createCrossThreadTask(*this, &UniqueIDBDatabase::didPerformPutOrAdd, callbackIdentifier, IDBError(IDBDatabaseException::ConstraintError, ASCIILiteral("Unable to serialize record value after injecting record key")), usedKey));
992             return;
993         }
994
995         injectedRecordValue = ThreadSafeDataBuffer::copyVector(serializedValue->data());
996     }
997
998     // 3.4.1 Object Store Storage Operation
999     // ...If a record already exists in store ...
1000     // then remove the record from store using the steps for deleting records from an object store...
1001     // This is important because formally deleting it from from the object store also removes it from the appropriate indexes.
1002     error = m_backingStore->deleteRange(transactionIdentifier, objectStoreIdentifier, usedKey);
1003     if (!error.isNull()) {
1004         postDatabaseTaskReply(createCrossThreadTask(*this, &UniqueIDBDatabase::didPerformPutOrAdd, callbackIdentifier, error, usedKey));
1005         return;
1006     }
1007
1008     if (injectedRecordValue.data())
1009         error = m_backingStore->addRecord(transactionIdentifier, *objectStoreInfo, usedKey, { injectedRecordValue, originalRecordValue.blobURLs(), originalRecordValue.blobFilePaths() });
1010     else
1011         error = m_backingStore->addRecord(transactionIdentifier, *objectStoreInfo, usedKey, originalRecordValue);
1012
1013     if (!error.isNull()) {
1014         postDatabaseTaskReply(createCrossThreadTask(*this, &UniqueIDBDatabase::didPerformPutOrAdd, callbackIdentifier, error, usedKey));
1015         return;
1016     }
1017
1018     if (overwriteMode != IndexedDB::ObjectStoreOverwriteMode::OverwriteForCursor && objectStoreInfo->autoIncrement() && keyData.type() == IndexedDB::KeyType::Number)
1019         error = m_backingStore->maybeUpdateKeyGeneratorNumber(transactionIdentifier, objectStoreIdentifier, keyData.number());
1020
1021     generatedKeyResetter.disable();
1022     postDatabaseTaskReply(createCrossThreadTask(*this, &UniqueIDBDatabase::didPerformPutOrAdd, callbackIdentifier, error, usedKey));
1023 }
1024
1025 void UniqueIDBDatabase::didPerformPutOrAdd(uint64_t callbackIdentifier, const IDBError& error, const IDBKeyData& resultKey)
1026 {
1027     ASSERT(isMainThread());
1028     LOG(IndexedDB, "(main) UniqueIDBDatabase::didPerformPutOrAdd");
1029
1030     performKeyDataCallback(callbackIdentifier, error, resultKey);
1031 }
1032
1033 void UniqueIDBDatabase::getRecord(const IDBRequestData& requestData, const IDBGetRecordData& getRecordData, GetResultCallback callback)
1034 {
1035     ASSERT(isMainThread());
1036     LOG(IndexedDB, "(main) UniqueIDBDatabase::getRecord");
1037
1038     uint64_t callbackID = storeCallbackOrFireError(callback);
1039     if (!callbackID)
1040         return;
1041
1042     if (uint64_t indexIdentifier = requestData.indexIdentifier())
1043         postDatabaseTask(createCrossThreadTask(*this, &UniqueIDBDatabase::performGetIndexRecord, callbackID, requestData.transactionIdentifier(), requestData.objectStoreIdentifier(), indexIdentifier, requestData.indexRecordType(), getRecordData.keyRangeData));
1044     else
1045         postDatabaseTask(createCrossThreadTask(*this, &UniqueIDBDatabase::performGetRecord, callbackID, requestData.transactionIdentifier(), requestData.objectStoreIdentifier(), getRecordData.keyRangeData));
1046 }
1047
1048 void UniqueIDBDatabase::getAllRecords(const IDBRequestData& requestData, const IDBGetAllRecordsData& getAllRecordsData, GetAllResultsCallback callback)
1049 {
1050     ASSERT(isMainThread());
1051     LOG(IndexedDB, "(main) UniqueIDBDatabase::getAllRecords");
1052
1053     uint64_t callbackID = storeCallbackOrFireError(callback);
1054     if (!callbackID)
1055         return;
1056
1057     postDatabaseTask(createCrossThreadTask(*this, &UniqueIDBDatabase::performGetAllRecords, callbackID, requestData.transactionIdentifier(), getAllRecordsData));
1058 }
1059
1060 void UniqueIDBDatabase::performGetRecord(uint64_t callbackIdentifier, const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, const IDBKeyRangeData& keyRangeData)
1061 {
1062     ASSERT(!isMainThread());
1063     LOG(IndexedDB, "(db) UniqueIDBDatabase::performGetRecord");
1064
1065     ASSERT(m_backingStore);
1066
1067     IDBGetResult result;
1068     IDBError error = m_backingStore->getRecord(transactionIdentifier, objectStoreIdentifier, keyRangeData, result);
1069
1070     postDatabaseTaskReply(createCrossThreadTask(*this, &UniqueIDBDatabase::didPerformGetRecord, callbackIdentifier, error, result));
1071 }
1072
1073 void UniqueIDBDatabase::performGetIndexRecord(uint64_t callbackIdentifier, const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, uint64_t indexIdentifier, IndexedDB::IndexRecordType recordType, const IDBKeyRangeData& range)
1074 {
1075     ASSERT(!isMainThread());
1076     LOG(IndexedDB, "(db) UniqueIDBDatabase::performGetIndexRecord");
1077
1078     ASSERT(m_backingStore);
1079
1080     IDBGetResult result;
1081     IDBError error = m_backingStore->getIndexRecord(transactionIdentifier, objectStoreIdentifier, indexIdentifier, recordType, range, result);
1082
1083     postDatabaseTaskReply(createCrossThreadTask(*this, &UniqueIDBDatabase::didPerformGetRecord, callbackIdentifier, error, result));
1084 }
1085
1086 void UniqueIDBDatabase::didPerformGetRecord(uint64_t callbackIdentifier, const IDBError& error, const IDBGetResult& result)
1087 {
1088     ASSERT(isMainThread());
1089     LOG(IndexedDB, "(main) UniqueIDBDatabase::didPerformGetRecord");
1090
1091     performGetResultCallback(callbackIdentifier, error, result);
1092 }
1093
1094 void UniqueIDBDatabase::performGetAllRecords(uint64_t callbackIdentifier, const IDBResourceIdentifier& transactionIdentifier, const IDBGetAllRecordsData& getAllRecordsData)
1095 {
1096     ASSERT(!isMainThread());
1097     LOG(IndexedDB, "(db) UniqueIDBDatabase::performGetAllRecords");
1098
1099     ASSERT(m_backingStore);
1100
1101     IDBGetAllResult result;
1102     IDBError error = m_backingStore->getAllRecords(transactionIdentifier, getAllRecordsData, result);
1103
1104     postDatabaseTaskReply(createCrossThreadTask(*this, &UniqueIDBDatabase::didPerformGetAllRecords, callbackIdentifier, error, WTFMove(result)));
1105 }
1106
1107 void UniqueIDBDatabase::didPerformGetAllRecords(uint64_t callbackIdentifier, const IDBError& error, const IDBGetAllResult& result)
1108 {
1109     ASSERT(isMainThread());
1110     LOG(IndexedDB, "(main) UniqueIDBDatabase::didPerformGetAllRecords");
1111
1112     performGetAllResultsCallback(callbackIdentifier, error, result);
1113 }
1114
1115 void UniqueIDBDatabase::getCount(const IDBRequestData& requestData, const IDBKeyRangeData& range, CountCallback callback)
1116 {
1117     ASSERT(isMainThread());
1118     LOG(IndexedDB, "(main) UniqueIDBDatabase::getCount");
1119
1120     uint64_t callbackID = storeCallbackOrFireError(callback);
1121     if (!callbackID)
1122         return;
1123     postDatabaseTask(createCrossThreadTask(*this, &UniqueIDBDatabase::performGetCount, callbackID, requestData.transactionIdentifier(), requestData.objectStoreIdentifier(), requestData.indexIdentifier(), range));
1124 }
1125
1126 void UniqueIDBDatabase::performGetCount(uint64_t callbackIdentifier, const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, uint64_t indexIdentifier, const IDBKeyRangeData& keyRangeData)
1127 {
1128     ASSERT(!isMainThread());
1129     LOG(IndexedDB, "(db) UniqueIDBDatabase::performGetCount");
1130
1131     ASSERT(m_backingStore);
1132     ASSERT(objectStoreIdentifier);
1133
1134     uint64_t count;
1135     IDBError error = m_backingStore->getCount(transactionIdentifier, objectStoreIdentifier, indexIdentifier, keyRangeData, count);
1136
1137     postDatabaseTaskReply(createCrossThreadTask(*this, &UniqueIDBDatabase::didPerformGetCount, callbackIdentifier, error, count));
1138 }
1139
1140 void UniqueIDBDatabase::didPerformGetCount(uint64_t callbackIdentifier, const IDBError& error, uint64_t count)
1141 {
1142     ASSERT(isMainThread());
1143     LOG(IndexedDB, "(main) UniqueIDBDatabase::didPerformGetCount");
1144
1145     performCountCallback(callbackIdentifier, error, count);
1146 }
1147
1148 void UniqueIDBDatabase::deleteRecord(const IDBRequestData& requestData, const IDBKeyRangeData& keyRangeData, ErrorCallback callback)
1149 {
1150     ASSERT(isMainThread());
1151     LOG(IndexedDB, "(main) UniqueIDBDatabase::deleteRecord");
1152
1153     uint64_t callbackID = storeCallbackOrFireError(callback);
1154     if (!callbackID)
1155         return;
1156     postDatabaseTask(createCrossThreadTask(*this, &UniqueIDBDatabase::performDeleteRecord, callbackID, requestData.transactionIdentifier(), requestData.objectStoreIdentifier(), keyRangeData));
1157 }
1158
1159 void UniqueIDBDatabase::performDeleteRecord(uint64_t callbackIdentifier, const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, const IDBKeyRangeData& range)
1160 {
1161     ASSERT(!isMainThread());
1162     LOG(IndexedDB, "(db) UniqueIDBDatabase::performDeleteRecord");
1163
1164     IDBError error = m_backingStore->deleteRange(transactionIdentifier, objectStoreIdentifier, range);
1165
1166     postDatabaseTaskReply(createCrossThreadTask(*this, &UniqueIDBDatabase::didPerformDeleteRecord, callbackIdentifier, error));
1167 }
1168
1169 void UniqueIDBDatabase::didPerformDeleteRecord(uint64_t callbackIdentifier, const IDBError& error)
1170 {
1171     ASSERT(isMainThread());
1172     LOG(IndexedDB, "(main) UniqueIDBDatabase::didPerformDeleteRecord");
1173
1174     performErrorCallback(callbackIdentifier, error);
1175 }
1176
1177 void UniqueIDBDatabase::openCursor(const IDBRequestData& requestData, const IDBCursorInfo& info, GetResultCallback callback)
1178 {
1179     ASSERT(isMainThread());
1180     LOG(IndexedDB, "(main) UniqueIDBDatabase::openCursor");
1181
1182     uint64_t callbackID = storeCallbackOrFireError(callback);
1183     if (!callbackID)
1184         return;
1185     postDatabaseTask(createCrossThreadTask(*this, &UniqueIDBDatabase::performOpenCursor, callbackID, requestData.transactionIdentifier(), info));
1186 }
1187
1188 void UniqueIDBDatabase::performOpenCursor(uint64_t callbackIdentifier, const IDBResourceIdentifier& transactionIdentifier, const IDBCursorInfo& info)
1189 {
1190     ASSERT(!isMainThread());
1191     LOG(IndexedDB, "(db) UniqueIDBDatabase::performOpenCursor");
1192
1193     IDBGetResult result;
1194     IDBError error = m_backingStore->openCursor(transactionIdentifier, info, result);
1195
1196     postDatabaseTaskReply(createCrossThreadTask(*this, &UniqueIDBDatabase::didPerformOpenCursor, callbackIdentifier, error, result));
1197 }
1198
1199 void UniqueIDBDatabase::didPerformOpenCursor(uint64_t callbackIdentifier, const IDBError& error, const IDBGetResult& result)
1200 {
1201     ASSERT(isMainThread());
1202     LOG(IndexedDB, "(main) UniqueIDBDatabase::didPerformOpenCursor");
1203
1204     performGetResultCallback(callbackIdentifier, error, result);
1205 }
1206
1207 void UniqueIDBDatabase::iterateCursor(const IDBRequestData& requestData, const IDBIterateCursorData& data, GetResultCallback callback)
1208 {
1209     ASSERT(isMainThread());
1210     LOG(IndexedDB, "(main) UniqueIDBDatabase::iterateCursor");
1211
1212     uint64_t callbackID = storeCallbackOrFireError(callback);
1213     if (!callbackID)
1214         return;
1215     postDatabaseTask(createCrossThreadTask(*this, &UniqueIDBDatabase::performIterateCursor, callbackID, requestData.transactionIdentifier(), requestData.cursorIdentifier(), data));
1216 }
1217
1218 void UniqueIDBDatabase::performIterateCursor(uint64_t callbackIdentifier, const IDBResourceIdentifier& transactionIdentifier, const IDBResourceIdentifier& cursorIdentifier, const IDBIterateCursorData& data)
1219 {
1220     ASSERT(!isMainThread());
1221     LOG(IndexedDB, "(db) UniqueIDBDatabase::performIterateCursor");
1222
1223     IDBGetResult result;
1224     IDBError error = m_backingStore->iterateCursor(transactionIdentifier, cursorIdentifier, data, result);
1225
1226     postDatabaseTaskReply(createCrossThreadTask(*this, &UniqueIDBDatabase::didPerformIterateCursor, callbackIdentifier, error, result));
1227 }
1228
1229 void UniqueIDBDatabase::didPerformIterateCursor(uint64_t callbackIdentifier, const IDBError& error, const IDBGetResult& result)
1230 {
1231     ASSERT(isMainThread());
1232     LOG(IndexedDB, "(main) UniqueIDBDatabase::didPerformIterateCursor");
1233
1234     performGetResultCallback(callbackIdentifier, error, result);
1235 }
1236
1237 bool UniqueIDBDatabase::prepareToFinishTransaction(UniqueIDBDatabaseTransaction& transaction)
1238 {
1239     auto takenTransaction = m_inProgressTransactions.take(transaction.info().identifier());
1240     if (!takenTransaction)
1241         return false;
1242
1243     ASSERT(!m_finishingTransactions.contains(transaction.info().identifier()));
1244     m_finishingTransactions.set(transaction.info().identifier(), WTFMove(takenTransaction));
1245
1246     return true;
1247 }
1248
1249 void UniqueIDBDatabase::commitTransaction(UniqueIDBDatabaseTransaction& transaction, ErrorCallback callback)
1250 {
1251     ASSERT(isMainThread());
1252     LOG(IndexedDB, "(main) UniqueIDBDatabase::commitTransaction - %s", transaction.info().identifier().loggingString().utf8().data());
1253
1254     ASSERT(&transaction.databaseConnection().database() == this);
1255
1256     uint64_t callbackID = storeCallbackOrFireError(callback);
1257     if (!callbackID)
1258         return;
1259
1260     if (!prepareToFinishTransaction(transaction)) {
1261         if (!m_openDatabaseConnections.contains(&transaction.databaseConnection())) {
1262             // This database connection is closing or has already closed, so there is no point in messaging back to it about the commit failing.
1263             forgetErrorCallback(callbackID);
1264             return;
1265         }
1266
1267         performErrorCallback(callbackID, { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to commit transaction that is already finishing") });
1268         return;
1269     }
1270
1271     postDatabaseTask(createCrossThreadTask(*this, &UniqueIDBDatabase::performCommitTransaction, callbackID, transaction.info().identifier()));
1272 }
1273
1274 void UniqueIDBDatabase::performCommitTransaction(uint64_t callbackIdentifier, const IDBResourceIdentifier& transactionIdentifier)
1275 {
1276     ASSERT(!isMainThread());
1277     LOG(IndexedDB, "(db) UniqueIDBDatabase::performCommitTransaction - %s", transactionIdentifier.loggingString().utf8().data());
1278
1279     IDBError error = m_backingStore->commitTransaction(transactionIdentifier);
1280     postDatabaseTaskReply(createCrossThreadTask(*this, &UniqueIDBDatabase::didPerformCommitTransaction, callbackIdentifier, error, transactionIdentifier));
1281 }
1282
1283 void UniqueIDBDatabase::didPerformCommitTransaction(uint64_t callbackIdentifier, const IDBError& error, const IDBResourceIdentifier& transactionIdentifier)
1284 {
1285     ASSERT(isMainThread());
1286     LOG(IndexedDB, "(main) UniqueIDBDatabase::didPerformCommitTransaction - %s", transactionIdentifier.loggingString().utf8().data());
1287
1288     performErrorCallback(callbackIdentifier, error);
1289
1290     transactionCompleted(m_finishingTransactions.take(transactionIdentifier));
1291 }
1292
1293 void UniqueIDBDatabase::abortTransaction(UniqueIDBDatabaseTransaction& transaction, ErrorCallback callback)
1294 {
1295     ASSERT(isMainThread());
1296     LOG(IndexedDB, "(main) UniqueIDBDatabase::abortTransaction - %s", transaction.info().identifier().loggingString().utf8().data());
1297
1298     ASSERT(&transaction.databaseConnection().database() == this);
1299
1300     uint64_t callbackID = storeCallbackOrFireError(callback);
1301     if (!callbackID)
1302         return;
1303
1304     if (!prepareToFinishTransaction(transaction)) {
1305         if (!m_openDatabaseConnections.contains(&transaction.databaseConnection())) {
1306             // This database connection is closing or has already closed, so there is no point in messaging back to it about the abort failing.
1307             forgetErrorCallback(callbackID);
1308             return;
1309         }
1310
1311         performErrorCallback(callbackID, { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to abort transaction that is already finishing") });
1312         return;
1313     }
1314
1315     postDatabaseTask(createCrossThreadTask(*this, &UniqueIDBDatabase::performAbortTransaction, callbackID, transaction.info().identifier()));
1316 }
1317
1318 void UniqueIDBDatabase::didFinishHandlingVersionChange(UniqueIDBDatabaseConnection& connection, const IDBResourceIdentifier& transactionIdentifier)
1319 {
1320     ASSERT(isMainThread());
1321     LOG(IndexedDB, "(main) UniqueIDBDatabase::didFinishHandlingVersionChange");
1322
1323     ASSERT_UNUSED(transactionIdentifier, !m_versionChangeTransaction || m_versionChangeTransaction->info().identifier() == transactionIdentifier);
1324     ASSERT_UNUSED(connection, !m_versionChangeDatabaseConnection || m_versionChangeDatabaseConnection.get() == &connection);
1325
1326     m_versionChangeTransaction = nullptr;
1327     m_versionChangeDatabaseConnection = nullptr;
1328
1329     if (m_hardClosedForUserDelete) {
1330         maybeFinishHardClose();
1331         return;
1332     }
1333
1334     invokeOperationAndTransactionTimer();
1335 }
1336
1337 void UniqueIDBDatabase::performAbortTransaction(uint64_t callbackIdentifier, const IDBResourceIdentifier& transactionIdentifier)
1338 {
1339     ASSERT(!isMainThread());
1340     LOG(IndexedDB, "(db) UniqueIDBDatabase::performAbortTransaction - %s", transactionIdentifier.loggingString().utf8().data());
1341
1342     IDBError error = m_backingStore->abortTransaction(transactionIdentifier);
1343     postDatabaseTaskReply(createCrossThreadTask(*this, &UniqueIDBDatabase::didPerformAbortTransaction, callbackIdentifier, error, transactionIdentifier));
1344 }
1345
1346 void UniqueIDBDatabase::didPerformAbortTransaction(uint64_t callbackIdentifier, const IDBError& error, const IDBResourceIdentifier& transactionIdentifier)
1347 {
1348     ASSERT(isMainThread());
1349     LOG(IndexedDB, "(main) UniqueIDBDatabase::didPerformAbortTransaction - %s", transactionIdentifier.loggingString().utf8().data());
1350
1351     auto transaction = m_finishingTransactions.take(transactionIdentifier);
1352     ASSERT(transaction);
1353
1354     if (m_versionChangeTransaction && m_versionChangeTransaction->info().identifier() == transactionIdentifier) {
1355         ASSERT(m_versionChangeTransaction == transaction);
1356         ASSERT(!m_versionChangeDatabaseConnection || &m_versionChangeTransaction->databaseConnection() == m_versionChangeDatabaseConnection);
1357         ASSERT(m_versionChangeTransaction->originalDatabaseInfo());
1358         m_databaseInfo = std::make_unique<IDBDatabaseInfo>(*m_versionChangeTransaction->originalDatabaseInfo());
1359     }
1360
1361     performErrorCallback(callbackIdentifier, error);
1362
1363     transactionCompleted(WTFMove(transaction));
1364 }
1365
1366 void UniqueIDBDatabase::transactionDestroyed(UniqueIDBDatabaseTransaction& transaction)
1367 {
1368     if (m_versionChangeTransaction == &transaction)
1369         m_versionChangeTransaction = nullptr;
1370 }
1371
1372 void UniqueIDBDatabase::connectionClosedFromClient(UniqueIDBDatabaseConnection& connection)
1373 {
1374     ASSERT(isMainThread());
1375     LOG(IndexedDB, "(main) UniqueIDBDatabase::connectionClosedFromClient - %s (%" PRIu64 ")", connection.openRequestIdentifier().loggingString().utf8().data(), connection.identifier());
1376
1377     Ref<UniqueIDBDatabaseConnection> protectedConnection(connection);
1378     m_openDatabaseConnections.remove(&connection);
1379
1380     if (m_versionChangeDatabaseConnection == &connection) {
1381         if (m_versionChangeTransaction) {
1382             m_clientClosePendingDatabaseConnections.add(WTFMove(m_versionChangeDatabaseConnection));
1383
1384             auto transactionIdentifier = m_versionChangeTransaction->info().identifier();
1385             if (m_inProgressTransactions.contains(transactionIdentifier)) {
1386                 ASSERT(!m_finishingTransactions.contains(transactionIdentifier));
1387                 connection.abortTransactionWithoutCallback(*m_versionChangeTransaction);
1388             }
1389
1390             return;
1391         }
1392
1393         m_versionChangeDatabaseConnection = nullptr;
1394     }
1395
1396     Deque<RefPtr<UniqueIDBDatabaseTransaction>> pendingTransactions;
1397     while (!m_pendingTransactions.isEmpty()) {
1398         auto transaction = m_pendingTransactions.takeFirst();
1399         if (&transaction->databaseConnection() != &connection)
1400             pendingTransactions.append(WTFMove(transaction));
1401     }
1402
1403     if (!pendingTransactions.isEmpty())
1404         m_pendingTransactions.swap(pendingTransactions);
1405
1406     Deque<RefPtr<UniqueIDBDatabaseTransaction>> transactionsToAbort;
1407     for (auto& transaction : m_inProgressTransactions.values()) {
1408         if (&transaction->databaseConnection() == &connection)
1409             transactionsToAbort.append(transaction);
1410     }
1411
1412     for (auto& transaction : transactionsToAbort)
1413         transaction->abortWithoutCallback();
1414
1415     if (m_currentOpenDBRequest)
1416         notifyCurrentRequestConnectionClosedOrFiredVersionChangeEvent(connection.identifier());
1417
1418     if (connection.hasNonFinishedTransactions()) {
1419         m_clientClosePendingDatabaseConnections.add(WTFMove(protectedConnection));
1420         return;
1421     }
1422
1423     if (m_hardClosedForUserDelete) {
1424         maybeFinishHardClose();
1425         return;
1426     }
1427
1428     // Now that a database connection has closed, previously blocked operations might be runnable.
1429     invokeOperationAndTransactionTimer();
1430 }
1431
1432 void UniqueIDBDatabase::connectionClosedFromServer(UniqueIDBDatabaseConnection& connection)
1433 {
1434     ASSERT(isMainThread());
1435     LOG(IndexedDB, "UniqueIDBDatabase::connectionClosedFromServer - %s (%" PRIu64 ")", connection.openRequestIdentifier().loggingString().utf8().data(), connection.identifier());
1436
1437     if (m_clientClosePendingDatabaseConnections.contains(&connection)) {
1438         ASSERT(!m_openDatabaseConnections.contains(&connection));
1439         ASSERT(!m_serverClosePendingDatabaseConnections.contains(&connection));
1440         return;
1441     }
1442
1443     Ref<UniqueIDBDatabaseConnection> protectedConnection(connection);
1444     m_openDatabaseConnections.remove(&connection);
1445
1446     connection.connectionToClient().didCloseFromServer(connection, IDBError::userDeleteError());
1447
1448     m_serverClosePendingDatabaseConnections.add(WTFMove(protectedConnection));
1449 }
1450
1451 void UniqueIDBDatabase::confirmDidCloseFromServer(UniqueIDBDatabaseConnection& connection)
1452 {
1453     ASSERT(isMainThread());
1454     LOG(IndexedDB, "UniqueIDBDatabase::confirmDidCloseFromServer - %s (%" PRIu64 ")", connection.openRequestIdentifier().loggingString().utf8().data(), connection.identifier());
1455
1456     ASSERT(m_serverClosePendingDatabaseConnections.contains(&connection));
1457     m_serverClosePendingDatabaseConnections.remove(&connection);
1458 }
1459
1460 void UniqueIDBDatabase::enqueueTransaction(Ref<UniqueIDBDatabaseTransaction>&& transaction)
1461 {
1462     LOG(IndexedDB, "UniqueIDBDatabase::enqueueTransaction - %s", transaction->info().loggingString().utf8().data());
1463     ASSERT(!m_hardClosedForUserDelete);
1464
1465     ASSERT(transaction->info().mode() != IDBTransactionMode::Versionchange);
1466
1467     m_pendingTransactions.append(WTFMove(transaction));
1468
1469     invokeOperationAndTransactionTimer();
1470 }
1471
1472 bool UniqueIDBDatabase::isCurrentlyInUse() const
1473 {
1474     return !m_openDatabaseConnections.isEmpty() || !m_clientClosePendingDatabaseConnections.isEmpty() || !m_pendingOpenDBRequests.isEmpty() || m_currentOpenDBRequest || m_versionChangeDatabaseConnection || m_versionChangeTransaction || m_isOpeningBackingStore || m_deleteBackingStoreInProgress;
1475 }
1476
1477 bool UniqueIDBDatabase::hasUnfinishedTransactions() const
1478 {
1479     return !m_inProgressTransactions.isEmpty() || !m_finishingTransactions.isEmpty();
1480 }
1481
1482 void UniqueIDBDatabase::invokeOperationAndTransactionTimer()
1483 {
1484     LOG(IndexedDB, "UniqueIDBDatabase::invokeOperationAndTransactionTimer()");
1485     ASSERT(!m_hardClosedForUserDelete);
1486
1487     if (!m_operationAndTransactionTimer.isActive())
1488         m_operationAndTransactionTimer.startOneShot(0);
1489 }
1490
1491 void UniqueIDBDatabase::operationAndTransactionTimerFired()
1492 {
1493     LOG(IndexedDB, "(main) UniqueIDBDatabase::operationAndTransactionTimerFired");
1494     ASSERT(!m_hardClosedForUserDelete);
1495
1496     RefPtr<UniqueIDBDatabase> protectedThis(this);
1497
1498     // This UniqueIDBDatabase might be no longer in use by any web page.
1499     // Assuming it is not ephemeral, the server should now close it to free up resources.
1500     if (!m_backingStoreIsEphemeral && !isCurrentlyInUse()) {
1501         ASSERT(m_pendingTransactions.isEmpty());
1502         ASSERT(!hasUnfinishedTransactions());
1503         m_server.closeUniqueIDBDatabase(*this);
1504         return;
1505     }
1506
1507     // The current operation might require multiple attempts to handle, so try to
1508     // make further progress on it now.
1509     if (m_currentOpenDBRequest)
1510         handleCurrentOperation();
1511
1512     if (!m_currentOpenDBRequest)
1513         handleDatabaseOperations();
1514
1515     bool hadDeferredTransactions = false;
1516     auto transaction = takeNextRunnableTransaction(hadDeferredTransactions);
1517
1518     if (transaction) {
1519         m_inProgressTransactions.set(transaction->info().identifier(), transaction);
1520         for (auto objectStore : transaction->objectStoreIdentifiers()) {
1521             m_objectStoreTransactionCounts.add(objectStore);
1522             if (!transaction->isReadOnly()) {
1523                 m_objectStoreWriteTransactions.add(objectStore);
1524                 ASSERT(m_objectStoreTransactionCounts.count(objectStore) == 1);
1525             }
1526         }
1527
1528         activateTransactionInBackingStore(*transaction);
1529
1530         // If no transactions were deferred, it's possible we can start another transaction right now.
1531         if (!hadDeferredTransactions)
1532             invokeOperationAndTransactionTimer();
1533     }
1534 }
1535
1536 void UniqueIDBDatabase::activateTransactionInBackingStore(UniqueIDBDatabaseTransaction& transaction)
1537 {
1538     LOG(IndexedDB, "(main) UniqueIDBDatabase::activateTransactionInBackingStore");
1539
1540     RefPtr<UniqueIDBDatabase> protectedThis(this);
1541     RefPtr<UniqueIDBDatabaseTransaction> refTransaction(&transaction);
1542
1543     auto callback = [this, protectedThis, refTransaction](const IDBError& error) {
1544         refTransaction->didActivateInBackingStore(error);
1545     };
1546
1547     uint64_t callbackID = storeCallbackOrFireError(callback);
1548     if (!callbackID)
1549         return;
1550     postDatabaseTask(createCrossThreadTask(*this, &UniqueIDBDatabase::performActivateTransactionInBackingStore, callbackID, transaction.info()));
1551 }
1552
1553 void UniqueIDBDatabase::performActivateTransactionInBackingStore(uint64_t callbackIdentifier, const IDBTransactionInfo& info)
1554 {
1555     LOG(IndexedDB, "(db) UniqueIDBDatabase::performActivateTransactionInBackingStore");
1556
1557     IDBError error = m_backingStore->beginTransaction(info);
1558     postDatabaseTaskReply(createCrossThreadTask(*this, &UniqueIDBDatabase::didPerformActivateTransactionInBackingStore, callbackIdentifier, error));
1559 }
1560
1561 void UniqueIDBDatabase::didPerformActivateTransactionInBackingStore(uint64_t callbackIdentifier, const IDBError& error)
1562 {
1563     LOG(IndexedDB, "(main) UniqueIDBDatabase::didPerformActivateTransactionInBackingStore");
1564
1565     invokeOperationAndTransactionTimer();
1566
1567     performErrorCallback(callbackIdentifier, error);
1568 }
1569
1570 template<typename T> bool scopesOverlap(const T& aScopes, const Vector<uint64_t>& bScopes)
1571 {
1572     for (auto scope : bScopes) {
1573         if (aScopes.contains(scope))
1574             return true;
1575     }
1576
1577     return false;
1578 }
1579
1580 RefPtr<UniqueIDBDatabaseTransaction> UniqueIDBDatabase::takeNextRunnableTransaction(bool& hadDeferredTransactions)
1581 {
1582     hadDeferredTransactions = false;
1583
1584     if (m_pendingTransactions.isEmpty())
1585         return nullptr;
1586
1587     if (!m_backingStoreSupportsSimultaneousTransactions && hasUnfinishedTransactions()) {
1588         LOG(IndexedDB, "UniqueIDBDatabase::takeNextRunnableTransaction - Backing store only supports 1 transaction, and we already have 1");
1589         return nullptr;
1590     }
1591
1592     Deque<RefPtr<UniqueIDBDatabaseTransaction>> deferredTransactions;
1593     RefPtr<UniqueIDBDatabaseTransaction> currentTransaction;
1594
1595     HashSet<uint64_t> deferredReadWriteScopes;
1596
1597     while (!m_pendingTransactions.isEmpty()) {
1598         currentTransaction = m_pendingTransactions.takeFirst();
1599
1600         switch (currentTransaction->info().mode()) {
1601         case IDBTransactionMode::Readonly: {
1602             bool hasOverlappingScopes = scopesOverlap(deferredReadWriteScopes, currentTransaction->objectStoreIdentifiers());
1603             hasOverlappingScopes |= scopesOverlap(m_objectStoreWriteTransactions, currentTransaction->objectStoreIdentifiers());
1604
1605             if (hasOverlappingScopes)
1606                 deferredTransactions.append(WTFMove(currentTransaction));
1607
1608             break;
1609         }
1610         case IDBTransactionMode::Readwrite: {
1611             bool hasOverlappingScopes = scopesOverlap(m_objectStoreTransactionCounts, currentTransaction->objectStoreIdentifiers());
1612             hasOverlappingScopes |= scopesOverlap(deferredReadWriteScopes, currentTransaction->objectStoreIdentifiers());
1613
1614             if (hasOverlappingScopes) {
1615                 for (auto objectStore : currentTransaction->objectStoreIdentifiers())
1616                     deferredReadWriteScopes.add(objectStore);
1617                 deferredTransactions.append(WTFMove(currentTransaction));
1618             }
1619
1620             break;
1621         }
1622         case IDBTransactionMode::Versionchange:
1623             // Version change transactions should never be scheduled in the traditional manner.
1624             RELEASE_ASSERT_NOT_REACHED();
1625         }
1626
1627         // If we didn't defer the currentTransaction above, it can be run now.
1628         if (currentTransaction)
1629             break;
1630     }
1631
1632     hadDeferredTransactions = !deferredTransactions.isEmpty();
1633     if (!hadDeferredTransactions)
1634         return currentTransaction;
1635
1636     // Prepend the deferred transactions back on the beginning of the deque for future scheduling passes.
1637     while (!deferredTransactions.isEmpty())
1638         m_pendingTransactions.prepend(deferredTransactions.takeLast());
1639
1640     return currentTransaction;
1641 }
1642
1643 void UniqueIDBDatabase::transactionCompleted(RefPtr<UniqueIDBDatabaseTransaction>&& transaction)
1644 {
1645     ASSERT(transaction);
1646     ASSERT(!m_inProgressTransactions.contains(transaction->info().identifier()));
1647     ASSERT(!m_finishingTransactions.contains(transaction->info().identifier()));
1648
1649     for (auto objectStore : transaction->objectStoreIdentifiers()) {
1650         if (!transaction->isReadOnly()) {
1651             m_objectStoreWriteTransactions.remove(objectStore);
1652             ASSERT(m_objectStoreTransactionCounts.count(objectStore) == 1);
1653         }
1654         m_objectStoreTransactionCounts.remove(objectStore);
1655     }
1656
1657     if (!transaction->databaseConnection().hasNonFinishedTransactions())
1658         m_clientClosePendingDatabaseConnections.remove(&transaction->databaseConnection());
1659
1660     if (m_versionChangeTransaction == transaction)
1661         m_versionChangeTransaction = nullptr;
1662
1663     // It's possible that this database had its backing store deleted but there were a few outstanding asynchronous operations.
1664     // If this transaction completing was the last of those operations, we can finally delete this UniqueIDBDatabase.
1665     if (m_clientClosePendingDatabaseConnections.isEmpty() && m_pendingOpenDBRequests.isEmpty() && !m_databaseInfo) {
1666         m_server.closeUniqueIDBDatabase(*this);
1667         return;
1668     }
1669
1670     // Previously blocked operations might be runnable.
1671     if (!m_hardClosedForUserDelete)
1672         invokeOperationAndTransactionTimer();
1673     else
1674         maybeFinishHardClose();
1675 }
1676
1677 void UniqueIDBDatabase::postDatabaseTask(CrossThreadTask&& task)
1678 {
1679     ASSERT(isMainThread());
1680     m_databaseQueue.append(WTFMove(task));
1681     ++m_queuedTaskCount;
1682
1683     m_server.postDatabaseTask(createCrossThreadTask(*this, &UniqueIDBDatabase::executeNextDatabaseTask));
1684 }
1685
1686 void UniqueIDBDatabase::postDatabaseTaskReply(CrossThreadTask&& task)
1687 {
1688     ASSERT(!isMainThread());
1689     m_databaseReplyQueue.append(WTFMove(task));
1690     ++m_queuedTaskCount;
1691
1692     m_server.postDatabaseTaskReply(createCrossThreadTask(*this, &UniqueIDBDatabase::executeNextDatabaseTaskReply));
1693 }
1694
1695 void UniqueIDBDatabase::executeNextDatabaseTask()
1696 {
1697     ASSERT(!isMainThread());
1698     ASSERT(m_queuedTaskCount);
1699
1700     auto task = m_databaseQueue.tryGetMessage();
1701     ASSERT(task);
1702
1703     // Performing the task might end up removing the last reference to this.
1704     Ref<UniqueIDBDatabase> protectedThis(*this);
1705
1706     task->performTask();
1707     --m_queuedTaskCount;
1708
1709     // Release the ref in the main thread to ensure it's deleted there as expected in case of being the last reference.
1710     callOnMainThread([protectedThis = WTFMove(protectedThis)] {
1711     });
1712 }
1713
1714 void UniqueIDBDatabase::executeNextDatabaseTaskReply()
1715 {
1716     ASSERT(isMainThread());
1717     ASSERT(m_queuedTaskCount);
1718
1719     auto task = m_databaseReplyQueue.tryGetMessage();
1720     ASSERT(task);
1721
1722     // Performing the task might end up removing the last reference to this.
1723     Ref<UniqueIDBDatabase> protectedThis(*this);
1724
1725     task->performTask();
1726     --m_queuedTaskCount;
1727
1728     // If this database was force closed (e.g. for a user delete) and there are no more
1729     // cleanup tasks left, delete this.
1730     maybeFinishHardClose();
1731 }
1732
1733 void UniqueIDBDatabase::maybeFinishHardClose()
1734 {
1735     if (m_hardCloseProtector && isDoneWithHardClose()) {
1736         callOnMainThread([this] {
1737             ASSERT(isDoneWithHardClose());
1738             m_hardCloseProtector = nullptr;
1739         });
1740     }
1741 }
1742
1743 bool UniqueIDBDatabase::isDoneWithHardClose()
1744 {
1745     return !m_queuedTaskCount && m_clientClosePendingDatabaseConnections.isEmpty() && m_serverClosePendingDatabaseConnections.isEmpty();
1746 }
1747
1748 static void errorOpenDBRequestForUserDelete(ServerOpenDBRequest& request)
1749 {
1750     auto result = IDBResultData::error(request.requestData().requestIdentifier(), IDBError::userDeleteError());
1751     if (request.isOpenRequest())
1752         request.connection().didOpenDatabase(result);
1753     else
1754         request.connection().didDeleteDatabase(result);
1755 }
1756
1757 void UniqueIDBDatabase::immediateCloseForUserDelete()
1758 {
1759     LOG(IndexedDB, "UniqueIDBDatabase::immediateCloseForUserDelete - Cancelling (%i, %i, %i, %i) callbacks", m_errorCallbacks.size(), m_keyDataCallbacks.size(), m_getResultCallbacks.size(), m_countCallbacks.size());
1760
1761     // Error out all transactions
1762     Vector<IDBResourceIdentifier> inProgressIdentifiers;
1763     copyKeysToVector(m_inProgressTransactions, inProgressIdentifiers);
1764     for (auto& identifier : inProgressIdentifiers)
1765         m_inProgressTransactions.get(identifier)->abortWithoutCallback();
1766
1767     ASSERT(m_inProgressTransactions.isEmpty());
1768
1769     m_pendingTransactions.clear();
1770     m_objectStoreTransactionCounts.clear();
1771     m_objectStoreWriteTransactions.clear();
1772
1773     // Error out all pending callbacks
1774     Vector<uint64_t> callbackIdentifiers;
1775     IDBError error = IDBError::userDeleteError();
1776     IDBKeyData keyData;
1777     IDBGetResult getResult;
1778
1779     copyKeysToVector(m_errorCallbacks, callbackIdentifiers);
1780     for (auto identifier : callbackIdentifiers)
1781         performErrorCallback(identifier, error);
1782
1783     callbackIdentifiers.clear();
1784     copyKeysToVector(m_keyDataCallbacks, callbackIdentifiers);
1785     for (auto identifier : callbackIdentifiers)
1786         performKeyDataCallback(identifier, error, keyData);
1787
1788     callbackIdentifiers.clear();
1789     copyKeysToVector(m_getResultCallbacks, callbackIdentifiers);
1790     for (auto identifier : callbackIdentifiers)
1791         performGetResultCallback(identifier, error, getResult);
1792
1793     callbackIdentifiers.clear();
1794     copyKeysToVector(m_countCallbacks, callbackIdentifiers);
1795     for (auto identifier : callbackIdentifiers)
1796         performCountCallback(identifier, error, 0);
1797
1798     // Error out all IDBOpenDBRequests
1799     if (m_currentOpenDBRequest) {
1800         errorOpenDBRequestForUserDelete(*m_currentOpenDBRequest);
1801         m_currentOpenDBRequest = nullptr;
1802     }
1803
1804     for (auto& request : m_pendingOpenDBRequests)
1805         errorOpenDBRequestForUserDelete(*request);
1806
1807     m_pendingOpenDBRequests.clear();
1808
1809     // Close all open connections
1810     ListHashSet<RefPtr<UniqueIDBDatabaseConnection>> openDatabaseConnections = m_openDatabaseConnections;
1811     for (auto& connection : openDatabaseConnections)
1812         connectionClosedFromServer(*connection);
1813
1814     // Cancel the operation timer
1815     m_operationAndTransactionTimer.stop();
1816
1817     // Set up the database to remain alive-but-inert until all of its background activity finishes and all
1818     // database connections confirm that they have closed.
1819     m_hardClosedForUserDelete = true;
1820     m_hardCloseProtector = this;
1821
1822     // Have the database unconditionally delete itself on the database task queue.
1823     postDatabaseTask(createCrossThreadTask(*this, &UniqueIDBDatabase::performUnconditionalDeleteBackingStore));
1824
1825     // Remove the database from the IDBServer's set of open databases.
1826     // If there is no in-progress background thread activity for this database, it will be deleted here.
1827     m_server.closeUniqueIDBDatabase(*this);
1828 }
1829
1830 void UniqueIDBDatabase::performErrorCallback(uint64_t callbackIdentifier, const IDBError& error)
1831 {
1832     auto callback = m_errorCallbacks.take(callbackIdentifier);
1833     ASSERT(callback || m_hardClosedForUserDelete);
1834     if (callback)
1835         callback(error);
1836 }
1837
1838 void UniqueIDBDatabase::performKeyDataCallback(uint64_t callbackIdentifier, const IDBError& error, const IDBKeyData& resultKey)
1839 {
1840     auto callback = m_keyDataCallbacks.take(callbackIdentifier);
1841     ASSERT(callback || m_hardClosedForUserDelete);
1842     if (callback)
1843         callback(error, resultKey);
1844 }
1845
1846 void UniqueIDBDatabase::performGetResultCallback(uint64_t callbackIdentifier, const IDBError& error, const IDBGetResult& resultData)
1847 {
1848     auto callback = m_getResultCallbacks.take(callbackIdentifier);
1849     ASSERT(callback || m_hardClosedForUserDelete);
1850     if (callback)
1851         callback(error, resultData);
1852 }
1853
1854 void UniqueIDBDatabase::performGetAllResultsCallback(uint64_t callbackIdentifier, const IDBError& error, const IDBGetAllResult& resultData)
1855 {
1856     auto callback = m_getAllResultsCallbacks.take(callbackIdentifier);
1857     ASSERT(callback || m_hardClosedForUserDelete);
1858     if (callback)
1859         callback(error, resultData);
1860 }
1861
1862 void UniqueIDBDatabase::performCountCallback(uint64_t callbackIdentifier, const IDBError& error, uint64_t count)
1863 {
1864     auto callback = m_countCallbacks.take(callbackIdentifier);
1865     ASSERT(callback || m_hardClosedForUserDelete);
1866     if (callback)
1867         callback(error, count);
1868 }
1869
1870 void UniqueIDBDatabase::forgetErrorCallback(uint64_t callbackIdentifier)
1871 {
1872     ASSERT(m_errorCallbacks.contains(callbackIdentifier));
1873     m_errorCallbacks.remove(callbackIdentifier);
1874 }
1875
1876 } // namespace IDBServer
1877 } // namespace WebCore
1878
1879 #endif // ENABLE(INDEXED_DATABASE)