mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-07-29 04:09:13 +00:00
LibWeb: Implement most of upgrade_a_database for IndexedDB
This commit is contained in:
parent
ca25f76ccc
commit
1656d8fe07
Notes:
github-actions[bot]
2024-11-26 13:51:49 +00:00
Author: https://github.com/stelar7
Commit: 1656d8fe07
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/2236
Reviewed-by: https://github.com/gmta ✅
7 changed files with 81 additions and 17 deletions
|
@ -32,6 +32,7 @@ void IDBRequest::visit_edges(Visitor& visitor)
|
|||
Base::visit_edges(visitor);
|
||||
visitor.visit(m_error);
|
||||
visitor.visit(m_result);
|
||||
visitor.visit(m_transaction);
|
||||
}
|
||||
|
||||
// https://w3c.github.io/IndexedDB/#dom-idbrequest-onsuccess
|
||||
|
|
|
@ -10,11 +10,13 @@
|
|||
|
||||
#include <LibWeb/Bindings/IDBRequestPrototype.h>
|
||||
#include <LibWeb/DOM/EventTarget.h>
|
||||
#include <LibWeb/IndexedDB/IDBTransaction.h>
|
||||
|
||||
namespace Web::IndexedDB {
|
||||
|
||||
using IDBRequestSource = Variant<Empty, GC::Ref<IDBObjectStore>, GC::Ref<IDBIndex>, GC::Ref<IDBCursor>>;
|
||||
|
||||
// https://w3c.github.io/IndexedDB/#request-api
|
||||
class IDBRequest : public DOM::EventTarget {
|
||||
WEB_PLATFORM_OBJECT(IDBRequest, DOM::EventTarget);
|
||||
GC_DECLARE_ALLOCATOR(IDBRequest);
|
||||
|
@ -25,6 +27,7 @@ public:
|
|||
[[nodiscard]] bool done() const { return m_done; }
|
||||
[[nodiscard]] bool processed() const { return m_processed; }
|
||||
[[nodiscard]] IDBRequestSource source() const { return m_source; }
|
||||
[[nodiscard]] GC::Ptr<IDBTransaction> transaction() const { return m_transaction; }
|
||||
|
||||
[[nodiscard]] Bindings::IDBRequestReadyState ready_state() const;
|
||||
[[nodiscard]] WebIDL::ExceptionOr<GC::Ptr<WebIDL::DOMException>> error() const;
|
||||
|
@ -35,6 +38,7 @@ public:
|
|||
void set_error(GC::Ptr<WebIDL::DOMException> error) { m_error = error; }
|
||||
void set_processed(bool processed) { m_processed = processed; }
|
||||
void set_source(IDBRequestSource source) { m_source = source; }
|
||||
void set_transaction(GC::Ref<IDBTransaction> transaction) { m_transaction = transaction; }
|
||||
|
||||
void set_onsuccess(WebIDL::CallbackType*);
|
||||
WebIDL::CallbackType* onsuccess();
|
||||
|
@ -57,7 +61,8 @@ private:
|
|||
GC::Ptr<WebIDL::DOMException> m_error;
|
||||
// A request has a source object.
|
||||
IDBRequestSource m_source;
|
||||
// FIXME: A request has a transaction which is initially null.
|
||||
// A request has a transaction which is initially null.
|
||||
GC::Ptr<IDBTransaction> m_transaction;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include <LibWeb/HTML/EventNames.h>
|
||||
#include <LibWeb/IndexedDB/IDBDatabase.h>
|
||||
#include <LibWeb/IndexedDB/IDBRequest.h>
|
||||
#include <LibWeb/IndexedDB/IDBTransaction.h>
|
||||
#include <LibWeb/IndexedDB/IDBVersionChangeEvent.h>
|
||||
#include <LibWeb/IndexedDB/Internal/Algorithms.h>
|
||||
#include <LibWeb/IndexedDB/Internal/ConnectionQueueHandler.h>
|
||||
|
@ -106,9 +107,8 @@ WebIDL::ExceptionOr<GC::Ref<IDBDatabase>> open_a_database_connection(JS::Realm&
|
|||
return true;
|
||||
}));
|
||||
|
||||
// FIXME: 6. Run upgrade a database using connection, version and request.
|
||||
// NOTE: upgrade a database sets this flag, so we set it manually temporarily.
|
||||
request->set_processed(true);
|
||||
// 6. Run upgrade a database using connection, version and request.
|
||||
upgrade_a_database(realm, connection, version, request);
|
||||
|
||||
// 7. If connection was closed, return a newly created "AbortError" DOMException and abort these steps.
|
||||
if (connection->state() == IDBDatabase::ConnectionState::Closed) {
|
||||
|
@ -282,4 +282,57 @@ void close_a_database_connection(IDBDatabase& connection, bool forced)
|
|||
connection.dispatch_event(DOM::Event::create(connection.realm(), HTML::EventNames::close));
|
||||
}
|
||||
|
||||
void upgrade_a_database(JS::Realm& realm, GC::Ref<IDBDatabase> connection, u64 version, GC::Ref<IDBRequest> request)
|
||||
{
|
||||
// 1. Let db be connection’s database.
|
||||
auto db = connection->associated_database();
|
||||
|
||||
// 2. Let transaction be a new upgrade transaction with connection used as connection.
|
||||
auto transaction = IDBTransaction::create(realm, connection);
|
||||
|
||||
// FIXME: 3. Set transaction’s scope to connection’s object store set.
|
||||
|
||||
// 4. Set db’s upgrade transaction to transaction.
|
||||
db->set_upgrade_transaction(transaction);
|
||||
|
||||
// 5. Set transaction’s state to inactive.
|
||||
transaction->set_state(IDBTransaction::TransactionState::Inactive);
|
||||
|
||||
// FIXME: 6. Start transaction.
|
||||
|
||||
// 7. Let old version be db’s version.
|
||||
auto old_version = db->version();
|
||||
|
||||
// 8. Set db’s version to version. This change is considered part of the transaction, and so if the transaction is aborted, this change is reverted.
|
||||
db->set_version(version);
|
||||
|
||||
// 9. Set request’s processed flag to true.
|
||||
request->set_processed(true);
|
||||
|
||||
// 10. Queue a task to run these steps:
|
||||
HTML::queue_a_task(HTML::Task::Source::DatabaseAccess, nullptr, nullptr, GC::create_function(realm.vm().heap(), [&realm, request, connection, transaction, old_version, version]() {
|
||||
// 1. Set request’s result to connection.
|
||||
request->set_result(connection);
|
||||
|
||||
// 2. Set request’s transaction to transaction.
|
||||
request->set_transaction(transaction);
|
||||
|
||||
// 3. Set request’s done flag to true.
|
||||
request->set_done(true);
|
||||
|
||||
// 4. Set transaction’s state to active.
|
||||
transaction->set_state(IDBTransaction::TransactionState::Active);
|
||||
|
||||
// 5. Let didThrow be the result of firing a version change event named upgradeneeded at request with old version and version.
|
||||
[[maybe_unused]] auto did_throw = fire_a_version_change_event(realm, HTML::EventNames::upgradeneeded, request, old_version, version);
|
||||
|
||||
// 6. Set transaction’s state to inactive.
|
||||
transaction->set_state(IDBTransaction::TransactionState::Inactive);
|
||||
|
||||
// FIXME: 7. If didThrow is true, run abort a transaction with transaction and a newly created "AbortError" DOMException.
|
||||
}));
|
||||
|
||||
// FIXME: 11. Wait for transaction to finish.
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -17,5 +17,6 @@ WebIDL::ExceptionOr<GC::Ref<IDBDatabase>> open_a_database_connection(JS::Realm&,
|
|||
bool fire_a_version_change_event(JS::Realm&, FlyString const&, GC::Ref<DOM::EventTarget>, u64, Optional<u64>);
|
||||
ErrorOr<Key> convert_a_value_to_a_key(JS::Realm&, JS::Value, Vector<JS::Value> = {});
|
||||
void close_a_database_connection(IDBDatabase&, bool forced = false);
|
||||
void upgrade_a_database(JS::Realm&, GC::Ref<IDBDatabase>, u64, GC::Ref<IDBRequest>);
|
||||
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@ void Database::visit_edges(Visitor& visitor)
|
|||
{
|
||||
Base::visit_edges(visitor);
|
||||
visitor.visit(m_associated_connections);
|
||||
visitor.visit(m_upgrade_transaction);
|
||||
}
|
||||
|
||||
ConnectionQueue& ConnectionQueueHandler::for_key_and_name(StorageAPI::StorageKey& key, String& name)
|
||||
|
|
|
@ -25,6 +25,8 @@ public:
|
|||
u64 version() const { return m_version; }
|
||||
String name() const { return m_name; }
|
||||
|
||||
void set_upgrade_transaction(GC::Ptr<IDBTransaction> transaction) { m_upgrade_transaction = transaction; }
|
||||
|
||||
void associate(GC::Ref<IDBDatabase> connection) { m_associated_connections.append(connection); }
|
||||
ReadonlySpan<GC::Ref<IDBDatabase>> associated_connections() { return m_associated_connections; }
|
||||
Vector<GC::Root<IDBDatabase>> associated_connections_except(IDBDatabase& connection)
|
||||
|
@ -66,7 +68,8 @@ private:
|
|||
// A database has a version. When a database is first created, its version is 0 (zero).
|
||||
u64 m_version { 0 };
|
||||
|
||||
// FIXME: A database has at most one associated upgrade transaction, which is either null or an upgrade transaction, and is initially null.
|
||||
// A database has at most one associated upgrade transaction, which is either null or an upgrade transaction, and is initially null.
|
||||
GC::Ptr<IDBTransaction> m_upgrade_transaction;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -9,27 +9,27 @@ Found 24 tests
|
|||
12 Pass
|
||||
12 Fail
|
||||
Details
|
||||
Result Test Name MessageFail Database readback sort - String < Array Cannot access property "transaction" on undefined object "db"
|
||||
Result Test Name MessageFail Database readback sort - String < Array undefined is not a function (evaluated from 'db.createObjectStore')
|
||||
Pass IDBKey.cmp sorted - String < Array
|
||||
Fail Database readback sort - float < String Cannot access property "transaction" on undefined object "db"
|
||||
Fail Database readback sort - float < String undefined is not a function (evaluated from 'db.createObjectStore')
|
||||
Pass IDBKey.cmp sorted - float < String
|
||||
Fail Database readback sort - float < Date Cannot access property "transaction" on undefined object "db"
|
||||
Fail Database readback sort - float < Date undefined is not a function (evaluated from 'db.createObjectStore')
|
||||
Pass IDBKey.cmp sorted - float < Date
|
||||
Fail Database readback sort - float < Date < String < Array Cannot access property "transaction" on undefined object "db"
|
||||
Fail Database readback sort - float < Date < String < Array undefined is not a function (evaluated from 'db.createObjectStore')
|
||||
Pass IDBKey.cmp sorted - float < Date < String < Array
|
||||
Fail Database readback sort - Date(1 sec ago) < Date(now) < Date(1 minute in future) Cannot access property "transaction" on undefined object "db"
|
||||
Fail Database readback sort - Date(1 sec ago) < Date(now) < Date(1 minute in future) undefined is not a function (evaluated from 'db.createObjectStore')
|
||||
Pass IDBKey.cmp sorted - Date(1 sec ago) < Date(now) < Date(1 minute in future)
|
||||
Fail Database readback sort - -1.1 < 1 < 1.01337 < 1.013373 < 2 Cannot access property "transaction" on undefined object "db"
|
||||
Fail Database readback sort - -1.1 < 1 < 1.01337 < 1.013373 < 2 undefined is not a function (evaluated from 'db.createObjectStore')
|
||||
Pass IDBKey.cmp sorted - -1.1 < 1 < 1.01337 < 1.013373 < 2
|
||||
Fail Database readback sort - -Infinity < -0.01 < 0 < Infinity Cannot access property "transaction" on undefined object "db"
|
||||
Fail Database readback sort - -Infinity < -0.01 < 0 < Infinity undefined is not a function (evaluated from 'db.createObjectStore')
|
||||
Pass IDBKey.cmp sorted - -Infinity < -0.01 < 0 < Infinity
|
||||
Fail Database readback sort - "" < "a" < "ab" < "b" < "ba" Cannot access property "transaction" on undefined object "db"
|
||||
Fail Database readback sort - "" < "a" < "ab" < "b" < "ba" undefined is not a function (evaluated from 'db.createObjectStore')
|
||||
Pass IDBKey.cmp sorted - "" < "a" < "ab" < "b" < "ba"
|
||||
Fail Database readback sort - Arrays Cannot access property "transaction" on undefined object "db"
|
||||
Fail Database readback sort - Arrays undefined is not a function (evaluated from 'db.createObjectStore')
|
||||
Pass IDBKey.cmp sorted - Arrays
|
||||
Fail Database readback sort - Array.length: 10,000 < Array.length: 10,001 Cannot access property "transaction" on undefined object "db"
|
||||
Fail Database readback sort - Array.length: 10,000 < Array.length: 10,001 undefined is not a function (evaluated from 'db.createObjectStore')
|
||||
Pass IDBKey.cmp sorted - Array.length: 10,000 < Array.length: 10,001
|
||||
Fail Database readback sort - Infinity inside arrays Cannot access property "transaction" on undefined object "db"
|
||||
Fail Database readback sort - Infinity inside arrays undefined is not a function (evaluated from 'db.createObjectStore')
|
||||
Pass IDBKey.cmp sorted - Infinity inside arrays
|
||||
Fail Database readback sort - Test different stuff at once Cannot access property "transaction" on undefined object "db"
|
||||
Fail Database readback sort - Test different stuff at once undefined is not a function (evaluated from 'db.createObjectStore')
|
||||
Pass IDBKey.cmp sorted - Test different stuff at once
|
Loading…
Add table
Add a link
Reference in a new issue