/* * Copyright (c) 2024-2025, stelar7 * * SPDX-License-Identifier: BSD-2-Clause */ #pragma once #include #include #include #include #include #include #include #include #include namespace Web::IndexedDB { using CursorSourceHandle = Variant, GC::Ref>; using CursorSource = Variant, GC::Ref>; // https://w3c.github.io/IndexedDB/#cursor-interface class IDBCursor : public Bindings::PlatformObject { WEB_PLATFORM_OBJECT(IDBCursor, Bindings::PlatformObject); GC_DECLARE_ALLOCATOR(IDBCursor); enum class GotValue { No, Yes, }; enum class KeyOnly { No, Yes, }; public: virtual ~IDBCursor() override; [[nodiscard]] static GC::Ref create(JS::Realm&, CursorSourceHandle, GC::Ptr, Bindings::IDBCursorDirection, GotValue, GC::Ptr, JS::Value, GC::Ref, KeyOnly); [[nodiscard]] CursorSourceHandle source_handle() { return m_source_handle; } [[nodiscard]] Bindings::IDBCursorDirection direction() { return m_direction; } [[nodiscard]] JS::Value key(); [[nodiscard]] JS::Value primary_key() const; [[nodiscard]] GC::Ptr request() { return m_request; } WebIDL::ExceptionOr advance(WebIDL::UnsignedLong); WebIDL::ExceptionOr continue_(JS::Value); WebIDL::ExceptionOr continue_primary_key(JS::Value, JS::Value); WebIDL::ExceptionOr> update(JS::Value); WebIDL::ExceptionOr> delete_(); [[nodiscard]] GC::Ref range() { return m_range; } [[nodiscard]] GC::Ptr position() { return m_position; } [[nodiscard]] GC::Ptr object_store_position() { return m_object_store_position; } [[nodiscard]] bool key_only() const { return m_key_only; } [[nodiscard]] bool got_value() const { return m_got_value; } [[nodiscard]] GC::Ref transaction(); [[nodiscard]] CursorSource internal_source(); [[nodiscard]] GC::Ref effective_key() const; [[nodiscard]] GC::Ref effective_object_store() const; void set_request(GC::Ptr request) { m_request = request; } void set_position(GC::Ptr position) { m_position = position; } void set_got_value(bool got_value) { m_got_value = got_value; } void set_key(GC::Ptr key) { m_key = key; } void set_value(JS::Value value) { m_value = value; } void set_object_store_position(GC::Ptr object_store_position) { m_object_store_position = object_store_position; } protected: explicit IDBCursor(JS::Realm&, CursorSourceHandle, GC::Ptr, Bindings::IDBCursorDirection, GotValue, GC::Ptr, JS::Value, GC::Ref, KeyOnly); virtual void initialize(JS::Realm&) override; virtual void visit_edges(Visitor& visitor) override; // A cursor has a value which represent the value of the last iterated record. Optional m_value; private: // A cursor has a position within its range. GC::Ptr m_position; // When iterating indexes the cursor also has an object store position GC::Ptr m_object_store_position; // A cursor has a direction that determines whether it moves in monotonically increasing or decreasing order of the record keys when iterated, and if it skips duplicated values when iterating indexes. Bindings::IDBCursorDirection m_direction; // A cursor has a got value flag. bool m_got_value { false }; // A cursor has a key which represent the key the last iterated record. GC::Ptr m_key; // A cursor has a source handle, which is the index handle or the object store handle that opened the cursor. CursorSourceHandle m_source_handle; // A cursor has a range of records in either an index or an object store. GC::Ref m_range; // A cursor has a request, which is the request used to open the cursor. GC::Ptr m_request; // A cursor also has a key only flag, that indicates whether the cursor’s value is exposed via the API. bool m_key_only { false }; }; }