void IDBTransaction::transitionedToFinishing(IndexedDB::TransactionState state) { ASSERT(!isFinishedOrFinishing()); m_state = state; ASSERT(isFinishedOrFinishing()); m_referencedObjectStores.clear(); }
void IDBTransaction::activate() { if (isFinishedOrFinishing()) return; m_state = IndexedDB::TransactionState::Active; }
void IDBTransaction::abortDueToFailedRequest(DOMError& error) { LOG(IndexedDB, "IDBTransaction::abortDueToFailedRequest"); if (isFinishedOrFinishing()) return; m_domError = &error; ExceptionCodeWithMessage ec; abort(ec); }
void IDBTransaction::commit() { LOG(IndexedDB, "IDBTransaction::commit"); ASSERT(!isFinishedOrFinishing()); transitionedToFinishing(IndexedDB::TransactionState::Committing); m_database->willCommitTransaction(*this); auto operation = createTransactionOperation(*this, nullptr, &IDBTransaction::commitOnServer); scheduleOperation(WTFMove(operation)); }
void IDBTransaction::abort(ExceptionCode& ec) { LOG(IndexedDB, "IDBTransaction::abort"); if (isFinishedOrFinishing()) { ec = INVALID_STATE_ERR; return; } m_state = IndexedDB::TransactionState::Aborting; m_database->willAbortTransaction(*this); auto operation = createTransactionOperation(*this, nullptr, &IDBTransaction::abortOnServer); scheduleOperation(WTF::move(operation)); }
void IDBTransaction::stop() { LOG(IndexedDB, "IDBTransaction::stop"); // IDBDatabase::stop() calls IDBTransaction::stop() for each of its active transactions. // Since the order of calling ActiveDOMObject::stop() is random, we might already have been stopped. if (m_contextStopped) return; m_contextStopped = true; if (isFinishedOrFinishing()) return; ExceptionCodeWithMessage ec; abort(ec); }
RefPtr<WebCore::IDBObjectStore> IDBTransaction::objectStore(const String& objectStoreName, ExceptionCode& ec) { LOG(IndexedDB, "IDBTransaction::objectStore"); if (objectStoreName.isEmpty()) { ec = NOT_FOUND_ERR; return nullptr; } if (isFinishedOrFinishing()) { ec = INVALID_STATE_ERR; return nullptr; } auto iterator = m_referencedObjectStores.find(objectStoreName); if (iterator != m_referencedObjectStores.end()) return iterator->value; bool found = false; for (auto& objectStore : m_info.objectStores()) { if (objectStore == objectStoreName) { found = true; break; } } auto* info = m_database->info().infoForExistingObjectStore(objectStoreName); if (!info) { ec = NOT_FOUND_ERR; return nullptr; } // Version change transactions are scoped to every object store in the database. if (!found && !isVersionChange()) { ec = NOT_FOUND_ERR; return nullptr; } auto objectStore = IDBObjectStore::create(*info, *this); m_referencedObjectStores.set(objectStoreName, &objectStore.get()); return adoptRef(&objectStore.leakRef()); }
void IDBTransaction::operationTimerFired() { LOG(IndexedDB, "IDBTransaction::operationTimerFired (%p)", this); if (!m_startedOnServer) return; if (!m_transactionOperationQueue.isEmpty()) { auto operation = m_transactionOperationQueue.takeFirst(); operation->perform(); return; } if (!m_transactionOperationMap.isEmpty() || !m_openRequests.isEmpty()) return; if (!isFinishedOrFinishing()) commit(); }
RefPtr<WebCore::IDBObjectStore> IDBTransaction::objectStore(const String& objectStoreName, ExceptionCodeWithMessage& ec) { LOG(IndexedDB, "IDBTransaction::objectStore"); if (isFinishedOrFinishing()) { ec.code = IDBDatabaseException::InvalidStateError; ec.message = ASCIILiteral("Failed to execute 'objectStore' on 'IDBTransaction': The transaction finished."); return nullptr; } auto iterator = m_referencedObjectStores.find(objectStoreName); if (iterator != m_referencedObjectStores.end()) return iterator->value; bool found = false; for (auto& objectStore : m_info.objectStores()) { if (objectStore == objectStoreName) { found = true; break; } } auto* info = m_database->info().infoForExistingObjectStore(objectStoreName); if (!info) { ec.code = IDBDatabaseException::NotFoundError; ec.message = ASCIILiteral("Failed to execute 'objectStore' on 'IDBTransaction': The specified object store was not found."); return nullptr; } // Version change transactions are scoped to every object store in the database. if (!info || (!found && !isVersionChange())) { ec.code = IDBDatabaseException::NotFoundError; ec.message = ASCIILiteral("Failed to execute 'objectStore' on 'IDBTransaction': The specified object store was not found."); return nullptr; } auto objectStore = IDBObjectStore::create(*info, *this); m_referencedObjectStores.set(objectStoreName, &objectStore.get()); return adoptRef(&objectStore.leakRef()); }
void IDBTransaction::abort(ExceptionCodeWithMessage& ec) { LOG(IndexedDB, "IDBTransaction::abort"); if (isFinishedOrFinishing()) { ec.code = IDBDatabaseException::InvalidStateError; ec.message = ASCIILiteral("Failed to execute 'abort' on 'IDBTransaction': The transaction is inactive or finished."); return; } m_state = IndexedDB::TransactionState::Aborting; m_database->willAbortTransaction(*this); if (isVersionChange()) { for (auto& objectStore : m_referencedObjectStores.values()) objectStore->rollbackInfoForVersionChangeAbort(); } m_abortQueue.swap(m_transactionOperationQueue); auto operation = createTransactionOperation(*this, nullptr, &IDBTransaction::abortOnServerAndCancelRequests); scheduleOperation(WTFMove(operation)); }