diff --git a/Libraries/LibWeb/IndexedDB/IDBRequest.cpp b/Libraries/LibWeb/IndexedDB/IDBRequest.cpp index c1d5b58f29b..a2d6f81c5a7 100644 --- a/Libraries/LibWeb/IndexedDB/IDBRequest.cpp +++ b/Libraries/LibWeb/IndexedDB/IDBRequest.cpp @@ -9,6 +9,7 @@ #include #include #include +#include namespace Web::IndexedDB { diff --git a/Libraries/LibWeb/IndexedDB/IDBRequest.h b/Libraries/LibWeb/IndexedDB/IDBRequest.h index e3031a22ccb..796cd4c9dad 100644 --- a/Libraries/LibWeb/IndexedDB/IDBRequest.h +++ b/Libraries/LibWeb/IndexedDB/IDBRequest.h @@ -10,7 +10,7 @@ #include #include -#include +#include namespace Web::IndexedDB { diff --git a/Libraries/LibWeb/IndexedDB/IDBTransaction.cpp b/Libraries/LibWeb/IndexedDB/IDBTransaction.cpp index e58115f3edd..0a1d94dc966 100644 --- a/Libraries/LibWeb/IndexedDB/IDBTransaction.cpp +++ b/Libraries/LibWeb/IndexedDB/IDBTransaction.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, stelar7 + * Copyright (c) 2024-2025, stelar7 * * SPDX-License-Identifier: BSD-2-Clause */ @@ -15,15 +15,18 @@ GC_DEFINE_ALLOCATOR(IDBTransaction); IDBTransaction::~IDBTransaction() = default; -IDBTransaction::IDBTransaction(JS::Realm& realm, GC::Ref database) +IDBTransaction::IDBTransaction(JS::Realm& realm, GC::Ref connection, Bindings::IDBTransactionMode mode, Bindings::IDBTransactionDurability durability, Vector> scopes) : EventTarget(realm) - , m_connection(database) + , m_connection(connection) + , m_mode(mode) + , m_durability(durability) + , m_scope(move(scopes)) { } -GC::Ref IDBTransaction::create(JS::Realm& realm, GC::Ref database) +GC::Ref IDBTransaction::create(JS::Realm& realm, GC::Ref connection, Bindings::IDBTransactionMode mode, Bindings::IDBTransactionDurability durability = Bindings::IDBTransactionDurability::Default, Vector> scopes = {}) { - return realm.create(realm, database); + return realm.create(realm, connection, mode, durability, move(scopes)); } void IDBTransaction::initialize(JS::Realm& realm) @@ -38,6 +41,8 @@ void IDBTransaction::visit_edges(Visitor& visitor) visitor.visit(m_connection); visitor.visit(m_error); visitor.visit(m_associated_request); + visitor.visit(m_scope); + visitor.visit(m_cleanup_event_loop); } void IDBTransaction::set_onabort(WebIDL::CallbackType* event_handler) @@ -70,6 +75,7 @@ WebIDL::CallbackType* IDBTransaction::onerror() return event_handler_attribute(HTML::EventNames::error); } +// https://w3c.github.io/IndexedDB/#dom-idbtransaction-abort WebIDL::ExceptionOr IDBTransaction::abort() { // 1. If this's state is committing or finished, then throw an "InvalidStateError" DOMException. @@ -82,4 +88,16 @@ WebIDL::ExceptionOr IDBTransaction::abort() return {}; } +// https://w3c.github.io/IndexedDB/#dom-idbtransaction-objectstorenames +GC::Ref IDBTransaction::object_store_names() +{ + // 1. Let names be a list of the names of the object stores in this's scope. + Vector names; + for (auto const& object_store : this->scope()) + names.append(object_store->name()); + + // 2. Return the result (a DOMStringList) of creating a sorted name list with names. + return create_a_sorted_name_list(realm(), names); +} + } diff --git a/Libraries/LibWeb/IndexedDB/IDBTransaction.h b/Libraries/LibWeb/IndexedDB/IDBTransaction.h index 14881a69dd0..a7b35fd75e2 100644 --- a/Libraries/LibWeb/IndexedDB/IDBTransaction.h +++ b/Libraries/LibWeb/IndexedDB/IDBTransaction.h @@ -1,17 +1,22 @@ /* - * Copyright (c) 2024, stelar7 + * Copyright (c) 2024-2025, stelar7 * * SPDX-License-Identifier: BSD-2-Clause */ #pragma once +#include #include #include #include #include #include +#include #include +#include +#include +#include namespace Web::IndexedDB { @@ -30,7 +35,7 @@ class IDBTransaction : public DOM::EventTarget { public: virtual ~IDBTransaction() override; - [[nodiscard]] static GC::Ref create(JS::Realm&, GC::Ref); + [[nodiscard]] static GC::Ref create(JS::Realm&, GC::Ref, Bindings::IDBTransactionMode, Bindings::IDBTransactionDurability, Vector>); [[nodiscard]] Bindings::IDBTransactionMode mode() const { return m_mode; } [[nodiscard]] TransactionState state() const { return m_state; } [[nodiscard]] GC::Ptr error() const { return m_error; } @@ -38,6 +43,8 @@ public: [[nodiscard]] Bindings::IDBTransactionDurability durability() const { return m_durability; } [[nodiscard]] GC::Ptr associated_request() const { return m_associated_request; } [[nodiscard]] bool aborted() const { return m_aborted; } + [[nodiscard]] GC::Ref object_store_names(); + [[nodiscard]] ReadonlySpan> scope() const { return m_scope; } void set_mode(Bindings::IDBTransactionMode mode) { m_mode = mode; } void set_state(TransactionState state) { m_state = state; } @@ -59,18 +66,39 @@ public: WebIDL::CallbackType* onerror(); protected: - explicit IDBTransaction(JS::Realm&, GC::Ref); + explicit IDBTransaction(JS::Realm&, GC::Ref, Bindings::IDBTransactionMode, Bindings::IDBTransactionDurability, Vector>); virtual void initialize(JS::Realm&) override; virtual void visit_edges(Visitor& visitor) override; private: + // AD-HOC: The transaction has a connection GC::Ref m_connection; + + // A transaction has a mode that determines which types of interactions can be performed upon that transaction. Bindings::IDBTransactionMode m_mode; + + // A transaction has a durability hint. This is a hint to the user agent of whether to prioritize performance or durability when committing the transaction. Bindings::IDBTransactionDurability m_durability { Bindings::IDBTransactionDurability::Default }; + + // A transaction has a state TransactionState m_state; + + // A transaction has a error which is set if the transaction is aborted. GC::Ptr m_error; + // A transaction has an associated upgrade request GC::Ptr m_associated_request; + + // AD-HOC: We need to track abort state separately, since we cannot rely on only the error. bool m_aborted { false }; + + // A transaction has a scope which is a set of object stores that the transaction may interact with. + Vector> m_scope; + + // A transaction has a request list of pending requests which have been made against the transaction. + RequestList m_request_list; + + // A transaction optionally has a cleanup event loop which is an event loop. + GC::Ptr m_cleanup_event_loop; }; } diff --git a/Libraries/LibWeb/IndexedDB/IDBTransaction.idl b/Libraries/LibWeb/IndexedDB/IDBTransaction.idl index bba6179e240..c343a328ab3 100644 --- a/Libraries/LibWeb/IndexedDB/IDBTransaction.idl +++ b/Libraries/LibWeb/IndexedDB/IDBTransaction.idl @@ -4,10 +4,10 @@ [Exposed=(Window,Worker)] interface IDBTransaction : EventTarget { - [FIXME] readonly attribute DOMStringList objectStoreNames; + readonly attribute DOMStringList objectStoreNames; readonly attribute IDBTransactionMode mode; readonly attribute IDBTransactionDurability durability; - [FIXME, SameObject] readonly attribute IDBDatabase db; + [SameObject, ImplementedAs=connection] readonly attribute IDBDatabase db; readonly attribute DOMException? error; [FIXME] IDBObjectStore objectStore(DOMString name); [FIXME] undefined commit(); diff --git a/Libraries/LibWeb/IndexedDB/Internal/Algorithms.cpp b/Libraries/LibWeb/IndexedDB/Internal/Algorithms.cpp index 6708cae50c8..4aa8fc7457d 100644 --- a/Libraries/LibWeb/IndexedDB/Internal/Algorithms.cpp +++ b/Libraries/LibWeb/IndexedDB/Internal/Algorithms.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, stelar7 + * Copyright (c) 2024-2025, stelar7 * * SPDX-License-Identifier: BSD-2-Clause */ @@ -312,9 +312,8 @@ GC::Ref upgrade_a_database(JS::Realm& realm, GC::Refassociated_database(); // 2. Let transaction be a new upgrade transaction with connection used as connection. - auto transaction = IDBTransaction::create(realm, connection); - - // FIXME: 3. Set transaction’s scope to connection’s object store set. + // 3. Set transaction’s scope to connection’s object store set. + auto transaction = IDBTransaction::create(realm, connection, Bindings::IDBTransactionMode::Versionchange, Bindings::IDBTransactionDurability::Default, Vector> { connection->object_store_set() }); // 4. Set db’s upgrade transaction to transaction. db->set_upgrade_transaction(transaction); diff --git a/Libraries/LibWeb/IndexedDB/Internal/Database.cpp b/Libraries/LibWeb/IndexedDB/Internal/Database.cpp index e02d0e38c52..cf4f5fd945c 100644 --- a/Libraries/LibWeb/IndexedDB/Internal/Database.cpp +++ b/Libraries/LibWeb/IndexedDB/Internal/Database.cpp @@ -4,8 +4,10 @@ * SPDX-License-Identifier: BSD-2-Clause */ +#include #include #include +#include namespace Web::IndexedDB {