mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-06-23 18:51:55 +00:00
LibWeb: Implement abort_a_transaction for IndexedDB
This commit is contained in:
parent
609f7aa659
commit
2954278e37
Notes:
github-actions[bot]
2024-12-14 22:04:24 +00:00
Author: https://github.com/stelar7
Commit: 2954278e37
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/2696
Reviewed-by: https://github.com/gmta
6 changed files with 66 additions and 2 deletions
|
@ -38,7 +38,7 @@ public:
|
|||
void set_error(GC::Ptr<WebIDL::DOMException> error) { m_error = error; }
|
||||
void set_processed(bool processed) { m_processed = processed; }
|
||||
void set_source(IDBRequestSource source) { m_source = source; }
|
||||
void set_transaction(GC::Ref<IDBTransaction> transaction) { m_transaction = transaction; }
|
||||
void set_transaction(GC::Ptr<IDBTransaction> transaction) { m_transaction = transaction; }
|
||||
|
||||
void set_onsuccess(WebIDL::CallbackType*);
|
||||
WebIDL::CallbackType* onsuccess();
|
||||
|
|
|
@ -36,6 +36,7 @@ void IDBTransaction::visit_edges(Visitor& visitor)
|
|||
Base::visit_edges(visitor);
|
||||
visitor.visit(m_connection);
|
||||
visitor.visit(m_error);
|
||||
visitor.visit(m_associated_request);
|
||||
}
|
||||
|
||||
void IDBTransaction::set_onabort(WebIDL::CallbackType* event_handler)
|
||||
|
|
|
@ -36,10 +36,12 @@ public:
|
|||
[[nodiscard]] GC::Ptr<WebIDL::DOMException> error() const { return m_error; }
|
||||
[[nodiscard]] GC::Ref<IDBDatabase> connection() const { return m_connection; }
|
||||
[[nodiscard]] Bindings::IDBTransactionDurability durability() const { return m_durability; }
|
||||
[[nodiscard]] GC::Ptr<IDBRequest> associated_request() const { return m_associated_request; }
|
||||
|
||||
void set_mode(Bindings::IDBTransactionMode mode) { m_mode = mode; }
|
||||
void set_state(TransactionState state) { m_state = state; }
|
||||
void set_error(GC::Ptr<WebIDL::DOMException> error) { m_error = error; }
|
||||
void set_associated_request(GC::Ptr<IDBRequest> request) { m_associated_request = request; }
|
||||
|
||||
[[nodiscard]] bool is_upgrade_transaction() const { return m_mode == Bindings::IDBTransactionMode::Versionchange; }
|
||||
[[nodiscard]] bool is_readonly() const { return m_mode == Bindings::IDBTransactionMode::Readonly; }
|
||||
|
@ -63,5 +65,7 @@ private:
|
|||
Bindings::IDBTransactionDurability m_durability { Bindings::IDBTransactionDurability::Default };
|
||||
TransactionState m_state;
|
||||
GC::Ptr<WebIDL::DOMException> m_error;
|
||||
|
||||
GC::Ptr<IDBRequest> m_associated_request;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ interface IDBTransaction : EventTarget {
|
|||
readonly attribute DOMException? error;
|
||||
[FIXME] IDBObjectStore objectStore(DOMString name);
|
||||
[FIXME] undefined commit();
|
||||
[FIXME] undefined abort();
|
||||
undefined abort();
|
||||
|
||||
attribute EventHandler onabort;
|
||||
attribute EventHandler oncomplete;
|
||||
|
|
|
@ -326,7 +326,9 @@ void upgrade_a_database(JS::Realm& realm, GC::Ref<IDBDatabase> connection, u64 v
|
|||
request->set_result(connection);
|
||||
|
||||
// 2. Set request’s transaction to transaction.
|
||||
// NOTE: We need to do a two-way binding here.
|
||||
request->set_transaction(transaction);
|
||||
transaction->set_associated_request(request);
|
||||
|
||||
// 3. Set request’s done flag to true.
|
||||
request->set_done(true);
|
||||
|
@ -422,4 +424,60 @@ WebIDL::ExceptionOr<u64> delete_a_database(JS::Realm& realm, StorageAPI::Storage
|
|||
return version;
|
||||
}
|
||||
|
||||
// https://w3c.github.io/IndexedDB/#abort-a-transaction
|
||||
void abort_a_transaction(IDBTransaction& transaction, GC::Ptr<WebIDL::DOMException> error)
|
||||
{
|
||||
// FIXME: 1. All the changes made to the database by the transaction are reverted.
|
||||
// For upgrade transactions this includes changes to the set of object stores and indexes, as well as the change to the version.
|
||||
// Any object stores and indexes which were created during the transaction are now considered deleted for the purposes of other algorithms.
|
||||
|
||||
// FIXME: 2. If transaction is an upgrade transaction, run the steps to abort an upgrade transaction with transaction.
|
||||
// if (transaction.is_upgrade_transaction())
|
||||
// abort_an_upgrade_transaction(transaction);
|
||||
|
||||
// 3. Set transaction’s state to finished.
|
||||
transaction.set_state(IDBTransaction::TransactionState::Finished);
|
||||
|
||||
// 4. If error is not null, set transaction’s error to error.
|
||||
if (error)
|
||||
transaction.set_error(error);
|
||||
|
||||
// FIXME: 5. For each request of transaction’s request list, abort the steps to asynchronously execute a request for request,
|
||||
// set request’s processed flag to true, and queue a task to run these steps:
|
||||
// FIXME: 1. Set request’s done flag to true.
|
||||
// FIXME: 2. Set request’s result to undefined.
|
||||
// FIXME: 3. Set request’s error to a newly created "AbortError" DOMException.
|
||||
// FIXME: 4. Fire an event named error at request with its bubbles and cancelable attributes initialized to true.
|
||||
|
||||
// 6. 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. Fire an event named abort at transaction with its bubbles attribute initialized to true.
|
||||
transaction.dispatch_event(DOM::Event::create(transaction.realm(), HTML::EventNames::abort, { .bubbles = true }));
|
||||
|
||||
// 3. If transaction is an upgrade transaction, then:
|
||||
if (transaction.is_upgrade_transaction()) {
|
||||
// 1. Let request be the open request associated with transaction.
|
||||
auto request = transaction.associated_request();
|
||||
|
||||
// 2. Set request’s transaction to null.
|
||||
// NOTE: Clear the two-way binding.
|
||||
request->set_transaction(nullptr);
|
||||
transaction.set_associated_request(nullptr);
|
||||
|
||||
// 3. Set request’s result to undefined.
|
||||
request->set_result(JS::js_undefined());
|
||||
|
||||
// 4. Set request’s processed flag to false.
|
||||
request->set_processed(false);
|
||||
|
||||
// 5. Set request’s done flag to false.
|
||||
request->set_done(false);
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -19,5 +19,6 @@ ErrorOr<Key> convert_a_value_to_a_key(JS::Realm&, JS::Value, Vector<JS::Value> =
|
|||
void close_a_database_connection(IDBDatabase&, bool forced = false);
|
||||
void upgrade_a_database(JS::Realm&, GC::Ref<IDBDatabase>, u64, GC::Ref<IDBRequest>);
|
||||
WebIDL::ExceptionOr<u64> delete_a_database(JS::Realm&, StorageAPI::StorageKey, String, GC::Ref<IDBRequest>);
|
||||
void abort_a_transaction(IDBTransaction&, GC::Ptr<WebIDL::DOMException>);
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue