ladybird/Libraries/LibWeb/IndexedDB/Internal/ObjectStore.cpp

87 lines
2.3 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* Copyright (c) 2025, stelar7 <dudedbz@gmail.com>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <AK/QuickSort.h>
#include <LibWeb/IndexedDB/IDBKeyRange.h>
#include <LibWeb/IndexedDB/Internal/ObjectStore.h>
namespace Web::IndexedDB {
GC_DEFINE_ALLOCATOR(ObjectStore);
ObjectStore::~ObjectStore() = default;
GC::Ref<ObjectStore> ObjectStore::create(JS::Realm& realm, GC::Ref<Database> database, String name, bool auto_increment, Optional<KeyPath> const& key_path)
{
return realm.create<ObjectStore>(database, name, auto_increment, key_path);
}
ObjectStore::ObjectStore(GC::Ref<Database> database, String name, bool auto_increment, Optional<KeyPath> const& key_path)
: m_database(database)
, m_name(move(name))
, m_key_path(key_path)
{
database->add_object_store(*this);
if (auto_increment)
m_key_generator = KeyGenerator {};
}
void ObjectStore::visit_edges(Visitor& visitor)
{
Base::visit_edges(visitor);
visitor.visit(m_database);
visitor.visit(m_indexes);
for (auto& record : m_records) {
visitor.visit(record.key);
}
}
void ObjectStore::remove_records_in_range(GC::Ref<IDBKeyRange> range)
{
m_records.remove_all_matching([&](auto const& record) {
return range->is_in_range(record.key);
});
}
bool ObjectStore::has_record_with_key(GC::Ref<Key> key)
{
auto index = m_records.find_if([&key](auto const& record) {
return Key::equals(key, record.key);
});
return index != m_records.end();
}
void ObjectStore::store_a_record(Record const& record)
{
m_records.append(record);
// NOTE: The record is stored in the object stores list of records such that the list is sorted according to the key of the records in ascending order.
AK::quick_sort(m_records, [](auto const& a, auto const& b) {
return Key::compare_two_keys(a.key, b.key) < 0;
});
}
u64 ObjectStore::count_records_in_range(GC::Ref<IDBKeyRange> range)
{
u64 count = 0;
for (auto const& record : m_records) {
if (range->is_in_range(record.key))
++count;
}
return count;
}
Optional<Record&> ObjectStore::first_in_range(GC::Ref<IDBKeyRange> range)
{
return m_records.first_matching([&](auto const& record) {
return range->is_in_range(record.key);
});
}
}