diff --git a/Libraries/LibWeb/IndexedDB/IDBTransaction.h b/Libraries/LibWeb/IndexedDB/IDBTransaction.h index d1fea580ca1..14881a69dd0 100644 --- a/Libraries/LibWeb/IndexedDB/IDBTransaction.h +++ b/Libraries/LibWeb/IndexedDB/IDBTransaction.h @@ -37,11 +37,13 @@ public: [[nodiscard]] GC::Ref connection() const { return m_connection; } [[nodiscard]] Bindings::IDBTransactionDurability durability() const { return m_durability; } [[nodiscard]] GC::Ptr 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 error) { m_error = error; } void set_associated_request(GC::Ptr 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 m_error; GC::Ptr m_associated_request; + bool m_aborted { false }; }; } diff --git a/Libraries/LibWeb/IndexedDB/Internal/Algorithms.cpp b/Libraries/LibWeb/IndexedDB/Internal/Algorithms.cpp index f846f4058da..6e27eef42f9 100644 --- a/Libraries/LibWeb/IndexedDB/Internal/Algorithms.cpp +++ b/Libraries/LibWeb/IndexedDB/Internal/Algorithms.cpp @@ -126,8 +126,13 @@ WebIDL::ExceptionOr> 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 delete_a_database(JS::Realm& realm, StorageAPI::Storage // https://w3c.github.io/IndexedDB/#abort-a-transaction void abort_a_transaction(IDBTransaction& transaction, GC::Ptr 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. diff --git a/Libraries/LibWeb/IndexedDB/Internal/Database.h b/Libraries/LibWeb/IndexedDB/Internal/Database.h index 8550eaa59ac..d5a150129ae 100644 --- a/Libraries/LibWeb/IndexedDB/Internal/Database.h +++ b/Libraries/LibWeb/IndexedDB/Internal/Database.h @@ -25,6 +25,7 @@ public: String name() const { return m_name; } void set_upgrade_transaction(GC::Ptr transaction) { m_upgrade_transaction = transaction; } + [[nodiscard]] GC::Ptr upgrade_transaction() { return m_upgrade_transaction; } void associate(GC::Ref connection) { m_associated_connections.append(connection); } ReadonlySpan> associated_connections() { return m_associated_connections; } diff --git a/Tests/LibWeb/Text/expected/wpt-import/IndexedDB/idbfactory_open.any.txt b/Tests/LibWeb/Text/expected/wpt-import/IndexedDB/idbfactory_open.any.txt index fbdc931772c..ea29667c7b6 100644 --- a/Tests/LibWeb/Text/expected/wpt-import/IndexedDB/idbfactory_open.any.txt +++ b/Tests/LibWeb/Text/expected/wpt-import/IndexedDB/idbfactory_open.any.txt @@ -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 \ No newline at end of file