mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-04-20 11:36:10 +00:00
LibWeb/IDB: Implement IDBTransaction attributes
This also uncovered a bug, where the transactions type was never set :^)
This commit is contained in:
parent
718c805e95
commit
5298ecfc94
Notes:
github-actions[bot]
2025-04-09 17:50:19 +00:00
Author: https://github.com/stelar7 Commit: https://github.com/LadybirdBrowser/ladybird/commit/5298ecfc942 Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/4178 Reviewed-by: https://github.com/ADKaster ✅ Reviewed-by: https://github.com/AtkinsSJ
7 changed files with 63 additions and 15 deletions
|
@ -9,6 +9,7 @@
|
|||
#include <LibWeb/Bindings/Intrinsics.h>
|
||||
#include <LibWeb/HTML/EventNames.h>
|
||||
#include <LibWeb/IndexedDB/IDBRequest.h>
|
||||
#include <LibWeb/IndexedDB/IDBTransaction.h>
|
||||
|
||||
namespace Web::IndexedDB {
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
#include <LibWeb/Bindings/IDBRequestPrototype.h>
|
||||
#include <LibWeb/DOM/EventTarget.h>
|
||||
#include <LibWeb/IndexedDB/IDBTransaction.h>
|
||||
#include <LibWeb/IndexedDB/Internal/RequestList.h>
|
||||
|
||||
namespace Web::IndexedDB {
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2024, stelar7 <dudedbz@gmail.com>
|
||||
* Copyright (c) 2024-2025, stelar7 <dudedbz@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
@ -15,15 +15,18 @@ GC_DEFINE_ALLOCATOR(IDBTransaction);
|
|||
|
||||
IDBTransaction::~IDBTransaction() = default;
|
||||
|
||||
IDBTransaction::IDBTransaction(JS::Realm& realm, GC::Ref<IDBDatabase> database)
|
||||
IDBTransaction::IDBTransaction(JS::Realm& realm, GC::Ref<IDBDatabase> connection, Bindings::IDBTransactionMode mode, Bindings::IDBTransactionDurability durability, Vector<GC::Ref<ObjectStore>> scopes)
|
||||
: EventTarget(realm)
|
||||
, m_connection(database)
|
||||
, m_connection(connection)
|
||||
, m_mode(mode)
|
||||
, m_durability(durability)
|
||||
, m_scope(move(scopes))
|
||||
{
|
||||
}
|
||||
|
||||
GC::Ref<IDBTransaction> IDBTransaction::create(JS::Realm& realm, GC::Ref<IDBDatabase> database)
|
||||
GC::Ref<IDBTransaction> IDBTransaction::create(JS::Realm& realm, GC::Ref<IDBDatabase> connection, Bindings::IDBTransactionMode mode, Bindings::IDBTransactionDurability durability = Bindings::IDBTransactionDurability::Default, Vector<GC::Ref<ObjectStore>> scopes = {})
|
||||
{
|
||||
return realm.create<IDBTransaction>(realm, database);
|
||||
return realm.create<IDBTransaction>(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<void> IDBTransaction::abort()
|
||||
{
|
||||
// 1. If this's state is committing or finished, then throw an "InvalidStateError" DOMException.
|
||||
|
@ -82,4 +88,16 @@ WebIDL::ExceptionOr<void> IDBTransaction::abort()
|
|||
return {};
|
||||
}
|
||||
|
||||
// https://w3c.github.io/IndexedDB/#dom-idbtransaction-objectstorenames
|
||||
GC::Ref<HTML::DOMStringList> IDBTransaction::object_store_names()
|
||||
{
|
||||
// 1. Let names be a list of the names of the object stores in this's scope.
|
||||
Vector<String> 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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,17 +1,22 @@
|
|||
/*
|
||||
* Copyright (c) 2024, stelar7 <dudedbz@gmail.com>
|
||||
* Copyright (c) 2024-2025, stelar7 <dudedbz@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AK/Vector.h>
|
||||
#include <LibGC/Ptr.h>
|
||||
#include <LibWeb/Bindings/IDBDatabasePrototype.h>
|
||||
#include <LibWeb/Bindings/IDBTransactionPrototype.h>
|
||||
#include <LibWeb/DOM/Event.h>
|
||||
#include <LibWeb/DOM/EventTarget.h>
|
||||
#include <LibWeb/HTML/EventLoop/EventLoop.h>
|
||||
#include <LibWeb/IndexedDB/IDBDatabase.h>
|
||||
#include <LibWeb/IndexedDB/IDBRequest.h>
|
||||
#include <LibWeb/IndexedDB/Internal/ObjectStore.h>
|
||||
#include <LibWeb/IndexedDB/Internal/RequestList.h>
|
||||
|
||||
namespace Web::IndexedDB {
|
||||
|
||||
|
@ -30,7 +35,7 @@ class IDBTransaction : public DOM::EventTarget {
|
|||
public:
|
||||
virtual ~IDBTransaction() override;
|
||||
|
||||
[[nodiscard]] static GC::Ref<IDBTransaction> create(JS::Realm&, GC::Ref<IDBDatabase>);
|
||||
[[nodiscard]] static GC::Ref<IDBTransaction> create(JS::Realm&, GC::Ref<IDBDatabase>, Bindings::IDBTransactionMode, Bindings::IDBTransactionDurability, Vector<GC::Ref<ObjectStore>>);
|
||||
[[nodiscard]] Bindings::IDBTransactionMode mode() const { return m_mode; }
|
||||
[[nodiscard]] TransactionState state() const { return m_state; }
|
||||
[[nodiscard]] GC::Ptr<WebIDL::DOMException> error() const { return m_error; }
|
||||
|
@ -38,6 +43,8 @@ public:
|
|||
[[nodiscard]] Bindings::IDBTransactionDurability durability() const { return m_durability; }
|
||||
[[nodiscard]] GC::Ptr<IDBRequest> associated_request() const { return m_associated_request; }
|
||||
[[nodiscard]] bool aborted() const { return m_aborted; }
|
||||
[[nodiscard]] GC::Ref<HTML::DOMStringList> object_store_names();
|
||||
[[nodiscard]] ReadonlySpan<GC::Ref<ObjectStore>> 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<IDBDatabase>);
|
||||
explicit IDBTransaction(JS::Realm&, GC::Ref<IDBDatabase>, Bindings::IDBTransactionMode, Bindings::IDBTransactionDurability, Vector<GC::Ref<ObjectStore>>);
|
||||
virtual void initialize(JS::Realm&) override;
|
||||
virtual void visit_edges(Visitor& visitor) override;
|
||||
|
||||
private:
|
||||
// AD-HOC: The transaction has a connection
|
||||
GC::Ref<IDBDatabase> 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<WebIDL::DOMException> m_error;
|
||||
|
||||
// A transaction has an associated upgrade request
|
||||
GC::Ptr<IDBRequest> 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<GC::Ref<ObjectStore>> 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<HTML::EventLoop> m_cleanup_event_loop;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2024, stelar7 <dudedbz@gmail.com>
|
||||
* Copyright (c) 2024-2025, stelar7 <dudedbz@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
@ -312,9 +312,8 @@ GC::Ref<IDBTransaction> upgrade_a_database(JS::Realm& realm, GC::Ref<IDBDatabase
|
|||
auto db = connection->associated_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<GC::Ref<ObjectStore>> { connection->object_store_set() });
|
||||
|
||||
// 4. Set db’s upgrade transaction to transaction.
|
||||
db->set_upgrade_transaction(transaction);
|
||||
|
|
|
@ -4,8 +4,10 @@
|
|||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <LibWeb/IndexedDB/IDBTransaction.h>
|
||||
#include <LibWeb/IndexedDB/Internal/ConnectionQueueHandler.h>
|
||||
#include <LibWeb/IndexedDB/Internal/Database.h>
|
||||
#include <LibWeb/IndexedDB/Internal/RequestList.h>
|
||||
|
||||
namespace Web::IndexedDB {
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue