From 7250aa0b6b600fb8287d79f7b388a345e1d41f1e Mon Sep 17 00:00:00 2001 From: stelar7 Date: Thu, 8 May 2025 23:47:49 +0200 Subject: [PATCH] LibWeb/IDB: Implement IDBObjectStore::getAllKeys --- Libraries/LibWeb/IndexedDB/IDBObjectStore.cpp | 31 +++++++++++++++++++ Libraries/LibWeb/IndexedDB/IDBObjectStore.h | 1 + Libraries/LibWeb/IndexedDB/IDBObjectStore.idl | 2 +- 3 files changed, 33 insertions(+), 1 deletion(-) diff --git a/Libraries/LibWeb/IndexedDB/IDBObjectStore.cpp b/Libraries/LibWeb/IndexedDB/IDBObjectStore.cpp index 116c5827bb6..588740fd9ca 100644 --- a/Libraries/LibWeb/IndexedDB/IDBObjectStore.cpp +++ b/Libraries/LibWeb/IndexedDB/IDBObjectStore.cpp @@ -607,4 +607,35 @@ WebIDL::ExceptionOr> IDBObjectStore::open_key_cursor(JS::Val return request; } +// https://w3c.github.io/IndexedDB/#dom-idbobjectstore-getallkeys +WebIDL::ExceptionOr> IDBObjectStore::get_all_keys(Optional query, Optional count) +{ + 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 getting all keys"_string); + + // 5. Let range be the result of converting a value to a key range with query. Rethrow any exceptions. + auto range = TRY(convert_a_value_to_a_key_range(realm, move(query))); + + // 6. Let operation be an algorithm to run retrieve multiple keys from an object store with store, range, and count if given. + auto operation = GC::Function()>::create(realm.heap(), [&realm, store, range, count] -> WebIDL::ExceptionOr { + return retrieve_multiple_keys_from_an_object_store(realm, store, range, count); + }); + + // 7. 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 get all keys with uuid {}", result->uuid()); + return result; +} + } diff --git a/Libraries/LibWeb/IndexedDB/IDBObjectStore.h b/Libraries/LibWeb/IndexedDB/IDBObjectStore.h index 133d806f497..681201aca29 100644 --- a/Libraries/LibWeb/IndexedDB/IDBObjectStore.h +++ b/Libraries/LibWeb/IndexedDB/IDBObjectStore.h @@ -57,6 +57,7 @@ public: [[nodiscard]] WebIDL::ExceptionOr> get_key(JS::Value); [[nodiscard]] WebIDL::ExceptionOr> get_all(Optional, Optional); [[nodiscard]] WebIDL::ExceptionOr> open_key_cursor(JS::Value, Bindings::IDBCursorDirection = Bindings::IDBCursorDirection::Next); + [[nodiscard]] WebIDL::ExceptionOr> get_all_keys(Optional, Optional); protected: explicit IDBObjectStore(JS::Realm&, GC::Ref, GC::Ref); diff --git a/Libraries/LibWeb/IndexedDB/IDBObjectStore.idl b/Libraries/LibWeb/IndexedDB/IDBObjectStore.idl index 3bfdf1129c2..50620f64064 100644 --- a/Libraries/LibWeb/IndexedDB/IDBObjectStore.idl +++ b/Libraries/LibWeb/IndexedDB/IDBObjectStore.idl @@ -17,7 +17,7 @@ interface IDBObjectStore { [NewObject] IDBRequest get(any query); [NewObject] IDBRequest getKey(any query); [NewObject] IDBRequest getAll(optional any query, optional [EnforceRange] unsigned long count); - [FIXME, NewObject] IDBRequest getAllKeys(optional any query, optional [EnforceRange] unsigned long count); + [NewObject] IDBRequest getAllKeys(optional any query, optional [EnforceRange] unsigned long count); [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");