Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions Libraries/LibWeb/IndexedDB/IDBRequest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,11 @@ GC::Ref<IDBRequest> IDBRequest::create(JS::Realm& realm, IDBRequestSource source
void IDBRequest::visit_edges(Visitor& visitor)
{
Base::visit_edges(visitor);
visitor.visit(m_error);
visitor.visit(m_result);
visitor.visit(m_transaction);

if (m_error.has_value())
visitor.visit(*m_error);
}

// https://w3c.github.io/IndexedDB/#dom-idbrequest-onsuccess
Expand Down Expand Up @@ -83,7 +85,7 @@ WebIDL::CallbackType* IDBRequest::onerror()
return WebIDL::InvalidStateError::create(realm(), "The request is not done"_string);

// 2. Otherwise, return this's error, or null if no error occurred.
return m_error;
return m_error.value_or(nullptr);
}

// https://w3c.github.io/IndexedDB/#dom-idbrequest-result
Expand All @@ -94,7 +96,7 @@ WebIDL::CallbackType* IDBRequest::onerror()
return WebIDL::InvalidStateError::create(realm(), "The request is not done"_string);

// 2. Otherwise, return this's result, or undefined if the request resulted in an error.
if (m_error)
if (m_error.has_value())
return JS::js_undefined();

return m_result;
Expand Down
6 changes: 4 additions & 2 deletions Libraries/LibWeb/IndexedDB/IDBRequest.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,13 @@ class IDBRequest : public DOM::EventTarget {

void set_done(bool done) { m_done = done; }
void set_result(JS::Value result) { m_result = result; }
void set_error(GC::Ptr<WebIDL::DOMException> error) { m_error = error; }
void set_error(Optional<GC::Ptr<WebIDL::DOMException>> error) { m_error = error; }
void set_processed(bool processed) { m_processed = processed; }
void set_source(IDBRequestSource source) { m_source = source; }
void set_transaction(GC::Ptr<IDBTransaction> transaction) { m_transaction = transaction; }

bool has_error() const { return m_error.has_value(); }

void set_onsuccess(WebIDL::CallbackType*);
WebIDL::CallbackType* onsuccess();
void set_onerror(WebIDL::CallbackType*);
Expand All @@ -63,7 +65,7 @@ class IDBRequest : public DOM::EventTarget {

// A request has a result and an error
JS::Value m_result;
GC::Ptr<WebIDL::DOMException> m_error;
Optional<GC::Ptr<WebIDL::DOMException>> m_error;

// A request has a source object.
IDBRequestSource m_source;
Expand Down
3 changes: 1 addition & 2 deletions Libraries/LibWeb/IndexedDB/IDBTransaction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,7 @@ WebIDL::ExceptionOr<void> IDBTransaction::abort()
if (m_state == TransactionState::Committing || m_state == TransactionState::Finished)
return WebIDL::InvalidStateError::create(realm(), "Transaction is ending"_string);

// 2. Set this's state to inactive and run abort a transaction with this and null.
m_state = TransactionState::Inactive;
// 2. Run abort a transaction with this and null.
abort_a_transaction(*this, nullptr);
return {};
}
Expand Down
32 changes: 16 additions & 16 deletions Libraries/LibWeb/IndexedDB/Internal/Algorithms.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -164,16 +164,15 @@ WebIDL::ExceptionOr<GC::Ref<IDBDatabase>> open_a_database_connection(JS::Realm&
}));

// 6. Run upgrade a database using connection, version and request.
// AD-HOC: https://github.com/w3c/IndexedDB/issues/433#issuecomment-2512330086
auto upgrade_transaction = upgrade_a_database(realm, connection, version, request);
upgrade_a_database(realm, connection, version, request);

// 7. If connection was closed, return a newly created "AbortError" DOMException and abort these steps.
if (connection->state() == IDBDatabase::ConnectionState::Closed)
return WebIDL::AbortError::create(realm, "Connection was closed"_string);

// 8. If the upgrade transaction was aborted, run the steps to close a database connection with connection,
// 8. If request's error is set, run the steps to close a database connection with connection,
// return a newly created "AbortError" DOMException and abort these steps.
if (upgrade_transaction->aborted()) {
if (request->has_error()) {
close_a_database_connection(*connection);
return WebIDL::AbortError::create(realm, "Upgrade transaction was aborted"_string);
}
Expand Down Expand Up @@ -360,7 +359,7 @@ void close_a_database_connection(GC::Ref<IDBDatabase> connection, bool forced)
}

// https://w3c.github.io/IndexedDB/#upgrade-a-database
GC::Ref<IDBTransaction> upgrade_a_database(JS::Realm& realm, GC::Ref<IDBDatabase> connection, u64 version, GC::Ref<IDBRequest> request)
void upgrade_a_database(JS::Realm& realm, GC::Ref<IDBDatabase> connection, u64 version, GC::Ref<IDBRequest> request)
{
// 1. Let db be connection’s database.
auto db = connection->associated_database();
Expand Down Expand Up @@ -431,8 +430,6 @@ GC::Ref<IDBTransaction> upgrade_a_database(JS::Realm& realm, GC::Ref<IDBDatabase
dbgln_if(IDB_DEBUG, "upgrade_a_database: waiting for step 11");
return transaction->is_finished();
}));

return transaction;
}

// https://w3c.github.io/IndexedDB/#deleting-a-database
Expand Down Expand Up @@ -540,22 +537,25 @@ void abort_a_transaction(GC::Ref<IDBTransaction> transaction, GC::Ptr<WebIDL::DO
transaction->set_aborted(true);
dbgln_if(IDB_DEBUG, "abort_a_transaction: transaction {} is aborting", transaction->uuid());

// FIXME: 1. All the changes made to the database by the transaction are reverted.
// 1. If transaction is finished, abort these steps.
if (transaction->is_finished())
return;

// FIXME: 2. All the changes made to the database by the transaction are reverted.
// For upgrade transactions this includes changes to the set of object stores and indexes, as well as the change to the version.
// Any object stores and indexes which were created during the transaction are now considered deleted for the purposes of other algorithms.

// FIXME: 2. If transaction is an upgrade transaction, run the steps to abort an upgrade transaction with transaction.
// FIXME: 3. If transaction is an upgrade transaction, run the steps to abort an upgrade transaction with transaction.
// if (transaction.is_upgrade_transaction())
// abort_an_upgrade_transaction(transaction);

// 3. Set transaction’s state to finished.
// 4. Set transaction’s state to finished.
transaction->set_state(IDBTransaction::TransactionState::Finished);

// 4. If error is not null, set transaction’s error to error.
if (error)
transaction->set_error(error);
// 5. Set transaction’s error to error.
transaction->set_error(error);

// 5. For each request of transaction’s request list,
// 6. For each request of transaction’s request list,
for (auto const& request : transaction->request_list()) {
// FIXME: abort the steps to asynchronously execute a request for request,

Expand All @@ -578,7 +578,7 @@ void abort_a_transaction(GC::Ref<IDBTransaction> transaction, GC::Ptr<WebIDL::DO
}));
}

// 6. Queue a database task to run these steps:
// 7. Queue a database task to run these steps:
queue_a_database_task(GC::create_function(transaction->realm().vm().heap(), [transaction]() {
// 1. If transaction is an upgrade transaction, then set transaction’s connection's associated database's upgrade transaction to null.
if (transaction->is_upgrade_transaction())
Expand Down Expand Up @@ -1209,7 +1209,7 @@ GC::Ref<IDBRequest> asynchronously_execute_a_request(JS::Realm& realm, IDBReques
request->set_result(result.release_value());

// 2. Set request’s error to undefined.
request->set_error(nullptr);
request->set_error(Optional<GC::Ptr<WebIDL::DOMException>> {});

// 3. Fire a success event at request.
fire_a_success_event(realm, request);
Expand Down
2 changes: 1 addition & 1 deletion Libraries/LibWeb/IndexedDB/Internal/Algorithms.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ WebIDL::ExceptionOr<GC::Ref<IDBDatabase>> open_a_database_connection(JS::Realm&,
bool fire_a_version_change_event(JS::Realm&, FlyString const&, GC::Ref<DOM::EventTarget>, u64, Optional<u64>);
WebIDL::ExceptionOr<GC::Ref<Key>> convert_a_value_to_a_key(JS::Realm&, JS::Value, Vector<JS::Value> = {});
void close_a_database_connection(GC::Ref<IDBDatabase>, bool forced = false);
GC::Ref<IDBTransaction> upgrade_a_database(JS::Realm&, GC::Ref<IDBDatabase>, u64, GC::Ref<IDBRequest>);
void upgrade_a_database(JS::Realm&, GC::Ref<IDBDatabase>, u64, GC::Ref<IDBRequest>);
WebIDL::ExceptionOr<u64> delete_a_database(JS::Realm&, StorageAPI::StorageKey, String, GC::Ref<IDBRequest>);
void abort_a_transaction(GC::Ref<IDBTransaction>, GC::Ptr<WebIDL::DOMException>);
JS::Value convert_a_key_to_a_value(JS::Realm&, GC::Ref<Key>);
Expand Down
21 changes: 21 additions & 0 deletions Libraries/LibWeb/IndexedDB/Internal/Key.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -165,4 +165,25 @@ i8 Key::compare_two_keys(GC::Ref<Key> a, GC::Ref<Key> b)
VERIFY_NOT_REACHED();
}

String Key::dump() const
{
return m_value.visit(
[](Vector<GC::Root<Key>> const& value) {
StringBuilder sb;
sb.append("["sv);
for (auto const& key : value) {
sb.append(key->dump());
sb.append(", "sv);
}
sb.append("]"sv);
return MUST(sb.to_string());
},
[](ByteBuffer const& value) {
return MUST(String::formatted("{}", value.span()));
},
[](auto const& value) {
return MUST(String::formatted("{}", value));
});
}

}
2 changes: 2 additions & 0 deletions Libraries/LibWeb/IndexedDB/Internal/Key.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ class Key : public JS::Cell {
[[nodiscard]] static bool less_than(GC::Ref<Key> a, GC::Ref<Key> b) { return compare_two_keys(a, b) < 0; }
[[nodiscard]] static bool greater_than(GC::Ref<Key> a, GC::Ref<Key> b) { return compare_two_keys(a, b) > 0; }

AK::String dump() const;

private:
Key(KeyType type, KeyValue value)
: m_type(type)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,26 +4,26 @@ Found 24 tests

24 Pass
Pass Database readback sort - String < Array
Pass IDBKey.cmp sorted - String < Array
Pass IDBKey.cmp sort - String < Array
Pass Database readback sort - float < String
Pass IDBKey.cmp sorted - float < String
Pass IDBKey.cmp sort - float < String
Pass Database readback sort - float < Date
Pass IDBKey.cmp sorted - float < Date
Pass IDBKey.cmp sort - float < Date
Pass Database readback sort - float < Date < String < Array
Pass IDBKey.cmp sorted - float < Date < String < Array
Pass IDBKey.cmp sort - float < Date < String < Array
Pass Database readback sort - Date(1 sec ago) < Date(now) < Date(1 minute in future)
Pass IDBKey.cmp sorted - Date(1 sec ago) < Date(now) < Date(1 minute in future)
Pass IDBKey.cmp sort - Date(1 sec ago) < Date(now) < Date(1 minute in future)
Pass Database readback sort - -1.1 < 1 < 1.01337 < 1.013373 < 2
Pass IDBKey.cmp sorted - -1.1 < 1 < 1.01337 < 1.013373 < 2
Pass IDBKey.cmp sort - -1.1 < 1 < 1.01337 < 1.013373 < 2
Pass Database readback sort - -Infinity < -0.01 < 0 < Infinity
Pass IDBKey.cmp sorted - -Infinity < -0.01 < 0 < Infinity
Pass IDBKey.cmp sort - -Infinity < -0.01 < 0 < Infinity
Pass Database readback sort - "" < "a" < "ab" < "b" < "ba"
Pass IDBKey.cmp sorted - "" < "a" < "ab" < "b" < "ba"
Pass IDBKey.cmp sort - "" < "a" < "ab" < "b" < "ba"
Pass Database readback sort - Arrays
Pass IDBKey.cmp sorted - Arrays
Pass IDBKey.cmp sort - Arrays
Pass Database readback sort - Array.length: 10,000 < Array.length: 10,001
Pass IDBKey.cmp sorted - Array.length: 10,000 < Array.length: 10,001
Pass IDBKey.cmp sort - Array.length: 10,000 < Array.length: 10,001
Pass Database readback sort - Infinity inside arrays
Pass IDBKey.cmp sorted - Infinity inside arrays
Pass IDBKey.cmp sort - Infinity inside arrays
Pass Database readback sort - Test different stuff at once
Pass IDBKey.cmp sorted - Test different stuff at once
Pass IDBKey.cmp sort - Test different stuff at once
15 changes: 15 additions & 0 deletions Tests/LibWeb/Text/input/wpt-import/IndexedDB/keyorder.any.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<!doctype html>
<meta charset=utf-8>
<title>Key sort order</title>
<script>
self.GLOBAL = {
isWindow: function() { return true; },
isWorker: function() { return false; },
isShadowRealm: function() { return false; },
};
</script>
<script src="../resources/testharness.js"></script>
<script src="../resources/testharnessreport.js"></script>
<script src="resources/support.js"></script>
<div id=log></div>
<script src="../IndexedDB/keyorder.any.js"></script>
Loading
Loading