LibWeb: Close the database if the upgrade connection is aborted

This commit is contained in:
stelar7 2024-12-01 22:52:33 +01:00 committed by Jelle Raaijmakers
parent 0b8f2a8b81
commit a25bba27fa
Notes: github-actions[bot] 2024-12-14 22:04:06 +00:00
4 changed files with 20 additions and 8 deletions

View file

@ -37,11 +37,13 @@ public:
[[nodiscard]] GC::Ref<IDBDatabase> connection() const { return m_connection; }
[[nodiscard]] Bindings::IDBTransactionDurability durability() const { return m_durability; }
[[nodiscard]] GC::Ptr<IDBRequest> associated_request() const { return m_associated_request; }
[[nodiscard]] bool aborted() const { return m_aborted; }
void set_mode(Bindings::IDBTransactionMode mode) { m_mode = mode; }
void set_state(TransactionState state) { m_state = state; }
void set_error(GC::Ptr<WebIDL::DOMException> error) { m_error = error; }
void set_associated_request(GC::Ptr<IDBRequest> request) { m_associated_request = request; }
void set_aborted(bool aborted) { m_aborted = aborted; }
[[nodiscard]] bool is_upgrade_transaction() const { return m_mode == Bindings::IDBTransactionMode::Versionchange; }
[[nodiscard]] bool is_readonly() const { return m_mode == Bindings::IDBTransactionMode::Readonly; }
@ -69,5 +71,6 @@ private:
GC::Ptr<WebIDL::DOMException> m_error;
GC::Ptr<IDBRequest> m_associated_request;
bool m_aborted { false };
};
}

View file

@ -126,8 +126,13 @@ WebIDL::ExceptionOr<GC::Ref<IDBDatabase>> open_a_database_connection(JS::Realm&
return WebIDL::AbortError::create(realm, "Connection was closed"_string);
}
// FIXME: 8. If the upgrade transaction was aborted, run the steps to close a database connection with connection,
// return a newly created "AbortError" DOMException and abort these steps.
// 8. If the upgrade transaction was aborted, run the steps to close a database connection with connection,
// return a newly created "AbortError" DOMException and abort these steps.
auto transaction = connection->associated_database()->upgrade_transaction();
if (transaction->aborted()) {
close_a_database_connection(*connection, true);
return WebIDL::AbortError::create(realm, "Upgrade transaction was aborted"_string);
}
}
// 11. Return connection.
@ -433,6 +438,9 @@ WebIDL::ExceptionOr<u64> delete_a_database(JS::Realm& realm, StorageAPI::Storage
// https://w3c.github.io/IndexedDB/#abort-a-transaction
void abort_a_transaction(IDBTransaction& transaction, GC::Ptr<WebIDL::DOMException> error)
{
// NOTE: This is not spec'ed anywhere, but we need to know IF the transaction was aborted.
transaction.set_aborted(true);
// FIXME: 1. 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.

View file

@ -25,6 +25,7 @@ public:
String name() const { return m_name; }
void set_upgrade_transaction(GC::Ptr<IDBTransaction> transaction) { m_upgrade_transaction = transaction; }
[[nodiscard]] GC::Ptr<IDBTransaction> upgrade_transaction() { return m_upgrade_transaction; }
void associate(GC::Ref<IDBDatabase> connection) { m_associated_connections.append(connection); }
ReadonlySpan<GC::Ref<IDBDatabase>> associated_connections() { return m_associated_connections; }

View file

@ -2,8 +2,8 @@ Harness status: OK
Found 29 tests
23 Pass
6 Fail
27 Pass
2 Fail
Pass IDBFactory.open() - request has no source
Pass IDBFactory.open() - database 'name' and 'version' are correctly set
Pass IDBFactory.open() - no version opens current database
@ -11,7 +11,7 @@ Pass IDBFactory.open() - new database has default version
Pass IDBFactory.open() - new database is empty
Pass IDBFactory.open() - open database with a lower version than current
Pass IDBFactory.open() - open database with a higher version than current
Fail IDBFactory.open() - error in version change transaction aborts open
Pass IDBFactory.open() - error in version change transaction aborts open
Pass Calling open() with version argument -1 should throw TypeError.
Pass Calling open() with version argument -0.5 should throw TypeError.
Pass Calling open() with version argument 0 should throw TypeError.
@ -27,9 +27,9 @@ Pass Calling open() with version argument false should throw TypeError.
Pass Calling open() with version argument object should throw TypeError.
Pass Calling open() with version argument object (second) should throw TypeError.
Pass Calling open() with version argument object (third) should throw TypeError.
Fail Calling open() with version argument 1.5 should not throw.
Fail Calling open() with version argument 9007199254740991 should not throw.
Fail Calling open() with version argument undefined should not throw.
Pass Calling open() with version argument 1.5 should not throw.
Pass Calling open() with version argument 9007199254740991 should not throw.
Pass Calling open() with version argument undefined should not throw.
Fail IDBFactory.open() - error in upgradeneeded resets db
Fail IDBFactory.open() - second open's transaction is available to get objectStores
Pass IDBFactory.open() - upgradeneeded gets VersionChangeEvent