From 559b9dbd830811b607ba8c40411194840d2531e0 Mon Sep 17 00:00:00 2001 From: stelar7 Date: Thu, 10 Jul 2025 08:55:16 +0200 Subject: [PATCH] LibWeb/IDB: Implement IDBObjectStore::get_all_records --- Libraries/LibWeb/IndexedDB/IDBObjectStore.cpp | 28 +++++++++++++++++++ Libraries/LibWeb/IndexedDB/IDBObjectStore.h | 7 +++++ Libraries/LibWeb/IndexedDB/IDBObjectStore.idl | 7 +++++ 3 files changed, 42 insertions(+) diff --git a/Libraries/LibWeb/IndexedDB/IDBObjectStore.cpp b/Libraries/LibWeb/IndexedDB/IDBObjectStore.cpp index e9fddcb1845..aa0a1bd781c 100644 --- a/Libraries/LibWeb/IndexedDB/IDBObjectStore.cpp +++ b/Libraries/LibWeb/IndexedDB/IDBObjectStore.cpp @@ -731,4 +731,32 @@ WebIDL::ExceptionOr> IDBObjectStore::get_all_keys(Optional> IDBObjectStore::get_all_records(IDBGetAllOptions const& options) +{ + 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->is_active()) + return WebIDL::TransactionInactiveError::create(realm, "Transaction is not active while getting all records"_utf16); + + // 5. Let range be the result of converting a value to a key range with options["query"]. Rethrow any exceptions. + auto range = TRY(convert_a_value_to_a_key_range(realm, options.query)); + + // 6. Let operation be an algorithm to run retrieve multiple items from an object store with the current Realm record, store, range, "record", options["direction"], and options["count"] if given. + auto operation = GC::Function()>::create(realm.heap(), [&realm, store, range, options] -> WebIDL::ExceptionOr { + return retrieve_multiple_items_from_an_object_store(realm, store, range, RecordKind::Record, options.direction, options.count); + }); + + // 7. Return the result (an IDBRequest) of running asynchronously execute a request with this and operation. + return asynchronously_execute_a_request(realm, GC::Ref(*this), operation); +} + } diff --git a/Libraries/LibWeb/IndexedDB/IDBObjectStore.h b/Libraries/LibWeb/IndexedDB/IDBObjectStore.h index cfabf6e903a..2570a3c6e85 100644 --- a/Libraries/LibWeb/IndexedDB/IDBObjectStore.h +++ b/Libraries/LibWeb/IndexedDB/IDBObjectStore.h @@ -21,6 +21,12 @@ struct IDBIndexParameters { bool multi_entry { false }; }; +struct IDBGetAllOptions { + JS::Value query { JS::js_undefined() }; + Optional count; + Bindings::IDBCursorDirection direction { Bindings::IDBCursorDirection::Next }; +}; + // https://w3c.github.io/IndexedDB/#object-store-interface // https://w3c.github.io/IndexedDB/#object-store-handle-construct class IDBObjectStore : public Bindings::PlatformObject { @@ -46,6 +52,7 @@ public: [[nodiscard]] WebIDL::ExceptionOr> get_key(JS::Value); [[nodiscard]] WebIDL::ExceptionOr> get_all(Optional, Optional); [[nodiscard]] WebIDL::ExceptionOr> get_all_keys(Optional, Optional); + [[nodiscard]] WebIDL::ExceptionOr> get_all_records(IDBGetAllOptions const&); [[nodiscard]] WebIDL::ExceptionOr> count(Optional); [[nodiscard]] WebIDL::ExceptionOr> open_cursor(JS::Value, Bindings::IDBCursorDirection = Bindings::IDBCursorDirection::Next); [[nodiscard]] WebIDL::ExceptionOr> open_key_cursor(JS::Value, Bindings::IDBCursorDirection = Bindings::IDBCursorDirection::Next); diff --git a/Libraries/LibWeb/IndexedDB/IDBObjectStore.idl b/Libraries/LibWeb/IndexedDB/IDBObjectStore.idl index 50620f64064..d8a4394021d 100644 --- a/Libraries/LibWeb/IndexedDB/IDBObjectStore.idl +++ b/Libraries/LibWeb/IndexedDB/IDBObjectStore.idl @@ -18,6 +18,7 @@ interface IDBObjectStore { [NewObject] IDBRequest getKey(any query); [NewObject] IDBRequest getAll(optional any query, optional [EnforceRange] unsigned long count); [NewObject] IDBRequest getAllKeys(optional any query, optional [EnforceRange] unsigned long count); + [NewObject] IDBRequest getAllRecords(optional IDBGetAllOptions options = {}); [NewObject] IDBRequest count(optional any query); [NewObject] IDBRequest openCursor(optional any query, optional IDBCursorDirection direction = "next"); [NewObject] IDBRequest openKeyCursor(optional any query, optional IDBCursorDirection direction = "next"); @@ -30,3 +31,9 @@ dictionary IDBIndexParameters { boolean unique = false; boolean multiEntry = false; }; + +dictionary IDBGetAllOptions { + any query = null; + [EnforceRange] unsigned long count; + IDBCursorDirection direction = "next"; +}; \ No newline at end of file