mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-07-29 12:19:54 +00:00
LibWeb/IDB: Implement IDBTransaction::commit
This commit is contained in:
parent
b6b00acbd1
commit
da56c1b1eb
Notes:
github-actions[bot]
2025-04-11 01:14:15 +00:00
Author: https://github.com/stelar7
Commit: da56c1b1eb
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/4306
Reviewed-by: https://github.com/ADKaster ✅
5 changed files with 77 additions and 1 deletions
|
@ -14,6 +14,7 @@
|
|||
#include <LibJS/Runtime/VM.h>
|
||||
#include <LibWeb/DOM/EventDispatcher.h>
|
||||
#include <LibWeb/HTML/EventNames.h>
|
||||
#include <LibWeb/HTML/Scripting/TemporaryExecutionContext.h>
|
||||
#include <LibWeb/IndexedDB/IDBDatabase.h>
|
||||
#include <LibWeb/IndexedDB/IDBRequest.h>
|
||||
#include <LibWeb/IndexedDB/IDBTransaction.h>
|
||||
|
@ -22,6 +23,7 @@
|
|||
#include <LibWeb/IndexedDB/Internal/ConnectionQueueHandler.h>
|
||||
#include <LibWeb/IndexedDB/Internal/Database.h>
|
||||
#include <LibWeb/Infra/Strings.h>
|
||||
#include <LibWeb/Platform/EventLoopPlugin.h>
|
||||
#include <LibWeb/StorageAPI/StorageKey.h>
|
||||
#include <LibWeb/WebIDL/AbstractOperations.h>
|
||||
#include <LibWeb/WebIDL/Buffers.h>
|
||||
|
@ -706,4 +708,60 @@ GC::Ref<HTML::DOMStringList> create_a_sorted_name_list(JS::Realm& realm, Vector<
|
|||
return HTML::DOMStringList::create(realm, names);
|
||||
}
|
||||
|
||||
// https://w3c.github.io/IndexedDB/#commit-a-transaction
|
||||
void commit_a_transaction(JS::Realm& realm, GC::Ref<IDBTransaction> transaction)
|
||||
{
|
||||
// 1. Set transaction’s state to committing.
|
||||
transaction->set_state(IDBTransaction::TransactionState::Committing);
|
||||
|
||||
dbgln_if(IDB_DEBUG, "commit_a_transaction: transaction {} is committing", transaction->uuid());
|
||||
|
||||
// 2. Run the following steps in parallel:
|
||||
Platform::EventLoopPlugin::the().deferred_invoke(GC::create_function(realm.heap(), [&realm, transaction]() {
|
||||
HTML::TemporaryExecutionContext context(realm, HTML::TemporaryExecutionContext::CallbacksEnabled::Yes);
|
||||
|
||||
// 1. Wait until every item in transaction’s request list is processed.
|
||||
HTML::main_thread_event_loop().spin_until(GC::create_function(realm.vm().heap(), [transaction]() {
|
||||
if constexpr (IDB_DEBUG) {
|
||||
dbgln("commit_a_transaction: waiting for step 1");
|
||||
dbgln("requests in queue:");
|
||||
for (auto const& request : transaction->request_list()) {
|
||||
dbgln(" - {} = {}", request->uuid(), request->processed() ? "processed"sv : "not processed"sv);
|
||||
}
|
||||
}
|
||||
|
||||
return transaction->request_list().all_requests_processed();
|
||||
}));
|
||||
|
||||
// 2. If transaction’s state is no longer committing, then terminate these steps.
|
||||
if (transaction->state() != IDBTransaction::TransactionState::Committing)
|
||||
return;
|
||||
|
||||
// FIXME: 3. Attempt to write any outstanding changes made by transaction to the database, considering transaction’s durability hint.
|
||||
// FIXME: 4. If an error occurs while writing the changes to the database, then run abort a transaction with transaction and an appropriate type for the error, for example "QuotaExceededError" or "UnknownError" DOMException, and terminate these steps.
|
||||
|
||||
// 5. Queue a task to run these steps:
|
||||
HTML::queue_a_task(HTML::Task::Source::DatabaseAccess, nullptr, nullptr, GC::create_function(transaction->realm().vm().heap(), [transaction]() {
|
||||
// 1. If transaction is an upgrade transaction, then set transaction’s connection's associated database's upgrade transaction to null.
|
||||
if (transaction->is_upgrade_transaction())
|
||||
transaction->connection()->associated_database()->set_upgrade_transaction(nullptr);
|
||||
|
||||
// 2. Set transaction’s state to finished.
|
||||
transaction->set_state(IDBTransaction::TransactionState::Finished);
|
||||
|
||||
// 3. Fire an event named complete at transaction.
|
||||
transaction->dispatch_event(DOM::Event::create(transaction->realm(), HTML::EventNames::complete));
|
||||
|
||||
// 4. If transaction is an upgrade transaction, then let request be the request associated with transaction and set request’s transaction to null.
|
||||
if (transaction->is_upgrade_transaction()) {
|
||||
auto request = transaction->associated_request();
|
||||
request->set_transaction(nullptr);
|
||||
|
||||
// Ad-hoc: Clear the two-way binding.
|
||||
transaction->set_associated_request(nullptr);
|
||||
}
|
||||
}));
|
||||
}));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue