diff --git a/Libraries/LibWeb/CMakeLists.txt b/Libraries/LibWeb/CMakeLists.txt index 31417efeebc..f68a045d40f 100644 --- a/Libraries/LibWeb/CMakeLists.txt +++ b/Libraries/LibWeb/CMakeLists.txt @@ -560,6 +560,7 @@ set(SOURCES IndexedDB/Internal/Algorithms.cpp IndexedDB/Internal/Database.cpp IndexedDB/Internal/Key.cpp + IndexedDB/Internal/ObjectStore.cpp IndexedDB/Internal/RequestList.cpp Internals/InternalAnimationTimeline.cpp Internals/Internals.cpp diff --git a/Libraries/LibWeb/Forward.h b/Libraries/LibWeb/Forward.h index 32c4a802ad2..91e44f3acc6 100644 --- a/Libraries/LibWeb/Forward.h +++ b/Libraries/LibWeb/Forward.h @@ -620,6 +620,7 @@ class IDBOpenDBRequest; class IDBRequest; class IDBTransaction; class IDBVersionChangeEvent; +class ObjectStore; class RequestList; } diff --git a/Libraries/LibWeb/IndexedDB/Internal/Database.cpp b/Libraries/LibWeb/IndexedDB/Internal/Database.cpp index 948976cfa8a..174ef6bafc8 100644 --- a/Libraries/LibWeb/IndexedDB/Internal/Database.cpp +++ b/Libraries/LibWeb/IndexedDB/Internal/Database.cpp @@ -26,6 +26,7 @@ void Database::visit_edges(Visitor& visitor) Base::visit_edges(visitor); visitor.visit(m_associated_connections); visitor.visit(m_upgrade_transaction); + visitor.visit(m_object_stores); } 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 b980e9c87a6..3dd705ee6be 100644 --- a/Libraries/LibWeb/IndexedDB/Internal/Database.h +++ b/Libraries/LibWeb/IndexedDB/Internal/Database.h @@ -10,6 +10,7 @@ #include #include #include +#include #include namespace Web::IndexedDB { @@ -61,8 +62,6 @@ protected: private: Vector> m_associated_connections; - // FIXME: A database has zero or more object stores which hold the data stored in the database. - // A database has a name which identifies it within a specific storage key. String m_name; @@ -71,6 +70,9 @@ private: // A database has at most one associated upgrade transaction, which is either null or an upgrade transaction, and is initially null. GC::Ptr m_upgrade_transaction; + + // A database has zero or more object stores which hold the data stored in the database. + Vector> m_object_stores; }; } diff --git a/Libraries/LibWeb/IndexedDB/Internal/ObjectStore.cpp b/Libraries/LibWeb/IndexedDB/Internal/ObjectStore.cpp new file mode 100644 index 00000000000..a92cc6096cc --- /dev/null +++ b/Libraries/LibWeb/IndexedDB/Internal/ObjectStore.cpp @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2025, stelar7 + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include + +namespace Web::IndexedDB { + +GC_DEFINE_ALLOCATOR(ObjectStore); + +ObjectStore::~ObjectStore() = default; + +GC::Ref ObjectStore::create(JS::Realm& realm, String name, bool auto_increment, Optional const& key_path) +{ + return realm.create(name, auto_increment, key_path); +} + +} diff --git a/Libraries/LibWeb/IndexedDB/Internal/ObjectStore.h b/Libraries/LibWeb/IndexedDB/Internal/ObjectStore.h new file mode 100644 index 00000000000..4a6e1dc98fd --- /dev/null +++ b/Libraries/LibWeb/IndexedDB/Internal/ObjectStore.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2025, stelar7 + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace Web::IndexedDB { + +using KeyPath = Variant>; + +// https://w3c.github.io/IndexedDB/#object-store-construct +class ObjectStore : public JS::Cell { + GC_CELL(ObjectStore, JS::Cell); + GC_DECLARE_ALLOCATOR(ObjectStore); + +public: + [[nodiscard]] static GC::Ref create(JS::Realm&, String, bool, Optional const&); + virtual ~ObjectStore(); + + String name() const { return m_name; } + Optional key_path() const { return m_key_path; } + bool uses_inline_keys() const { return m_key_path.has_value(); } + bool uses_out_of_line_keys() const { return !m_key_path.has_value(); } + + // The autoIncrement getter steps are to return true if this’s object store has a key generator, and false otherwise. + bool auto_increment() const { return m_key_generator.has_value(); } + +private: + ObjectStore(String name, bool auto_increment, Optional const& key_path) + : m_name(move(name)) + , m_key_path(key_path) + { + if (auto_increment) + m_key_generator = KeyGenerator {}; + } + + // An object store has a name, which is a name. At any one time, the name is unique within the database to which it belongs. + String m_name; + + // An object store optionally has a key path. If the object store has a key path it is said to use in-line keys. Otherwise it is said to use out-of-line keys. + Optional m_key_path; + + // An object store optionally has a key generator. + Optional m_key_generator; +}; + +}