void UniqueIDBDatabase::handleOpenDatabaseOperations() { ASSERT(isMainThread()); LOG(IndexedDB, "(main) UniqueIDBDatabase::handleOpenDatabaseOperations"); // If a version change transaction is currently in progress, no new connections can be opened right now. // We will try again later. if (m_versionChangeDatabaseConnection) return; auto operation = m_pendingOpenDatabaseOperations.takeFirst(); // 3.3.1 Opening a database // If requested version is undefined, then let requested version be 1 if db was created in the previous step, // or the current version of db otherwise. uint64_t requestedVersion = operation->requestData().requestedVersion(); if (!requestedVersion) requestedVersion = m_databaseInfo->version() ? m_databaseInfo->version() : 1; // 3.3.1 Opening a database // If the database version higher than the requested version, abort these steps and return a VersionError. if (requestedVersion < m_databaseInfo->version()) { auto result = IDBResultData::error(operation->requestData().requestIdentifier(), IDBError(IDBExceptionCode::VersionError)); operation->connection().didOpenDatabase(result); return; } Ref<UniqueIDBDatabaseConnection> connection = UniqueIDBDatabaseConnection::create(*this, operation->connection()); UniqueIDBDatabaseConnection* rawConnection = &connection.get(); m_server.registerDatabaseConnection(*rawConnection); if (requestedVersion == m_databaseInfo->version()) { addOpenDatabaseConnection(WTF::move(connection)); auto result = IDBResultData::openDatabaseSuccess(operation->requestData().requestIdentifier(), *rawConnection); operation->connection().didOpenDatabase(result); return; } ASSERT(!m_versionChangeOperation); ASSERT(!m_versionChangeDatabaseConnection); m_versionChangeOperation = adoptRef(operation.leakRef()); m_versionChangeDatabaseConnection = rawConnection; // 3.3.7 "versionchange" transaction steps // If there's no other open connections to this database, the version change process can begin immediately. if (!hasAnyOpenConnections()) { startVersionChangeTransaction(); return; } // Otherwise we have to notify all those open connections and wait for them to close. notifyConnectionsOfVersionChange(); }
void UniqueIDBDatabase::startVersionChangeTransaction() { LOG(IndexedDB, "(main) UniqueIDBDatabase::startVersionChangeTransaction"); ASSERT(!m_versionChangeTransaction); ASSERT(m_versionChangeOperation); ASSERT(m_versionChangeDatabaseConnection); auto operation = m_versionChangeOperation; m_versionChangeOperation = nullptr; uint64_t requestedVersion = operation->requestData().requestedVersion(); if (!requestedVersion) requestedVersion = m_databaseInfo->version() ? m_databaseInfo->version() : 1; addOpenDatabaseConnection(*m_versionChangeDatabaseConnection); m_versionChangeTransaction = &m_versionChangeDatabaseConnection->createVersionChangeTransaction(requestedVersion); auto result = IDBResultData::openDatabaseUpgradeNeeded(operation->requestData().requestIdentifier(), *m_versionChangeTransaction); operation->connection().didOpenDatabase(result); }
void UniqueIDBDatabase::startVersionChangeTransaction() { LOG(IndexedDB, "(main) UniqueIDBDatabase::startVersionChangeTransaction"); ASSERT(!m_versionChangeTransaction); ASSERT(m_versionChangeOperation); ASSERT(m_versionChangeDatabaseConnection); auto operation = m_versionChangeOperation; m_versionChangeOperation = nullptr; uint64_t requestedVersion = operation->requestData().requestedVersion(); if (!requestedVersion) requestedVersion = m_databaseInfo->version() ? m_databaseInfo->version() : 1; addOpenDatabaseConnection(*m_versionChangeDatabaseConnection); m_versionChangeTransaction = &m_versionChangeDatabaseConnection->createVersionChangeTransaction(requestedVersion); m_inProgressTransactions.set(m_versionChangeTransaction->info().identifier(), m_versionChangeTransaction); m_server.postDatabaseTask(createCrossThreadTask(*this, &UniqueIDBDatabase::beginTransactionInBackingStore, m_versionChangeTransaction->info())); auto result = IDBResultData::openDatabaseUpgradeNeeded(operation->requestData().requestIdentifier(), *m_versionChangeTransaction); operation->connection().didOpenDatabase(result); }