LibWeb/IDB: Add internal Index object

This commit is contained in:
stelar7 2025-04-01 18:26:13 +02:00 committed by Andrew Kaster
parent 8beade51e0
commit 9321ad04c0
Notes: github-actions[bot] 2025-04-09 17:50:57 +00:00
6 changed files with 119 additions and 0 deletions

View file

@ -567,6 +567,7 @@ set(SOURCES
IndexedDB/IDBVersionChangeEvent.cpp
IndexedDB/Internal/Algorithms.cpp
IndexedDB/Internal/Database.cpp
IndexedDB/Internal/Index.cpp
IndexedDB/Internal/Key.cpp
IndexedDB/Internal/ObjectStore.cpp
IndexedDB/Internal/RequestList.cpp

View file

@ -625,6 +625,7 @@ class IDBOpenDBRequest;
class IDBRequest;
class IDBTransaction;
class IDBVersionChangeEvent;
class Index;
class ObjectStore;
class RequestList;
}

View file

@ -0,0 +1,42 @@
/*
* Copyright (c) 2025, stelar7 <dudedbz@gmail.com>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <LibWeb/IndexedDB/Internal/Index.h>
#include <LibWeb/IndexedDB/Internal/ObjectStore.h>
namespace Web::IndexedDB {
GC_DEFINE_ALLOCATOR(Index);
Index::~Index() = default;
GC::Ref<Index> Index::create(JS::Realm& realm, GC::Ref<ObjectStore> store, String name, KeyPath const& key_path, bool unique, bool multi_entry)
{
return realm.create<Index>(store, name, key_path, unique, multi_entry);
}
Index::Index(GC::Ref<ObjectStore> store, String name, KeyPath const& key_path, bool unique, bool multi_entry)
: m_object_store(store)
, m_name(move(name))
, m_unique(unique)
, m_multi_entry(multi_entry)
, m_key_path(key_path)
{
store->add_index(*this);
}
void Index::visit_edges(Visitor& visitor)
{
Base::visit_edges(visitor);
visitor.visit(m_object_store);
for (auto& record : m_records) {
visitor.visit(record.key);
visitor.visit(record.value);
}
}
}

View file

@ -0,0 +1,67 @@
/*
* Copyright (c) 2025, stelar7 <dudedbz@gmail.com>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <AK/Vector.h>
#include <LibGC/Ptr.h>
#include <LibJS/Heap/Cell.h>
#include <LibJS/Runtime/Realm.h>
#include <LibWeb/IndexedDB/Internal/ObjectStore.h>
namespace Web::IndexedDB {
using KeyPath = Variant<String, Vector<String>>;
// https://w3c.github.io/IndexedDB/#index-list-of-records
struct IndexRecord {
GC::Ref<Key> key;
GC::Ref<Key> value;
};
// https://w3c.github.io/IndexedDB/#index-construct
class Index : public JS::Cell {
GC_CELL(Index, JS::Cell);
GC_DECLARE_ALLOCATOR(Index);
public:
[[nodiscard]] static GC::Ref<Index> create(JS::Realm&, GC::Ref<ObjectStore>, String, KeyPath const&, bool, bool);
virtual ~Index();
void set_name(String name) { m_name = move(name); }
[[nodiscard]] String name() const { return m_name; }
[[nodiscard]] bool unique() const { return m_unique; }
[[nodiscard]] bool multi_entry() const { return m_multi_entry; }
[[nodiscard]] GC::Ref<ObjectStore> object_store() const { return m_object_store; }
[[nodiscard]] AK::ReadonlySpan<IndexRecord> records() const { return m_records; }
[[nodiscard]] KeyPath const& key_path() const { return m_key_path; }
protected:
virtual void visit_edges(Visitor&) override;
private:
Index(GC::Ref<ObjectStore>, String, KeyPath const&, bool, bool);
// An index [...] has a referenced object store.
GC::Ref<ObjectStore> m_object_store;
// The index has a list of records which hold the data stored in the index.
Vector<IndexRecord> m_records;
// An index has a name, which is a name. At any one time, the name is unique within indexs referenced object store.
String m_name;
// An index has a unique flag. When true, the index enforces that no two records in the index has the same key.
bool m_unique { false };
// An index has a multiEntry flag. This flag affects how the index behaves when the result of evaluating the indexs key path yields an array key.
bool m_multi_entry { false };
// The keys are derived from the referenced object stores values using a key path.
KeyPath m_key_path;
};
}

View file

@ -32,6 +32,7 @@ void ObjectStore::visit_edges(Visitor& visitor)
{
Base::visit_edges(visitor);
visitor.visit(m_database);
visitor.visit(m_indexes);
}
}

View file

@ -15,6 +15,7 @@
#include <LibJS/Runtime/Realm.h>
#include <LibWeb/IndexedDB/Internal/Algorithms.h>
#include <LibWeb/IndexedDB/Internal/Database.h>
#include <LibWeb/IndexedDB/Internal/Index.h>
#include <LibWeb/IndexedDB/Internal/KeyGenerator.h>
namespace Web::IndexedDB {
@ -39,6 +40,9 @@ public:
GC::Ref<Database> database() const { return m_database; }
void add_index(GC::Ref<Index> index) { m_indexes.append(index); }
ReadonlySpan<GC::Ref<Index>> index_set() const { return m_indexes; }
protected:
virtual void visit_edges(Visitor&) override;
@ -48,6 +52,9 @@ private:
// AD-HOC: An ObjectStore needs to know what Database it belongs to...
GC::Ref<Database> m_database;
// AD-HOC: An Index has referenced ObjectStores, we also need the reverse mapping
Vector<GC::Ref<Index>> m_indexes;
// 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;