From 18a008d073da0e0db83ee383cce79caf6adec71d Mon Sep 17 00:00:00 2001 From: stelar7 Date: Mon, 28 Apr 2025 15:55:46 +0200 Subject: [PATCH] LibWeb/IDB: Implement retrieve_a_value_from_an_object_store --- .../LibWeb/IndexedDB/Internal/Algorithms.cpp | 17 +++++++++++++++++ .../LibWeb/IndexedDB/Internal/Algorithms.h | 1 + .../LibWeb/IndexedDB/Internal/ObjectStore.cpp | 7 +++++++ .../LibWeb/IndexedDB/Internal/ObjectStore.h | 1 + 4 files changed, 26 insertions(+) diff --git a/Libraries/LibWeb/IndexedDB/Internal/Algorithms.cpp b/Libraries/LibWeb/IndexedDB/Internal/Algorithms.cpp index 42745cec306..7cc5be8070e 100644 --- a/Libraries/LibWeb/IndexedDB/Internal/Algorithms.cpp +++ b/Libraries/LibWeb/IndexedDB/Internal/Algorithms.cpp @@ -1458,4 +1458,21 @@ JS::Value count_the_records_in_a_range(GC::Ref source, GC::Ref retrieve_a_value_from_an_object_store(JS::Realm& realm, GC::Ref store, GC::Ref range) +{ + // 1. Let record be the first record in store’s list of records whose key is in range, if any. + auto record = store->first_in_range(range); + + // 2. If record was not found, return undefined. + if (!record.has_value()) + return JS::js_undefined(); + + // 3. Let serialized be record’s value. If an error occurs while reading the value from the underlying storage, return a newly created "NotReadableError" DOMException. + auto serialized = record->value; + + // 4. Return ! StructuredDeserialize(serialized, targetRealm). + return MUST(HTML::structured_deserialize(realm.vm(), serialized, realm)); +} + } diff --git a/Libraries/LibWeb/IndexedDB/Internal/Algorithms.h b/Libraries/LibWeb/IndexedDB/Internal/Algorithms.h index 12be59ff772..e7fb80ff6fc 100644 --- a/Libraries/LibWeb/IndexedDB/Internal/Algorithms.h +++ b/Libraries/LibWeb/IndexedDB/Internal/Algorithms.h @@ -43,5 +43,6 @@ void delete_records_from_an_object_store(GC::Ref, GC::Ref> 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); +WebIDL::ExceptionOr retrieve_a_value_from_an_object_store(JS::Realm&, GC::Ref, GC::Ref); } diff --git a/Libraries/LibWeb/IndexedDB/Internal/ObjectStore.cpp b/Libraries/LibWeb/IndexedDB/Internal/ObjectStore.cpp index 20d54b67d38..38ffa9c3430 100644 --- a/Libraries/LibWeb/IndexedDB/Internal/ObjectStore.cpp +++ b/Libraries/LibWeb/IndexedDB/Internal/ObjectStore.cpp @@ -77,4 +77,11 @@ u64 ObjectStore::count_records_in_range(GC::Ref range) return count; } +Optional ObjectStore::first_in_range(GC::Ref range) +{ + return m_records.first_matching([&](auto const& record) { + return range->is_in_range(record.key); + }); +} + } diff --git a/Libraries/LibWeb/IndexedDB/Internal/ObjectStore.h b/Libraries/LibWeb/IndexedDB/Internal/ObjectStore.h index aab58c3d4f5..fbe2e637add 100644 --- a/Libraries/LibWeb/IndexedDB/Internal/ObjectStore.h +++ b/Libraries/LibWeb/IndexedDB/Internal/ObjectStore.h @@ -53,6 +53,7 @@ public: bool has_record_with_key(GC::Ref key); void store_a_record(Record const& record); u64 count_records_in_range(GC::Ref range); + Optional first_in_range(GC::Ref range); protected: virtual void visit_edges(Visitor&) override;