diff --git a/Libraries/LibWeb/IndexedDB/IDBDatabase.cpp b/Libraries/LibWeb/IndexedDB/IDBDatabase.cpp index 339a804bc0e..53592e9ddd6 100644 --- a/Libraries/LibWeb/IndexedDB/IDBDatabase.cpp +++ b/Libraries/LibWeb/IndexedDB/IDBDatabase.cpp @@ -116,7 +116,7 @@ WebIDL::ExceptionOr> IDBDatabase::create_object_store(St return WebIDL::SyntaxError::create(realm, "Invalid key path"_string); // 6. If an object store named name already exists in database throw a "ConstraintError" DOMException. - if (database->has_object_store_named(name)) + if (database->object_store_with_name(name)) return WebIDL::ConstraintError::create(realm, "Object store already exists"_string); // 7. Let autoIncrement be options’s autoIncrement member. @@ -150,4 +150,37 @@ GC::Ref IDBDatabase::object_store_names() return create_a_sorted_name_list(realm(), names); } +// https://w3c.github.io/IndexedDB/#dom-idbdatabase-deleteobjectstore +WebIDL::ExceptionOr IDBDatabase::delete_object_store(String const& name) +{ + auto& realm = this->realm(); + + // 1. Let database be this's associated database. + auto database = associated_database(); + + // 2. Let transaction be database’s upgrade transaction if it is not null, or throw an "InvalidStateError" DOMException otherwise. + auto transaction = database->upgrade_transaction(); + if (!transaction) + return WebIDL::InvalidStateError::create(realm, "Upgrade transaction is null"_string); + + // 3. If transaction’s state is not active, then throw a "TransactionInactiveError" DOMException. + if (transaction->state() != IDBTransaction::TransactionState::Active) + return WebIDL::TransactionInactiveError::create(realm, "Transaction is not active"_string); + + // 4. Let store be the object store named name in database, or throw a "NotFoundError" DOMException if none. + auto store = database->object_store_with_name(name); + if (!store) + return WebIDL::NotFoundError::create(realm, "Object store not found"_string); + + // 5. Remove store from this's object store set. + this->remove_from_object_store_set(*store); + + // FIXME: 6. If there is an object store handle associated with store and transaction, remove all entries from its index set. + + // 7. Destroy store. + database->remove_object_store(*store); + + return {}; +} + } diff --git a/Libraries/LibWeb/IndexedDB/IDBDatabase.h b/Libraries/LibWeb/IndexedDB/IDBDatabase.h index fa184b8c5cc..69fa58e3b57 100644 --- a/Libraries/LibWeb/IndexedDB/IDBDatabase.h +++ b/Libraries/LibWeb/IndexedDB/IDBDatabase.h @@ -52,9 +52,14 @@ public: [[nodiscard]] ConnectionState state() const { return m_state; } [[nodiscard]] GC::Ref associated_database() { return m_associated_database; } [[nodiscard]] ReadonlySpan> object_store_set() { return m_object_store_set; } + void remove_from_object_store_set(GC::Ref object_store) + { + m_object_store_set.remove_first_matching([&](auto& entry) { return entry == object_store; }); + } [[nodiscard]] GC::Ref object_store_names(); WebIDL::ExceptionOr> create_object_store(String const&, IDBObjectStoreParameters const&); + WebIDL::ExceptionOr delete_object_store(String const&); void close(); diff --git a/Libraries/LibWeb/IndexedDB/IDBDatabase.idl b/Libraries/LibWeb/IndexedDB/IDBDatabase.idl index d08d74008fb..af526a21863 100644 --- a/Libraries/LibWeb/IndexedDB/IDBDatabase.idl +++ b/Libraries/LibWeb/IndexedDB/IDBDatabase.idl @@ -11,7 +11,7 @@ interface IDBDatabase : EventTarget { [FIXME, NewObject] IDBTransaction transaction((DOMString or sequence) storeNames, optional IDBTransactionMode mode = "readonly", optional IDBTransactionOptions options = {}); undefined close(); [NewObject] IDBObjectStore createObjectStore(DOMString name, optional IDBObjectStoreParameters options = {}); - [FIXME] undefined deleteObjectStore(DOMString name); + undefined deleteObjectStore(DOMString name); // Event handlers: attribute EventHandler onabort; diff --git a/Libraries/LibWeb/IndexedDB/IDBObjectStore.cpp b/Libraries/LibWeb/IndexedDB/IDBObjectStore.cpp index ddb006c42d7..fbbcbe1c205 100644 --- a/Libraries/LibWeb/IndexedDB/IDBObjectStore.cpp +++ b/Libraries/LibWeb/IndexedDB/IDBObjectStore.cpp @@ -89,7 +89,7 @@ WebIDL::ExceptionOr IDBObjectStore::set_name(String const& value) return {}; // 8. If an object store named name already exists in store’s database, throw a "ConstraintError" DOMException. - if (store->database()->has_object_store_named(name)) + if (store->database()->object_store_with_name(name)) return WebIDL::ConstraintError::create(realm, "Object store with the given name already exists"_string); // 9. Set store’s name to name. diff --git a/Libraries/LibWeb/IndexedDB/Internal/Database.cpp b/Libraries/LibWeb/IndexedDB/Internal/Database.cpp index 96f414763bd..e02d0e38c52 100644 --- a/Libraries/LibWeb/IndexedDB/Internal/Database.cpp +++ b/Libraries/LibWeb/IndexedDB/Internal/Database.cpp @@ -29,14 +29,14 @@ void Database::visit_edges(Visitor& visitor) visitor.visit(m_object_stores); } -bool Database::has_object_store_named(String const& name) const +GC::Ptr Database::object_store_with_name(String const& name) const { for (auto const& object_store : m_object_stores) { if (object_store->name() == name) - return true; + return object_store; } - return false; + return nullptr; } Vector> Database::for_key(StorageAPI::StorageKey const& key) diff --git a/Libraries/LibWeb/IndexedDB/Internal/Database.h b/Libraries/LibWeb/IndexedDB/Internal/Database.h index c2d5378dace..ebc5c24485d 100644 --- a/Libraries/LibWeb/IndexedDB/Internal/Database.h +++ b/Libraries/LibWeb/IndexedDB/Internal/Database.h @@ -41,8 +41,12 @@ public: } ReadonlySpan> object_stores() { return m_object_stores; } - bool has_object_store_named(String const& name) const; + GC::Ptr object_store_with_name(String const& name) const; void add_object_store(GC::Ref object_store) { m_object_stores.append(object_store); } + void remove_object_store(GC::Ref object_store) + { + m_object_stores.remove_first_matching([&](auto& entry) { return entry == object_store; }); + } [[nodiscard]] static Vector> for_key(StorageAPI::StorageKey const&); [[nodiscard]] static Optional const&> for_key_and_name(StorageAPI::StorageKey&, String&);