From 187d02c45dd81cecab60936ab585647a8ceb9301 Mon Sep 17 00:00:00 2001 From: Timothy Flynn Date: Tue, 7 Oct 2025 14:35:22 -0400 Subject: [PATCH] LibDatabase+LibWebView: Extract our SQLite wrapper to its own library It currently lives in LibWebView as it was only used for cookies and local storage, both of which are managed in the UI process. Let's move it to its own library now to allow other processes to use it, without having to depend on LibWebView (and therefore LibWeb). --- Libraries/CMakeLists.txt | 1 + Libraries/LibDatabase/CMakeLists.txt | 8 +++++ .../{LibWebView => LibDatabase}/Database.cpp | 34 ++++++++----------- .../{LibWebView => LibDatabase}/Database.h | 11 +++--- Libraries/LibDatabase/Forward.h | 18 ++++++++++ Libraries/LibWebView/Application.cpp | 11 +++--- Libraries/LibWebView/Application.h | 3 +- Libraries/LibWebView/CMakeLists.txt | 6 +--- Libraries/LibWebView/CookieJar.cpp | 5 +-- Libraries/LibWebView/CookieJar.h | 6 ++-- Libraries/LibWebView/Forward.h | 1 - Libraries/LibWebView/StorageJar.cpp | 3 +- Libraries/LibWebView/StorageJar.h | 6 ++-- 13 files changed, 68 insertions(+), 45 deletions(-) create mode 100644 Libraries/LibDatabase/CMakeLists.txt rename Libraries/{LibWebView => LibDatabase}/Database.cpp (80%) rename Libraries/{LibWebView => LibDatabase}/Database.h (83%) create mode 100644 Libraries/LibDatabase/Forward.h diff --git a/Libraries/CMakeLists.txt b/Libraries/CMakeLists.txt index f823ce6912..76ce2735c2 100644 --- a/Libraries/CMakeLists.txt +++ b/Libraries/CMakeLists.txt @@ -1,5 +1,6 @@ add_subdirectory(LibCompress) add_subdirectory(LibCrypto) +add_subdirectory(LibDatabase) add_subdirectory(LibDiff) add_subdirectory(LibDNS) add_subdirectory(LibGC) diff --git a/Libraries/LibDatabase/CMakeLists.txt b/Libraries/LibDatabase/CMakeLists.txt new file mode 100644 index 0000000000..d30f6cec0b --- /dev/null +++ b/Libraries/LibDatabase/CMakeLists.txt @@ -0,0 +1,8 @@ +set(SOURCES + Database.cpp +) + +find_package(SQLite3 REQUIRED) + +ladybird_lib(LibDatabase database EXPLICIT_SYMBOL_EXPORT) +target_link_libraries(LibDatabase PRIVATE LibCore SQLite::SQLite3) diff --git a/Libraries/LibWebView/Database.cpp b/Libraries/LibDatabase/Database.cpp similarity index 80% rename from Libraries/LibWebView/Database.cpp rename to Libraries/LibDatabase/Database.cpp index e78174a38b..de70443ac0 100644 --- a/Libraries/LibWebView/Database.cpp +++ b/Libraries/LibDatabase/Database.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022-2024, Tim Flynn + * Copyright (c) 2022-2025, Tim Flynn * * SPDX-License-Identifier: BSD-2-Clause */ @@ -8,12 +8,11 @@ #include #include #include -#include -#include +#include #include -namespace WebView { +namespace Database { static constexpr StringView sql_error(int error_code) { @@ -39,13 +38,10 @@ static constexpr StringView sql_error(int error_code) } \ }) -ErrorOr> Database::create() +ErrorOr> Database::create(ByteString const& directory, StringView name) { - // FIXME: Move this to a generic "Ladybird data directory" helper. - auto database_path = ByteString::formatted("{}/Ladybird", Core::StandardPaths::user_data_directory()); - TRY(Core::Directory::create(database_path, Core::Directory::CreateDirectories::Yes)); - - auto database_file = ByteString::formatted("{}/Ladybird.db", database_path); + TRY(Core::Directory::create(directory, Core::Directory::CreateDirectories::Yes)); + auto database_file = ByteString::formatted("{}/{}.db", directory, name); sqlite3* m_database { nullptr }; SQL_TRY(sqlite3_open(database_file.characters(), &m_database)); @@ -67,7 +63,7 @@ Database::~Database() sqlite3_close(m_database); } -ErrorOr Database::prepare_statement(StringView statement) +ErrorOr Database::prepare_statement(StringView statement) { sqlite3_stmt* prepared_statement { nullptr }; SQL_TRY(sqlite3_prepare_v2(m_database, statement.characters_without_null_termination(), static_cast(statement.length()), &prepared_statement, nullptr)); @@ -119,10 +115,10 @@ void Database::apply_placeholder(StatementID statement_id, int index, ValueType } } -template void Database::apply_placeholder(StatementID, int, String const&); -template void Database::apply_placeholder(StatementID, int, UnixDateTime const&); -template void Database::apply_placeholder(StatementID, int, int const&); -template void Database::apply_placeholder(StatementID, int, bool const&); +template DATABASE_API void Database::apply_placeholder(StatementID, int, String const&); +template DATABASE_API void Database::apply_placeholder(StatementID, int, UnixDateTime const&); +template DATABASE_API void Database::apply_placeholder(StatementID, int, int const&); +template DATABASE_API void Database::apply_placeholder(StatementID, int, bool const&); template ValueType Database::result_column(StatementID statement_id, int column) @@ -144,9 +140,9 @@ ValueType Database::result_column(StatementID statement_id, int column) VERIFY_NOT_REACHED(); } -template String Database::result_column(StatementID, int); -template UnixDateTime Database::result_column(StatementID, int); -template int Database::result_column(StatementID, int); -template bool Database::result_column(StatementID, int); +template DATABASE_API String Database::result_column(StatementID, int); +template DATABASE_API UnixDateTime Database::result_column(StatementID, int); +template DATABASE_API int Database::result_column(StatementID, int); +template DATABASE_API bool Database::result_column(StatementID, int); } diff --git a/Libraries/LibWebView/Database.h b/Libraries/LibDatabase/Database.h similarity index 83% rename from Libraries/LibWebView/Database.h rename to Libraries/LibDatabase/Database.h index 044211a5b4..0c105e6628 100644 --- a/Libraries/LibWebView/Database.h +++ b/Libraries/LibDatabase/Database.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022-2024, Tim Flynn + * Copyright (c) 2022-2025, Tim Flynn * Copyright (c) 2023, Jelle Raaijmakers * * SPDX-License-Identifier: BSD-2-Clause @@ -13,19 +13,18 @@ #include #include #include -#include +#include struct sqlite3; struct sqlite3_stmt; -namespace WebView { +namespace Database { -class WEBVIEW_API Database : public RefCounted { +class DATABASE_API Database : public RefCounted { public: - static ErrorOr> create(); + static ErrorOr> create(ByteString const& directory, StringView name); ~Database(); - using StatementID = size_t; using OnResult = Function; ErrorOr prepare_statement(StringView statement); diff --git a/Libraries/LibDatabase/Forward.h b/Libraries/LibDatabase/Forward.h new file mode 100644 index 0000000000..a5afc01bd8 --- /dev/null +++ b/Libraries/LibDatabase/Forward.h @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2025, Tim Flynn + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include +#include + +namespace Database { + +class Database; + +using StatementID = size_t; + +} diff --git a/Libraries/LibWebView/Application.cpp b/Libraries/LibWebView/Application.cpp index da005ddbb8..6248832e51 100644 --- a/Libraries/LibWebView/Application.cpp +++ b/Libraries/LibWebView/Application.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -17,7 +18,6 @@ #include #include #include -#include #include #include #include @@ -347,9 +347,12 @@ ErrorOr Application::launch_services() }; if (m_browser_options.disable_sql_database == DisableSQLDatabase::No) { - m_database = Database::create().release_value_but_fixme_should_propagate_errors(); - m_cookie_jar = CookieJar::create(*m_database).release_value_but_fixme_should_propagate_errors(); - m_storage_jar = StorageJar::create(*m_database).release_value_but_fixme_should_propagate_errors(); + // FIXME: Move this to a generic "Ladybird data directory" helper. + auto database_path = ByteString::formatted("{}/Ladybird", Core::StandardPaths::user_data_directory()); + + m_database = TRY(Database::Database::create(database_path, "Ladybird"sv)); + m_cookie_jar = TRY(CookieJar::create(*m_database)); + m_storage_jar = TRY(StorageJar::create(*m_database)); } else { m_cookie_jar = CookieJar::create(); m_storage_jar = StorageJar::create(); diff --git a/Libraries/LibWebView/Application.h b/Libraries/LibWebView/Application.h index d0a13269df..75c53c9fae 100644 --- a/Libraries/LibWebView/Application.h +++ b/Libraries/LibWebView/Application.h @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -181,7 +182,7 @@ private: RefPtr m_spare_web_content_process; bool m_has_queued_task_to_launch_spare_web_content_process { false }; - RefPtr m_database; + RefPtr m_database; OwnPtr m_cookie_jar; OwnPtr m_storage_jar; diff --git a/Libraries/LibWebView/CMakeLists.txt b/Libraries/LibWebView/CMakeLists.txt index 532347e2f4..9503d8f6cd 100644 --- a/Libraries/LibWebView/CMakeLists.txt +++ b/Libraries/LibWebView/CMakeLists.txt @@ -7,7 +7,6 @@ set(SOURCES BrowserProcess.cpp ConsoleOutput.cpp CookieJar.cpp - Database.cpp DOMNodeProperties.cpp HeadlessWebView.cpp HelperProcess.cpp @@ -70,16 +69,13 @@ set(GENERATED_SOURCES ) ladybird_lib(LibWebView webview EXPLICIT_SYMBOL_EXPORT) -target_link_libraries(LibWebView PRIVATE LibCore LibDevTools LibFileSystem LibGfx LibImageDecoderClient LibIPC LibRequests LibJS LibWeb LibUnicode LibURL LibSyntax LibTextCodec) +target_link_libraries(LibWebView PRIVATE LibCore LibDatabase LibDevTools LibFileSystem LibGfx LibImageDecoderClient LibIPC LibRequests LibJS LibWeb LibUnicode LibURL LibSyntax LibTextCodec) if (APPLE) target_link_libraries(LibWebView PRIVATE LibThreading) endif() # Third-party -find_package(SQLite3 REQUIRED) -target_link_libraries(LibWebView PRIVATE SQLite::SQLite3) - if (HAS_FONTCONFIG) target_link_libraries(LibWebView PRIVATE Fontconfig::Fontconfig) endif() diff --git a/Libraries/LibWebView/CookieJar.cpp b/Libraries/LibWebView/CookieJar.cpp index 7b7e4bebc0..3972273586 100644 --- a/Libraries/LibWebView/CookieJar.cpp +++ b/Libraries/LibWebView/CookieJar.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -20,7 +21,7 @@ namespace WebView { static constexpr auto DATABASE_SYNCHRONIZATION_TIMER = AK::Duration::from_seconds(30); -ErrorOr> CookieJar::create(Database& database) +ErrorOr> CookieJar::create(Database::Database& database) { Statements statements {}; @@ -665,7 +666,7 @@ void CookieJar::PersistedStorage::insert_cookie(Web::Cookie::Cookie const& cooki cookie.persistent); } -static Web::Cookie::Cookie parse_cookie(Database& database, Database::StatementID statement_id) +static Web::Cookie::Cookie parse_cookie(Database::Database& database, Database::StatementID statement_id) { int column = 0; auto convert_text = [&](auto& field) { field = database.result_column(statement_id, column++); }; diff --git a/Libraries/LibWebView/CookieJar.h b/Libraries/LibWebView/CookieJar.h index 6745b132b5..2aa79c3c34 100644 --- a/Libraries/LibWebView/CookieJar.h +++ b/Libraries/LibWebView/CookieJar.h @@ -13,10 +13,10 @@ #include #include #include +#include #include #include #include -#include #include namespace WebView { @@ -76,13 +76,13 @@ class WEBVIEW_API CookieJar { void insert_cookie(Web::Cookie::Cookie const& cookie); TransientStorage::Cookies select_all_cookies(); - Database& database; + Database::Database& database; Statements statements; RefPtr synchronization_timer {}; }; public: - static ErrorOr> create(Database&); + static ErrorOr> create(Database::Database&); static NonnullOwnPtr create(); ~CookieJar(); diff --git a/Libraries/LibWebView/Forward.h b/Libraries/LibWebView/Forward.h index 1e5f7bad58..4507d42117 100644 --- a/Libraries/LibWebView/Forward.h +++ b/Libraries/LibWebView/Forward.h @@ -16,7 +16,6 @@ class Action; class Application; class Autocomplete; class CookieJar; -class Database; class Menu; class OutOfProcessWebView; class ProcessManager; diff --git a/Libraries/LibWebView/StorageJar.cpp b/Libraries/LibWebView/StorageJar.cpp index c11194b088..e0b22e0672 100644 --- a/Libraries/LibWebView/StorageJar.cpp +++ b/Libraries/LibWebView/StorageJar.cpp @@ -6,6 +6,7 @@ #include #include +#include #include namespace WebView { @@ -13,7 +14,7 @@ namespace WebView { // Quota size is specified in https://storage.spec.whatwg.org/#registered-storage-endpoints static constexpr size_t LOCAL_STORAGE_QUOTA = 5 * MiB; -ErrorOr> StorageJar::create(Database& database) +ErrorOr> StorageJar::create(Database::Database& database) { Statements statements {}; diff --git a/Libraries/LibWebView/StorageJar.h b/Libraries/LibWebView/StorageJar.h index 39b835ecd5..0baae08f77 100644 --- a/Libraries/LibWebView/StorageJar.h +++ b/Libraries/LibWebView/StorageJar.h @@ -9,8 +9,8 @@ #include #include #include +#include #include -#include #include #include @@ -31,7 +31,7 @@ class WEBVIEW_API StorageJar { AK_MAKE_NONMOVABLE(StorageJar); public: - static ErrorOr> create(Database&); + static ErrorOr> create(Database::Database&); static NonnullOwnPtr create(); ~StorageJar(); @@ -71,7 +71,7 @@ private: void clear(StorageEndpointType storage_endpoint, String const& storage_key); Vector get_keys(StorageEndpointType storage_endpoint, String const& storage_key); - Database& database; + Database::Database& database; Statements statements; };