From aa35ced34fe7330c41a16966ae8b7aae6527fee9 Mon Sep 17 00:00:00 2001 From: stelar7 Date: Thu, 8 May 2025 09:59:13 +0200 Subject: [PATCH] LibWeb/IDB: Implement IDBObjectStore::delete --- Libraries/LibWeb/IndexedDB/IDBObjectStore.cpp | 35 +++++++++++++++++++ Libraries/LibWeb/IndexedDB/IDBObjectStore.h | 1 + Libraries/LibWeb/IndexedDB/IDBObjectStore.idl | 2 +- .../LibWeb/IndexedDB/Internal/Algorithms.cpp | 3 +- .../LibWeb/IndexedDB/Internal/Algorithms.h | 2 +- 5 files changed, 40 insertions(+), 3 deletions(-) diff --git a/Libraries/LibWeb/IndexedDB/IDBObjectStore.cpp b/Libraries/LibWeb/IndexedDB/IDBObjectStore.cpp index c582dba9abd..c05d3b06129 100644 --- a/Libraries/LibWeb/IndexedDB/IDBObjectStore.cpp +++ b/Libraries/LibWeb/IndexedDB/IDBObjectStore.cpp @@ -439,4 +439,39 @@ WebIDL::ExceptionOr> IDBObjectStore::open_cursor(JS::Value q return request; } +// https://w3c.github.io/IndexedDB/#dom-idbobjectstore-delete +WebIDL::ExceptionOr> IDBObjectStore::delete_(JS::Value query) +{ + auto& realm = this->realm(); + + // 1. Let transaction be this’s transaction. + auto transaction = this->transaction(); + + // 2. Let store be this’s object store. + auto store = this->store(); + + // FIXME: 3. If store has been deleted, throw an "InvalidStateError" DOMException. + + // 4. If transaction’s state is not active, then throw a "TransactionInactiveError" DOMException. + if (transaction->state() != IDBTransaction::TransactionState::Active) + return WebIDL::TransactionInactiveError::create(realm, "Transaction is not active while deleting object store"_string); + + // 5. If transaction is a read-only transaction, throw a "ReadOnlyError" DOMException. + if (transaction->is_readonly()) + return WebIDL::ReadOnlyError::create(realm, "Transaction is read-only while deleting object store"_string); + + // 6. Let range be the result of converting a value to a key range with query and true. Rethrow any exceptions. + auto range = TRY(convert_a_value_to_a_key_range(realm, query, true)); + + // 7. Let operation be an algorithm to run delete records from an object store with store and range. + auto operation = GC::Function()>::create(realm.heap(), [store, range] -> WebIDL::ExceptionOr { + return delete_records_from_an_object_store(store, range); + }); + + // 8. Return the result (an IDBRequest) of running asynchronously execute a request with this and operation. + auto result = asynchronously_execute_a_request(realm, GC::Ref(*this), operation); + dbgln_if(IDB_DEBUG, "Executing request for delete with uuid {}", result->uuid()); + return result; +} + } diff --git a/Libraries/LibWeb/IndexedDB/IDBObjectStore.h b/Libraries/LibWeb/IndexedDB/IDBObjectStore.h index c23ff66c543..53998193297 100644 --- a/Libraries/LibWeb/IndexedDB/IDBObjectStore.h +++ b/Libraries/LibWeb/IndexedDB/IDBObjectStore.h @@ -52,6 +52,7 @@ public: [[nodiscard]] WebIDL::ExceptionOr> count(Optional); [[nodiscard]] WebIDL::ExceptionOr> get(JS::Value); [[nodiscard]] WebIDL::ExceptionOr> open_cursor(JS::Value, Bindings::IDBCursorDirection = Bindings::IDBCursorDirection::Next); + [[nodiscard]] WebIDL::ExceptionOr> delete_(JS::Value); protected: explicit IDBObjectStore(JS::Realm&, GC::Ref, GC::Ref); diff --git a/Libraries/LibWeb/IndexedDB/IDBObjectStore.idl b/Libraries/LibWeb/IndexedDB/IDBObjectStore.idl index 6d21125107d..92c916a1664 100644 --- a/Libraries/LibWeb/IndexedDB/IDBObjectStore.idl +++ b/Libraries/LibWeb/IndexedDB/IDBObjectStore.idl @@ -12,7 +12,7 @@ interface IDBObjectStore { [NewObject] IDBRequest put(any value, optional any key); [NewObject] IDBRequest add(any value, optional any key); - [FIXME, NewObject] IDBRequest delete(any query); + [NewObject] IDBRequest delete(any query); [FIXME, NewObject] IDBRequest clear(); [NewObject] IDBRequest get(any query); [FIXME, NewObject] IDBRequest getKey(any query); diff --git a/Libraries/LibWeb/IndexedDB/Internal/Algorithms.cpp b/Libraries/LibWeb/IndexedDB/Internal/Algorithms.cpp index 568b8fd2583..9bfb97cd01c 100644 --- a/Libraries/LibWeb/IndexedDB/Internal/Algorithms.cpp +++ b/Libraries/LibWeb/IndexedDB/Internal/Algorithms.cpp @@ -1312,7 +1312,7 @@ void inject_a_key_into_a_value_using_a_key_path(JS::Realm& realm, JS::Value valu } // https://w3c.github.io/IndexedDB/#delete-records-from-an-object-store -void delete_records_from_an_object_store(GC::Ref store, GC::Ref range) +JS::Value delete_records_from_an_object_store(GC::Ref store, GC::Ref range) { // 1. Remove all records, if any, from store’s list of records with key in range. store->remove_records_in_range(range); @@ -1320,6 +1320,7 @@ void delete_records_from_an_object_store(GC::Ref store, GC::Ref asynchronously_execute_a_request(JS::Realm&, IDBRequestSourc ErrorOr generate_a_key(GC::Ref); void possibly_update_the_key_generator(GC::Ref, GC::Ref); void inject_a_key_into_a_value_using_a_key_path(JS::Realm&, JS::Value, GC::Ref, KeyPath const&); -void delete_records_from_an_object_store(GC::Ref, GC::Ref); +JS::Value delete_records_from_an_object_store(GC::Ref, GC::Ref); WebIDL::ExceptionOr> store_a_record_into_an_object_store(JS::Realm&, GC::Ref, JS::Value, GC::Ptr, bool); WebIDL::ExceptionOr> convert_a_value_to_a_key_range(JS::Realm&, Optional, bool = false); JS::Value count_the_records_in_a_range(GC::Ref, GC::Ref);