LibWeb/IDB: Implement create_a_request_to_retrieve_multiple_items
Some checks are pending
CI / macOS, arm64, Sanitizer, Clang (push) Waiting to run
CI / Linux, x86_64, Fuzzers, Clang (push) Waiting to run
CI / Linux, x86_64, Sanitizer, GNU (push) Waiting to run
CI / Linux, x86_64, Sanitizer, Clang (push) Waiting to run
Package the js repl as a binary artifact / Linux, arm64 (push) Waiting to run
Package the js repl as a binary artifact / macOS, arm64 (push) Waiting to run
Package the js repl as a binary artifact / Linux, x86_64 (push) Waiting to run
Run test262 and test-wasm / run_and_update_results (push) Waiting to run
Lint Code / lint (push) Waiting to run
Label PRs with merge conflicts / auto-labeler (push) Waiting to run
Push notes / build (push) Waiting to run

This commit is contained in:
stelar7 2025-07-25 19:51:45 +02:00 committed by Jelle Raaijmakers
commit fde5dc7491
Notes: github-actions[bot] 2025-08-27 14:14:36 +00:00
4 changed files with 117 additions and 291 deletions

View file

@ -206,135 +206,17 @@ WebIDL::ExceptionOr<GC::Ref<IDBRequest>> IDBIndex::get_key(JS::Value query)
// https://w3c.github.io/IndexedDB/#dom-idbindex-getall
WebIDL::ExceptionOr<GC::Ref<IDBRequest>> IDBIndex::get_all(Optional<JS::Value> query_or_options, Optional<WebIDL::UnsignedLong> count)
{
auto& realm = this->realm();
auto& vm = realm.vm();
// 1. Let transaction be thiss transaction.
auto transaction = this->transaction();
// 2. Let index be thiss index.
auto index = this->index();
// FIXME: 3. If index or indexs object store has been deleted, throw an "InvalidStateError" DOMException.
// 4. If transactions 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"_utf16);
// 5. Let range be a key range.
GC::Ptr<IDBKeyRange> range;
// 6. Let direction be a cursor direction.
Bindings::IDBCursorDirection direction = Bindings::IDBCursorDirection::Next;
// 7. If running is a potentially valid key range with query_or_options is true, then:
if (is_a_potentially_valid_key_range(realm, *query_or_options)) {
// 1. Set range to the result of converting a value to a key range with query_or_options. Rethrow any exceptions.
range = TRY(convert_a_value_to_a_key_range(realm, query_or_options));
// 2. Set direction to "next".
direction = Bindings::IDBCursorDirection::Next;
}
// 8. Else:
else {
// 1. Set range to the result of converting a value to a key range with query_or_options["query"]. Rethrow any exceptions.
range = TRY(convert_a_value_to_a_key_range(realm, TRY(query_or_options->get(vm, "query"_utf16))));
// 2. Set count to query_or_options["count"].
count = TRY(TRY(query_or_options->get(vm, "count"_utf16)).to_u32(vm));
// 3. Set direction to query_or_options["direction"].
auto direction_value = TRY(TRY(query_or_options->get(vm, "direction"_utf16)).to_string(vm));
if (direction_value == "next"_string) {
direction = Bindings::IDBCursorDirection::Next;
} else if (direction_value == "nextunique"_string) {
direction = Bindings::IDBCursorDirection::Nextunique;
} else if (direction_value == "prev"_string) {
direction = Bindings::IDBCursorDirection::Prev;
} else if (direction_value == "prevunique"_string) {
direction = Bindings::IDBCursorDirection::Prevunique;
} else {
return WebIDL::SimpleException { WebIDL::SimpleExceptionType::TypeError, "Invalid direction value"_string };
}
}
// 9. Let operation be an algorithm to run retrieve multiple items from an index with the current Realm record, index, range, "value", direction and count if given.
auto operation = GC::Function<WebIDL::ExceptionOr<JS::Value>()>::create(realm.heap(), [&realm, index, range, direction, count] -> WebIDL::ExceptionOr<JS::Value> {
return retrieve_multiple_items_from_an_index(realm, index, GC::Ref(*range), RecordKind::Value, direction, count);
});
// 10. 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 with uuid {}", result->uuid());
return result;
// 1. Return the result of creating a request to retrieve multiple items with the current Realm record, this,
// "value", queryOrOptions, and count if given. Rethrow any exceptions.
return create_a_request_to_retrieve_multiple_items(realm(), GC::Ref(*this), RecordKind::Value, *query_or_options, count);
}
// https://w3c.github.io/IndexedDB/#dom-idbindex-getallkeys
WebIDL::ExceptionOr<GC::Ref<IDBRequest>> IDBIndex::get_all_keys(Optional<JS::Value> query_or_options, Optional<WebIDL::UnsignedLong> count)
{
auto& realm = this->realm();
auto& vm = realm.vm();
// 1. Let transaction be thiss transaction.
auto transaction = this->transaction();
// 2. Let index be thiss index.
auto index = this->index();
// FIXME: 3. If index or indexs object store has been deleted, throw an "InvalidStateError" DOMException.
// 4. If transactions 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 keys"_utf16);
// 5. Let range be a key range.
GC::Ptr<IDBKeyRange> range;
// 6. Let direction be a cursor direction.
Bindings::IDBCursorDirection direction = Bindings::IDBCursorDirection::Next;
// 7. If running is a potentially valid key range with query_or_options is true, then:
if (is_a_potentially_valid_key_range(realm, *query_or_options)) {
// 1. Set range to the result of converting a value to a key range with query_or_options. Rethrow any exceptions.
range = TRY(convert_a_value_to_a_key_range(realm, query_or_options));
// 2. Set direction to "next".
direction = Bindings::IDBCursorDirection::Next;
}
// 8. Else:
else {
// 1. Set range to the result of converting a value to a key range with query_or_options["query"]. Rethrow any exceptions.
range = TRY(convert_a_value_to_a_key_range(realm, TRY(query_or_options->get(vm, "query"_utf16))));
// 2. Set count to query_or_options["count"].
count = TRY(TRY(query_or_options->get(vm, "count"_utf16)).to_u32(vm));
// 3. Set direction to query_or_options["direction"].
auto direction_value = TRY(TRY(query_or_options->get(vm, "direction"_utf16)).to_string(vm));
if (direction_value == "next"_string) {
direction = Bindings::IDBCursorDirection::Next;
} else if (direction_value == "nextunique"_string) {
direction = Bindings::IDBCursorDirection::Nextunique;
} else if (direction_value == "prev"_string) {
direction = Bindings::IDBCursorDirection::Prev;
} else if (direction_value == "prevunique"_string) {
direction = Bindings::IDBCursorDirection::Prevunique;
} else {
return WebIDL::SimpleException { WebIDL::SimpleExceptionType::TypeError, "Invalid direction value"_string };
}
}
// 9. Let operation be an algorithm to run retrieve multiple items from an index with the current Realm record, index, range, "key", direction and count if given.
auto operation = GC::Function<WebIDL::ExceptionOr<JS::Value>()>::create(realm.heap(), [&realm, index, range, direction, count] -> WebIDL::ExceptionOr<JS::Value> {
return retrieve_multiple_items_from_an_index(realm, index, GC::Ref(*range), RecordKind::Key, direction, count);
});
// 10. 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;
// 1. Return the result of creating a request to retrieve multiple items with the current Realm record, this, "key",
// queryOrOptions, and count if given. Rethrow any exceptions.
return create_a_request_to_retrieve_multiple_items(realm(), GC::Ref(*this), RecordKind::Key, *query_or_options, count);
}
// https://w3c.github.io/IndexedDB/#dom-idbindex-count
@ -409,30 +291,15 @@ WebIDL::ExceptionOr<GC::Ref<IDBRequest>> IDBIndex::open_key_cursor(JS::Value que
WebIDL::ExceptionOr<GC::Ref<IDBRequest>> IDBIndex::get_all_records(IDBGetAllOptions const& options)
{
auto& realm = this->realm();
// 1. Return the result of creating a request to retrieve multiple items with the current Realm record, this,
// "record", and options. Rethrow any exceptions.
// 1. Let transaction be thiss transaction.
auto transaction = this->transaction();
auto converted_options = JS::Object::create(realm(), nullptr);
MUST(converted_options->create_data_property("query"_utf16, options.query));
MUST(converted_options->create_data_property("count"_utf16, options.count.has_value() ? JS::Value(options.count.value()) : JS::js_undefined()));
MUST(converted_options->create_data_property("direction"_utf16, JS::PrimitiveString::create(realm().vm(), idl_enum_to_string(options.direction))));
// 2. Let index be thiss index.
auto index = this->index();
// FIXME: 3. If index or indexs object store has been deleted, then throw an "InvalidStateError" DOMException.
// 4. If transactions 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 index with the current Realm record, index, range, "record", options["direction"], and options["count"] if given.
auto operation = GC::Function<WebIDL::ExceptionOr<JS::Value>()>::create(realm.heap(), [&realm, index, range, options]() -> WebIDL::ExceptionOr<JS::Value> {
return retrieve_multiple_items_from_an_index(realm, index, GC::Ref(*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);
return create_a_request_to_retrieve_multiple_items(realm(), GC::Ref(*this), RecordKind::Record, converted_options, {});
}
}

View file

@ -562,68 +562,9 @@ WebIDL::ExceptionOr<GC::Ref<IDBRequest>> IDBObjectStore::get_key(JS::Value query
// https://w3c.github.io/IndexedDB/#dom-idbobjectstore-getall
WebIDL::ExceptionOr<GC::Ref<IDBRequest>> IDBObjectStore::get_all(Optional<JS::Value> query_or_options, Optional<WebIDL::UnsignedLong> count)
{
auto& realm = this->realm();
auto& vm = realm.vm();
// 1. Let transaction be thiss transaction.
auto transaction = this->transaction();
// 2. Let store be thiss object store.
auto store = this->store();
// FIXME: 3. If store has been deleted, throw an "InvalidStateError" DOMException.
// 4. If transactions 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"_utf16);
// 5. Let range be a key range.
GC::Ptr<IDBKeyRange> range;
// 6. Let direction be a cursor direction.
Bindings::IDBCursorDirection direction = Bindings::IDBCursorDirection::Next;
// 7. If running is a potentially valid key range with query_or_options is true, then:
if (is_a_potentially_valid_key_range(realm, *query_or_options)) {
// 1. Set range to the result of converting a value to a key range with query_or_options. Rethrow any exceptions.
range = TRY(convert_a_value_to_a_key_range(realm, query_or_options));
// 2. Set direction to "next".
direction = Bindings::IDBCursorDirection::Next;
}
// 8. Else:
else {
// 1. Set range to the result of converting a value to a key range with query_or_options["query"]. Rethrow any exceptions.
range = TRY(convert_a_value_to_a_key_range(realm, TRY(query_or_options->get(vm, "query"_utf16))));
// 2. Set count to query_or_options["count"].
count = TRY(TRY(query_or_options->get(vm, "count"_utf16)).to_u32(vm));
// 3. Set direction to query_or_options["direction"].
auto direction_value = TRY(TRY(query_or_options->get(vm, "direction"_utf16)).to_string(vm));
if (direction_value == "next")
direction = Bindings::IDBCursorDirection::Next;
else if (direction_value == "nextunique")
direction = Bindings::IDBCursorDirection::Nextunique;
else if (direction_value == "prev")
direction = Bindings::IDBCursorDirection::Prev;
else if (direction_value == "prevunique")
direction = Bindings::IDBCursorDirection::Prevunique;
else
return WebIDL::SimpleException { WebIDL::SimpleExceptionType::TypeError, "Invalid direction value"_string };
}
// 9. Let operation be an algorithm to run retrieve multiple items from an object store with the current Realm record, store, range, "value", direction, and count if given.
auto operation = GC::Function<WebIDL::ExceptionOr<JS::Value>()>::create(realm.heap(), [&realm, store, range, direction, count] -> WebIDL::ExceptionOr<JS::Value> {
return retrieve_multiple_items_from_an_object_store(realm, store, GC::Ref(*range), RecordKind::Value, direction, count);
});
// 10. 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 with uuid {}", result->uuid());
return result;
// 1. Return the result of creating a request to retrieve multiple items with the current Realm record, this,
// "value", queryOrOptions, and count if given. Rethrow any exceptions.
return create_a_request_to_retrieve_multiple_items(realm(), GC::Ref(*this), RecordKind::Value, *query_or_options, count);
}
// https://w3c.github.io/IndexedDB/#dom-idbobjectstore-openkeycursor
@ -668,95 +609,23 @@ WebIDL::ExceptionOr<GC::Ref<IDBRequest>> IDBObjectStore::open_key_cursor(JS::Val
// https://w3c.github.io/IndexedDB/#dom-idbobjectstore-getallkeys
WebIDL::ExceptionOr<GC::Ref<IDBRequest>> IDBObjectStore::get_all_keys(Optional<JS::Value> query_or_options, Optional<WebIDL::UnsignedLong> count)
{
auto& realm = this->realm();
auto& vm = realm.vm();
// 1. Let transaction be thiss transaction.
auto transaction = this->transaction();
// 2. Let store be thiss object store.
auto store = this->store();
// FIXME: 3. If store has been deleted, throw an "InvalidStateError" DOMException.
// 4. If transactions 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 keys"_utf16);
// 5. Let range be a key range.
GC::Ptr<IDBKeyRange> range;
// 6. Let direction be a cursor direction.
Bindings::IDBCursorDirection direction = Bindings::IDBCursorDirection::Next;
// 7. If running is a potentially valid key range with query_or_options is true, then:
if (is_a_potentially_valid_key_range(realm, *query_or_options)) {
// 1. Set range to the result of converting a value to a key range with query_or_options. Rethrow any exceptions.
range = TRY(convert_a_value_to_a_key_range(realm, query_or_options));
// 2. Set direction to "next".
direction = Bindings::IDBCursorDirection::Next;
}
// 8. Else:
else {
// 1. Set range to the result of converting a value to a key range with query_or_options["query"]. Rethrow any exceptions.
range = TRY(convert_a_value_to_a_key_range(realm, TRY(query_or_options->get(vm, "query"_utf16))));
// 2. Set count to query_or_options["count"].
count = TRY(TRY(query_or_options->get(vm, "count"_utf16)).to_u32(vm));
// 3. Set direction to query_or_options["direction"].
auto direction_value = TRY(TRY(query_or_options->get(vm, "direction"_utf16)).to_string(vm));
if (direction_value == "next")
direction = Bindings::IDBCursorDirection::Next;
else if (direction_value == "nextunique")
direction = Bindings::IDBCursorDirection::Nextunique;
else if (direction_value == "prev")
direction = Bindings::IDBCursorDirection::Prev;
else if (direction_value == "prevunique")
direction = Bindings::IDBCursorDirection::Prevunique;
else
return WebIDL::SimpleException { WebIDL::SimpleExceptionType::TypeError, "Invalid direction value"_string };
}
// 9. Let operation be an algorithm to run retrieve multiple items from an object store with the current Realm record, store, range, "key", direction, and count if given.
auto operation = GC::Function<WebIDL::ExceptionOr<JS::Value>()>::create(realm.heap(), [&realm, store, range, direction, count] -> WebIDL::ExceptionOr<JS::Value> {
return retrieve_multiple_items_from_an_object_store(realm, store, GC::Ref(*range), RecordKind::Key, direction, count);
});
// 10. 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;
// 1. Return the result of creating a request to retrieve multiple items with the current Realm record, this, "key",
// queryOrOptions, and count if given. Rethrow any exceptions.
return create_a_request_to_retrieve_multiple_items(realm(), GC::Ref(*this), RecordKind::Key, *query_or_options, count);
}
// https://pr-preview.s3.amazonaws.com/w3c/IndexedDB/pull/461.html#dom-idbobjectstore-getallrecords
WebIDL::ExceptionOr<GC::Ref<IDBRequest>> IDBObjectStore::get_all_records(IDBGetAllOptions const& options)
{
auto& realm = this->realm();
// 1. Return the result of creating a request to retrieve multiple items with the current Realm record, this,
// "record", and options. Rethrow any exceptions.
// 1. Let transaction be thiss transaction.
auto transaction = this->transaction();
auto converted_options = JS::Object::create(realm(), nullptr);
MUST(converted_options->create_data_property("query"_utf16_fly_string, options.query));
MUST(converted_options->create_data_property("count"_utf16_fly_string, options.count.has_value() ? JS::Value(options.count.value()) : JS::js_undefined()));
MUST(converted_options->create_data_property("direction"_utf16_fly_string, JS::PrimitiveString::create(realm().vm(), idl_enum_to_string(options.direction))));
// 2. Let store be thiss object store.
auto store = this->store();
// FIXME: 3. If store has been deleted, throw an "InvalidStateError" DOMException.
// 4. If transactions 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<WebIDL::ExceptionOr<JS::Value>()>::create(realm.heap(), [&realm, store, range, options] -> WebIDL::ExceptionOr<JS::Value> {
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);
return create_a_request_to_retrieve_multiple_items(realm(), GC::Ref(*this), RecordKind::Record, converted_options, {});
}
}

View file

@ -2186,6 +2186,7 @@ bool is_a_potentially_valid_key_range(JS::Realm& realm, JS::Value value)
return false;
}
// https://pr-preview.s3.amazonaws.com/w3c/IndexedDB/pull/461.html#retrieve-multiple-items-from-an-index
GC::Ref<JS::Array> retrieve_multiple_items_from_an_index(JS::Realm& target_realm, GC::Ref<Index> index, GC::Ref<IDBKeyRange> range, RecordKind kind, Bindings::IDBCursorDirection direction, Optional<WebIDL::UnsignedLong> count)
{
// 1. If count is not given or is 0 (zero), let count be infinity.
@ -2329,4 +2330,92 @@ GC::Ref<JS::Array> retrieve_multiple_items_from_an_index(JS::Realm& target_realm
return list;
}
// https://pr-preview.s3.amazonaws.com/w3c/IndexedDB/pull/461.html#create-a-request-to-retrieve-multiple-items
WebIDL::ExceptionOr<GC::Ref<IDBRequest>> create_a_request_to_retrieve_multiple_items(JS::Realm& realm, IDBRequestSource source_handle, RecordKind kind, JS::Value query_or_options, Optional<WebIDL::UnsignedLong> count)
{
auto& vm = realm.vm();
// 1. Let source be an index or an object store from sourceHandle.
// If sourceHandle is an index handle, then source is the index handles associated index.
// Otherwise, source is the object store handles associated object store.
auto source = source_handle.visit(
[](Empty) -> Variant<GC::Ref<ObjectStore>, GC::Ref<Index>> { VERIFY_NOT_REACHED(); },
[](GC::Ref<IDBCursor>) -> Variant<GC::Ref<ObjectStore>, GC::Ref<Index>> { VERIFY_NOT_REACHED(); },
[](GC::Ref<IDBIndex> index) -> Variant<GC::Ref<ObjectStore>, GC::Ref<Index>> { return index->index(); },
[](GC::Ref<IDBObjectStore> object_store) -> Variant<GC::Ref<ObjectStore>, GC::Ref<Index>> { return object_store->store(); });
// FIXME: 2. If source has been deleted, throw an "InvalidStateError" DOMException.
// FIXME: 3. If source is an index and sources object store has been deleted, throw an "InvalidStateError" DOMException.
// 4. Let transaction be sourceHandles transaction.
auto transaction = source_handle.visit(
[](Empty) -> GC::Ref<IDBTransaction> { VERIFY_NOT_REACHED(); },
[](GC::Ref<IDBCursor>) -> GC::Ref<IDBTransaction> { VERIFY_NOT_REACHED(); },
[](GC::Ref<IDBIndex> index) -> GC::Ref<IDBTransaction> { return index->transaction(); },
[](GC::Ref<IDBObjectStore> object_store) -> GC::Ref<IDBTransaction> { return object_store->transaction(); });
// 5. If transactions state is not active, then throw a "TransactionInactiveError" DOMException.
if (!transaction->is_active())
return WebIDL::TransactionInactiveError::create(realm, "Transaction is not active while creating retrieve multiple items request"_utf16);
// 6. Let range be a key range.
GC::Ptr<IDBKeyRange> range;
// 7. Let direction be a cursor direction.
Bindings::IDBCursorDirection direction;
// 8. If running is a potentially valid key range with queryOrOptions is true, then:
if (is_a_potentially_valid_key_range(realm, query_or_options)) {
// 1. Set range to the result of converting a value to a key range with queryOrOptions. Rethrow any exceptions.
range = TRY(convert_a_value_to_a_key_range(realm, query_or_options));
// 2. Set direction to "next".
direction = Bindings::IDBCursorDirection::Next;
}
// 9. Else:
else {
// 1. Set range to the result of converting a value to a key range with queryOrOptions["query"]. Rethrow any exceptions.
range = TRY(convert_a_value_to_a_key_range(realm, TRY(query_or_options.get(vm, "query"_utf16))));
// 2. Set count to query_or_options["count"].
count = TRY(TRY(query_or_options.get(vm, "count"_utf16)).to_u32(vm));
// 3. Set direction to query_or_options["direction"].
auto direction_value = TRY(TRY(query_or_options.get(vm, "direction"_utf16)).to_string(vm));
if (direction_value == "next")
direction = Bindings::IDBCursorDirection::Next;
else if (direction_value == "nextunique")
direction = Bindings::IDBCursorDirection::Nextunique;
else if (direction_value == "prev")
direction = Bindings::IDBCursorDirection::Prev;
else if (direction_value == "prevunique")
direction = Bindings::IDBCursorDirection::Prevunique;
else
return WebIDL::SimpleException { WebIDL::SimpleExceptionType::TypeError, "Invalid direction value"_string };
}
// 10. Let operation be an algorithm to run.
auto operation = source.visit(
// 11. If source is an index, set operation to retrieve multiple items from an index with targetRealm, source, range, kind, direction, and count if given.
[&](GC::Ref<Index> index) {
return GC::create_function(realm.heap(),
[&realm, index, range, kind, direction, count]() -> WebIDL::ExceptionOr<JS::Value> {
return retrieve_multiple_items_from_an_index(realm, index, GC::Ref(*range), kind, direction, count);
});
},
// 12. Else set operation to retrieve multiple items from an object store with targetRealm, source, range, kind, direction, and count if given.
[&](GC::Ref<ObjectStore> object_store) {
return GC::create_function(realm.heap(),
[&realm, object_store, range, kind, direction, count]() -> WebIDL::ExceptionOr<JS::Value> {
return retrieve_multiple_items_from_an_object_store(realm, object_store, GC::Ref(*range), kind, direction, count);
});
});
// 13. Return the result (an IDBRequest) of running asynchronously execute a request with sourceHandle and operation.
auto result = asynchronously_execute_a_request(realm, source_handle, operation);
dbgln_if(IDB_DEBUG, "Executing request for creating retrieve multiple items request with uuid {}", result->uuid());
return result;
}
}

View file

@ -68,5 +68,6 @@ bool cleanup_indexed_database_transactions(GC::Ref<HTML::EventLoop>);
bool is_a_potentially_valid_key_range(JS::Realm&, JS::Value);
GC::Ref<JS::Array> retrieve_multiple_items_from_an_object_store(JS::Realm&, GC::Ref<ObjectStore>, GC::Ref<IDBKeyRange>, RecordKind, Bindings::IDBCursorDirection, Optional<WebIDL::UnsignedLong>);
GC::Ref<JS::Array> retrieve_multiple_items_from_an_index(JS::Realm&, GC::Ref<Index>, GC::Ref<IDBKeyRange>, RecordKind, Bindings::IDBCursorDirection, Optional<WebIDL::UnsignedLong>);
WebIDL::ExceptionOr<GC::Ref<IDBRequest>> create_a_request_to_retrieve_multiple_items(JS::Realm&, IDBRequestSource, RecordKind, JS::Value, Optional<WebIDL::UnsignedLong>);
}