LibWeb/IDB: Implement IDBDatabase::deleteObjectStore

This commit is contained in:
stelar7 2025-03-24 21:59:58 +01:00 committed by Jelle Raaijmakers
parent b11276e5c4
commit 209d05fcb4
Notes: github-actions[bot] 2025-03-27 15:48:47 +00:00
6 changed files with 49 additions and 7 deletions

View file

@ -116,7 +116,7 @@ WebIDL::ExceptionOr<GC::Ref<IDBObjectStore>> 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 optionss autoIncrement member.
@ -150,4 +150,37 @@ GC::Ref<HTML::DOMStringList> IDBDatabase::object_store_names()
return create_a_sorted_name_list(realm(), names);
}
// https://w3c.github.io/IndexedDB/#dom-idbdatabase-deleteobjectstore
WebIDL::ExceptionOr<void> 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 databases 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 transactions 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 {};
}
}

View file

@ -52,9 +52,14 @@ public:
[[nodiscard]] ConnectionState state() const { return m_state; }
[[nodiscard]] GC::Ref<Database> associated_database() { return m_associated_database; }
[[nodiscard]] ReadonlySpan<GC::Ref<ObjectStore>> object_store_set() { return m_object_store_set; }
void remove_from_object_store_set(GC::Ref<ObjectStore> object_store)
{
m_object_store_set.remove_first_matching([&](auto& entry) { return entry == object_store; });
}
[[nodiscard]] GC::Ref<HTML::DOMStringList> object_store_names();
WebIDL::ExceptionOr<GC::Ref<IDBObjectStore>> create_object_store(String const&, IDBObjectStoreParameters const&);
WebIDL::ExceptionOr<void> delete_object_store(String const&);
void close();

View file

@ -11,7 +11,7 @@ interface IDBDatabase : EventTarget {
[FIXME, NewObject] IDBTransaction transaction((DOMString or sequence<DOMString>) 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;

View file

@ -89,7 +89,7 @@ WebIDL::ExceptionOr<void> IDBObjectStore::set_name(String const& value)
return {};
// 8. If an object store named name already exists in stores 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 stores name to name.

View file

@ -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<ObjectStore> 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<GC::Root<Database>> Database::for_key(StorageAPI::StorageKey const& key)

View file

@ -41,8 +41,12 @@ public:
}
ReadonlySpan<GC::Ref<ObjectStore>> object_stores() { return m_object_stores; }
bool has_object_store_named(String const& name) const;
GC::Ptr<ObjectStore> object_store_with_name(String const& name) const;
void add_object_store(GC::Ref<ObjectStore> object_store) { m_object_stores.append(object_store); }
void remove_object_store(GC::Ref<ObjectStore> object_store)
{
m_object_stores.remove_first_matching([&](auto& entry) { return entry == object_store; });
}
[[nodiscard]] static Vector<GC::Root<Database>> for_key(StorageAPI::StorageKey const&);
[[nodiscard]] static Optional<GC::Root<Database> const&> for_key_and_name(StorageAPI::StorageKey&, String&);