mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-08-11 02:29:21 +00:00
LibWeb/IDB: Add internal Index object
This commit is contained in:
parent
8beade51e0
commit
9321ad04c0
Notes:
github-actions[bot]
2025-04-09 17:50:57 +00:00
Author: https://github.com/stelar7
Commit: 9321ad04c0
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/4178
Reviewed-by: https://github.com/ADKaster ✅
Reviewed-by: https://github.com/AtkinsSJ
6 changed files with 119 additions and 0 deletions
|
@ -567,6 +567,7 @@ set(SOURCES
|
||||||
IndexedDB/IDBVersionChangeEvent.cpp
|
IndexedDB/IDBVersionChangeEvent.cpp
|
||||||
IndexedDB/Internal/Algorithms.cpp
|
IndexedDB/Internal/Algorithms.cpp
|
||||||
IndexedDB/Internal/Database.cpp
|
IndexedDB/Internal/Database.cpp
|
||||||
|
IndexedDB/Internal/Index.cpp
|
||||||
IndexedDB/Internal/Key.cpp
|
IndexedDB/Internal/Key.cpp
|
||||||
IndexedDB/Internal/ObjectStore.cpp
|
IndexedDB/Internal/ObjectStore.cpp
|
||||||
IndexedDB/Internal/RequestList.cpp
|
IndexedDB/Internal/RequestList.cpp
|
||||||
|
|
|
@ -625,6 +625,7 @@ class IDBOpenDBRequest;
|
||||||
class IDBRequest;
|
class IDBRequest;
|
||||||
class IDBTransaction;
|
class IDBTransaction;
|
||||||
class IDBVersionChangeEvent;
|
class IDBVersionChangeEvent;
|
||||||
|
class Index;
|
||||||
class ObjectStore;
|
class ObjectStore;
|
||||||
class RequestList;
|
class RequestList;
|
||||||
}
|
}
|
||||||
|
|
42
Libraries/LibWeb/IndexedDB/Internal/Index.cpp
Normal file
42
Libraries/LibWeb/IndexedDB/Internal/Index.cpp
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
67
Libraries/LibWeb/IndexedDB/Internal/Index.h
Normal file
67
Libraries/LibWeb/IndexedDB/Internal/Index.h
Normal 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 index’s 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 index’s key path yields an array key.
|
||||||
|
bool m_multi_entry { false };
|
||||||
|
|
||||||
|
// The keys are derived from the referenced object store’s values using a key path.
|
||||||
|
KeyPath m_key_path;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
|
@ -32,6 +32,7 @@ void ObjectStore::visit_edges(Visitor& visitor)
|
||||||
{
|
{
|
||||||
Base::visit_edges(visitor);
|
Base::visit_edges(visitor);
|
||||||
visitor.visit(m_database);
|
visitor.visit(m_database);
|
||||||
|
visitor.visit(m_indexes);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
#include <LibJS/Runtime/Realm.h>
|
#include <LibJS/Runtime/Realm.h>
|
||||||
#include <LibWeb/IndexedDB/Internal/Algorithms.h>
|
#include <LibWeb/IndexedDB/Internal/Algorithms.h>
|
||||||
#include <LibWeb/IndexedDB/Internal/Database.h>
|
#include <LibWeb/IndexedDB/Internal/Database.h>
|
||||||
|
#include <LibWeb/IndexedDB/Internal/Index.h>
|
||||||
#include <LibWeb/IndexedDB/Internal/KeyGenerator.h>
|
#include <LibWeb/IndexedDB/Internal/KeyGenerator.h>
|
||||||
|
|
||||||
namespace Web::IndexedDB {
|
namespace Web::IndexedDB {
|
||||||
|
@ -39,6 +40,9 @@ public:
|
||||||
|
|
||||||
GC::Ref<Database> database() const { return m_database; }
|
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:
|
protected:
|
||||||
virtual void visit_edges(Visitor&) override;
|
virtual void visit_edges(Visitor&) override;
|
||||||
|
|
||||||
|
@ -48,6 +52,9 @@ private:
|
||||||
// AD-HOC: An ObjectStore needs to know what Database it belongs to...
|
// AD-HOC: An ObjectStore needs to know what Database it belongs to...
|
||||||
GC::Ref<Database> m_database;
|
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.
|
// 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;
|
String m_name;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue