Database.h 3.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. /*
  2. * Copyright (c) 2022-2024, Tim Flynn <trflynn89@serenityos.org>
  3. * Copyright (c) 2023, Jelle Raaijmakers <jelle@gmta.nl>
  4. *
  5. * SPDX-License-Identifier: BSD-2-Clause
  6. */
  7. #pragma once
  8. #include <AK/Error.h>
  9. #include <AK/Function.h>
  10. #include <AK/HashMap.h>
  11. #include <AK/NonnullRefPtr.h>
  12. #include <AK/Optional.h>
  13. #include <AK/RefCounted.h>
  14. #include <AK/StringView.h>
  15. #include <AK/Vector.h>
  16. #include <LibCore/Promise.h>
  17. #include <LibSQL/SQLClient.h>
  18. #include <LibSQL/Type.h>
  19. #include <LibSQL/Value.h>
  20. namespace WebView {
  21. class Database : public RefCounted<Database> {
  22. using OnResult = Function<void(ReadonlySpan<SQL::Value>)>;
  23. using OnComplete = Function<void()>;
  24. using OnError = Function<void(StringView)>;
  25. public:
  26. static ErrorOr<NonnullRefPtr<Database>> create();
  27. static ErrorOr<NonnullRefPtr<Database>> create(NonnullRefPtr<SQL::SQLClient>);
  28. ErrorOr<SQL::StatementID> prepare_statement(StringView statement);
  29. template<typename... PlaceholderValues>
  30. void execute_statement(SQL::StatementID statement_id, OnResult on_result, OnComplete on_complete, OnError on_error, PlaceholderValues&&... placeholder_values)
  31. {
  32. auto sync_promise = Core::Promise<Empty>::construct();
  33. PendingExecution pending_execution {
  34. .on_result = move(on_result),
  35. .on_complete = [sync_promise, on_complete = move(on_complete)] {
  36. if (on_complete)
  37. on_complete();
  38. sync_promise->resolve({}); },
  39. .on_error = [sync_promise, on_error = move(on_error)](auto message) {
  40. if (on_error)
  41. on_error(message);
  42. sync_promise->resolve({}); },
  43. };
  44. Vector<SQL::Value> values { SQL::Value(forward<PlaceholderValues>(placeholder_values))... };
  45. execute_statement(statement_id, move(values), move(pending_execution));
  46. MUST(sync_promise->await());
  47. }
  48. private:
  49. struct ExecutionKey {
  50. constexpr bool operator==(ExecutionKey const&) const = default;
  51. SQL::StatementID statement_id { 0 };
  52. SQL::ExecutionID execution_id { 0 };
  53. };
  54. struct PendingExecution {
  55. OnResult on_result { nullptr };
  56. OnComplete on_complete { nullptr };
  57. OnError on_error { nullptr };
  58. };
  59. struct ExecutionKeyTraits : public Traits<ExecutionKey> {
  60. static constexpr unsigned hash(ExecutionKey const& key)
  61. {
  62. return pair_int_hash(u64_hash(key.statement_id), u64_hash(key.execution_id));
  63. }
  64. };
  65. Database(NonnullRefPtr<SQL::SQLClient> sql_client, SQL::ConnectionID connection_id);
  66. void execute_statement(SQL::StatementID statement_id, Vector<SQL::Value> placeholder_values, PendingExecution pending_execution);
  67. template<typename ResultData>
  68. auto take_pending_execution(ResultData const& result_data)
  69. {
  70. return m_pending_executions.take({ result_data.statement_id, result_data.execution_id });
  71. }
  72. NonnullRefPtr<SQL::SQLClient> m_sql_client;
  73. SQL::ConnectionID m_connection_id { 0 };
  74. HashMap<ExecutionKey, PendingExecution, ExecutionKeyTraits> m_pending_executions;
  75. };
  76. }