LibWeb/IDB: Implement IDBDatabase::transaction()

This commit is contained in:
stelar7
2025-04-25 18:08:40 +02:00
committed by Jelle Raaijmakers
parent a05be67e4a
commit 61384473ca
Notes: github-actions[bot] 2025-04-28 09:33:04 +00:00
5 changed files with 62 additions and 1 deletions

View File

@@ -189,4 +189,53 @@ WebIDL::ExceptionOr<void> IDBDatabase::delete_object_store(String const& name)
return {};
}
WebIDL::ExceptionOr<GC::Ref<IDBTransaction>> IDBDatabase::transaction(Variant<String, Vector<String>> store_names, Bindings::IDBTransactionMode mode, IDBTransactionOptions options)
{
// 1. If a live upgrade transaction is associated with the connection, throw an "InvalidStateError" DOMException.
auto database = associated_database();
if (database->upgrade_transaction())
return WebIDL::InvalidStateError::create(realm(), "Upgrade transaction is live"_string);
// 2. If this's close pending flag is true, then throw an "InvalidStateError" DOMException.
if (close_pending())
return WebIDL::InvalidStateError::create(realm(), "Close pending"_string);
// 3. Let scope be the set of unique strings in storeNames if it is a sequence, or a set containing one string equal to storeNames otherwise.
Vector<String> scope;
if (store_names.has<Vector<String>>()) {
scope = store_names.get<Vector<String>>();
} else {
scope.append(store_names.get<String>());
}
// 4. If any string in scope is not the name of an object store in the connected database, throw a "NotFoundError" DOMException.
for (auto const& store_name : scope) {
if (!database->object_store_with_name(store_name))
return WebIDL::NotFoundError::create(realm(), "Object store not found"_string);
}
// 5. If scope is empty, throw an "InvalidAccessError" DOMException.
if (scope.is_empty())
return WebIDL::InvalidAccessError::create(realm(), "Scope is empty"_string);
// 6. If mode is not "readonly" or "readwrite", throw a TypeError.
if (mode != Bindings::IDBTransactionMode::Readonly && mode != Bindings::IDBTransactionMode::Readwrite)
return WebIDL::SimpleException { WebIDL::SimpleExceptionType::TypeError, "Invalid transaction mode"_string };
// 7. Let transaction be a newly created transaction with this connection, mode, options durability member, and the set of object stores named in scope.
Vector<GC::Ref<ObjectStore>> scope_stores;
for (auto const& store_name : scope) {
auto store = database->object_store_with_name(store_name);
scope_stores.append(*store);
}
auto transaction = IDBTransaction::create(realm(), *this, mode, options.durability, scope_stores);
// 8. Set transactions cleanup event loop to the current event loop.
transaction->set_cleanup_event_loop(HTML::main_thread_event_loop());
// 9. Return an IDBTransaction object representing transaction.
return transaction;
}
}