summaryrefslogtreecommitdiff
path: root/Userland/Services
diff options
context:
space:
mode:
authorTimothy Flynn <trflynn89@pm.me>2022-12-09 14:52:43 -0500
committerTim Flynn <trflynn89@pm.me>2022-12-11 10:08:17 -0500
commit12152a4556d2c7b7243fc89e170d8949adbfcb3f (patch)
treeda30f99e55096841a788549ab7e74340fa480729 /Userland/Services
parent6b64485b40e6324caecf943d1d113cd6216d2af9 (diff)
downloadserenity-12152a4556d2c7b7243fc89e170d8949adbfcb3f.zip
SQLServer: Re-use already opened SQL::Database objects
Currently, we create a new SQL::Database object for each database we are requested to open. When multiple clients connect to the same database, the same underlying database file is opened and cached each time. This results in updates from one client not being propagated to others. To prevent this, when a database is requested to be open, check if it is already open. We can then re-use that SQL::Database object for the new connection.
Diffstat (limited to 'Userland/Services')
-rw-r--r--Userland/Services/SQLServer/DatabaseConnection.cpp14
-rw-r--r--Userland/Services/SQLServer/DatabaseConnection.h1
2 files changed, 13 insertions, 2 deletions
diff --git a/Userland/Services/SQLServer/DatabaseConnection.cpp b/Userland/Services/SQLServer/DatabaseConnection.cpp
index 0373962cc0..581b740fb9 100644
--- a/Userland/Services/SQLServer/DatabaseConnection.cpp
+++ b/Userland/Services/SQLServer/DatabaseConnection.cpp
@@ -13,6 +13,17 @@ namespace SQLServer {
static HashMap<SQL::ConnectionID, NonnullRefPtr<DatabaseConnection>> s_connections;
static SQL::ConnectionID s_next_connection_id = 0;
+static ErrorOr<NonnullRefPtr<SQL::Database>> find_or_create_database(StringView database_path, StringView database_name)
+{
+ for (auto const& connection : s_connections) {
+ if (connection.value->database_name() == database_name)
+ return connection.value->database();
+ }
+
+ auto database_file = DeprecatedString::formatted("{}/{}.db", database_path, database_name);
+ return SQL::Database::try_create(move(database_file));
+}
+
RefPtr<DatabaseConnection> DatabaseConnection::connection_for(SQL::ConnectionID connection_id)
{
if (s_connections.contains(connection_id))
@@ -26,8 +37,7 @@ ErrorOr<NonnullRefPtr<DatabaseConnection>> DatabaseConnection::create(StringView
if (LexicalPath path(database_name); (path.title() != database_name) || (path.dirname() != "."))
return Error::from_string_view("Invalid database name"sv);
- auto database_file = DeprecatedString::formatted("{}/{}.db", database_path, database_name);
- auto database = SQL::Database::construct(move(database_file));
+ auto database = TRY(find_or_create_database(database_path, database_name));
if (auto result = database->open(); result.is_error()) {
warnln("Could not open database: {}", result.error().error_string());
diff --git a/Userland/Services/SQLServer/DatabaseConnection.h b/Userland/Services/SQLServer/DatabaseConnection.h
index bab3ff87f3..d43e449b2c 100644
--- a/Userland/Services/SQLServer/DatabaseConnection.h
+++ b/Userland/Services/SQLServer/DatabaseConnection.h
@@ -26,6 +26,7 @@ public:
SQL::ConnectionID connection_id() const { return m_connection_id; }
int client_id() const { return m_client_id; }
NonnullRefPtr<SQL::Database> database() { return m_database; }
+ StringView database_name() const { return m_database_name; }
void disconnect();
SQL::ResultOr<SQL::StatementID> prepare_statement(StringView sql);