/* * Copyright (c) 2022-2024, Tim Flynn * Copyright (c) 2023, Jelle Raaijmakers * * SPDX-License-Identifier: BSD-2-Clause */ #pragma once #include #include #include #include #include #include #include #include #include #include #include #include namespace WebView { class Database : public RefCounted { using OnResult = Function)>; using OnComplete = Function; using OnError = Function; public: static ErrorOr> create(); static ErrorOr> create(NonnullRefPtr); ErrorOr prepare_statement(StringView statement); template void execute_statement(SQL::StatementID statement_id, OnResult on_result, OnComplete on_complete, OnError on_error, PlaceholderValues&&... placeholder_values) { auto sync_promise = Core::Promise::construct(); PendingExecution pending_execution { .on_result = move(on_result), .on_complete = [sync_promise, on_complete = move(on_complete)] { if (on_complete) on_complete(); sync_promise->resolve({}); }, .on_error = [sync_promise, on_error = move(on_error)](auto message) { if (on_error) on_error(message); sync_promise->resolve({}); }, }; Vector values { SQL::Value(forward(placeholder_values))... }; execute_statement(statement_id, move(values), move(pending_execution)); MUST(sync_promise->await()); } private: struct ExecutionKey { constexpr bool operator==(ExecutionKey const&) const = default; SQL::StatementID statement_id { 0 }; SQL::ExecutionID execution_id { 0 }; }; struct PendingExecution { OnResult on_result { nullptr }; OnComplete on_complete { nullptr }; OnError on_error { nullptr }; }; struct ExecutionKeyTraits : public Traits { static constexpr unsigned hash(ExecutionKey const& key) { return pair_int_hash(u64_hash(key.statement_id), u64_hash(key.execution_id)); } }; Database(NonnullRefPtr sql_client, SQL::ConnectionID connection_id); void execute_statement(SQL::StatementID statement_id, Vector placeholder_values, PendingExecution pending_execution); template auto take_pending_execution(ResultData const& result_data) { return m_pending_executions.take({ result_data.statement_id, result_data.execution_id }); } NonnullRefPtr m_sql_client; SQL::ConnectionID m_connection_id { 0 }; HashMap m_pending_executions; }; }