/* * Copyright (c) 2024-2025, stelar7 * * SPDX-License-Identifier: BSD-2-Clause */ #pragma once #include #include #include #include #include #include namespace Web::IndexedDB { // https://www.w3.org/TR/IndexedDB/#database-construct class Database : public Bindings::PlatformObject { WEB_PLATFORM_OBJECT(Database, Bindings::PlatformObject); GC_DECLARE_ALLOCATOR(Database); public: void set_version(u64 version) { m_version = version; } u64 version() const { return m_version; } 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); } Vector> associated_connections(); Vector> associated_connections_except(IDBDatabase& connection); ReadonlySpan> object_stores() { return m_object_stores; } 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 const&, String const&); [[nodiscard]] static ErrorOr> create_for_key_and_name(JS::Realm&, StorageAPI::StorageKey const&, String const&); [[nodiscard]] static ErrorOr delete_for_key_and_name(StorageAPI::StorageKey const&, String const&); static void for_each_database(AK::Function const&)> const& visitor); [[nodiscard]] static GC::Ref create(JS::Realm&, String const&); virtual ~Database(); void wait_for_connections_to_close(ReadonlySpan> connections, GC::Ref> after_all); protected: explicit Database(IDBDatabase& database); explicit Database(JS::Realm& realm, String name) : PlatformObject(realm) , m_name(move(name)) { } virtual void visit_edges(Visitor&) override; private: struct ConnectionCloseState final : public GC::Cell { GC_CELL(ConnectionCloseState, GC::Cell); GC_DECLARE_ALLOCATOR(ConnectionCloseState); virtual void visit_edges(Visitor& visitor) override; void add_connection_to_observe(GC::Ref database); Vector> database_observers; GC::Ptr> after_all; }; Vector> m_associated_connections; Vector> m_pending_connection_close_queue; // A database has a name which identifies it within a specific storage key. String m_name; // A database has a version. When a database is first created, its version is 0 (zero). u64 m_version { 0 }; // 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; }; }