SQLServer: Store LibSQL database files in the standard data directory

This also allows for overriding the path. Ladybird will want to store
the database files in a subdirectory of the standard data directory that
contains the Ladybird application name.

Fixes #16000.
This commit is contained in:
Timothy Flynn 2022-12-05 12:50:45 -05:00 committed by Andreas Kling
parent 49d74ee288
commit b3e287342f
5 changed files with 23 additions and 12 deletions

View file

@ -4,8 +4,8 @@
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <AK/DeprecatedString.h>
#include <AK/Vector.h>
#include <LibCore/StandardPaths.h>
#include <LibSQL/Result.h>
#include <SQLServer/ConnectionFromClient.h>
#include <SQLServer/DatabaseConnection.h>
@ -23,8 +23,14 @@ RefPtr<ConnectionFromClient> ConnectionFromClient::client_connection_for(int cli
return nullptr;
}
void ConnectionFromClient::set_database_path(DeprecatedString database_path)
{
m_database_path = move(database_path);
}
ConnectionFromClient::ConnectionFromClient(NonnullOwnPtr<Core::Stream::LocalSocket> socket, int client_id)
: IPC::ConnectionFromClient<SQLClientEndpoint, SQLServerEndpoint>(*this, move(socket), client_id)
, m_database_path(DeprecatedString::formatted("{}/sql", Core::StandardPaths::data_directory()))
{
s_connections.set(client_id, *this);
}
@ -38,7 +44,7 @@ Messages::SQLServer::ConnectResponse ConnectionFromClient::connect(DeprecatedStr
{
dbgln_if(SQLSERVER_DEBUG, "ConnectionFromClient::connect(database_name: {})", database_name);
if (auto database_connection = DatabaseConnection::create(database_name, client_id()); !database_connection.is_error())
if (auto database_connection = DatabaseConnection::create(m_database_path, database_name, client_id()); !database_connection.is_error())
return { database_connection.value()->connection_id() };
return { {} };
}

View file

@ -6,6 +6,7 @@
#pragma once
#include <AK/DeprecatedString.h>
#include <AK/HashMap.h>
#include <AK/Vector.h>
#include <LibIPC/ConnectionFromClient.h>
@ -25,6 +26,8 @@ public:
static RefPtr<ConnectionFromClient> client_connection_for(int client_id);
void set_database_path(DeprecatedString);
private:
explicit ConnectionFromClient(NonnullOwnPtr<Core::Stream::LocalSocket>, int client_id);
@ -32,6 +35,8 @@ private:
virtual Messages::SQLServer::PrepareStatementResponse prepare_statement(u64, DeprecatedString const&) override;
virtual Messages::SQLServer::ExecuteStatementResponse execute_statement(u64, Vector<SQL::Value> const& placeholder_values) override;
virtual void disconnect(u64) override;
DeprecatedString m_database_path;
};
}

View file

@ -21,12 +21,14 @@ RefPtr<DatabaseConnection> DatabaseConnection::connection_for(u64 connection_id)
return nullptr;
}
ErrorOr<NonnullRefPtr<DatabaseConnection>> DatabaseConnection::create(DeprecatedString database_name, int client_id)
ErrorOr<NonnullRefPtr<DatabaseConnection>> DatabaseConnection::create(StringView database_path, DeprecatedString database_name, int client_id)
{
if (LexicalPath path(database_name); (path.title() != database_name) || (path.dirname() != "."))
return Error::from_string_view("Invalid database name"sv);
auto database = SQL::Database::construct(DeprecatedString::formatted("/home/anon/sql/{}.db", database_name));
auto database_file = DeprecatedString::formatted("{}/{}.db", database_path, database_name);
auto database = SQL::Database::construct(move(database_file));
if (auto result = database->open(); result.is_error()) {
warnln("Could not open database: {}", result.error().error_string());
return Error::from_string_view("Could not open database"sv);

View file

@ -18,7 +18,7 @@ class DatabaseConnection final : public Core::Object {
C_OBJECT_ABSTRACT(DatabaseConnection)
public:
static ErrorOr<NonnullRefPtr<DatabaseConnection>> create(DeprecatedString database_name, int client_id);
static ErrorOr<NonnullRefPtr<DatabaseConnection>> create(StringView database_path, DeprecatedString database_name, int client_id);
~DatabaseConnection() override = default;
static RefPtr<DatabaseConnection> connection_for(u64 connection_id);

View file

@ -4,24 +4,22 @@
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <LibCore/Directory.h>
#include <LibCore/EventLoop.h>
#include <LibCore/StandardPaths.h>
#include <LibCore/System.h>
#include <LibIPC/MultiServer.h>
#include <LibMain/Main.h>
#include <SQLServer/ConnectionFromClient.h>
#include <stdio.h>
#include <sys/stat.h>
ErrorOr<int> serenity_main(Main::Arguments)
{
TRY(Core::System::pledge("stdio accept unix rpath wpath cpath"));
if (mkdir("/home/anon/sql", 0700) < 0 && errno != EEXIST) {
perror("mkdir");
return 1;
}
auto database_path = DeprecatedString::formatted("{}/sql", Core::StandardPaths::data_directory());
TRY(Core::Directory::create(database_path, Core::Directory::CreateDirectories::Yes));
TRY(Core::System::unveil("/home/anon/sql", "rwc"));
TRY(Core::System::unveil(database_path, "rwc"sv));
TRY(Core::System::unveil(nullptr, nullptr));
Core::EventLoop event_loop;