forked from SerenityOS/serenity
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
LibSQL+SQLServer: Build SQLServer system service
This patch introduces the SQLServer system server. This service is supposed to be the only process/application talking to database storage. This makes things like locking and caching more reliable, easier to implement, and more efficient. In LibSQL we added a client component that does the ugly IPC nitty- gritty for you. All that's needed is setting a number of event handler lambdas and you can connect to databases and execute statements on them. Applications that wish to use this SQLClient class obviously need to link LibSQL and LibIPC.
- Loading branch information
1 parent
1037d6b
commit a034774
Showing
19 changed files
with
650 additions
and
12 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
file(GLOB TEST_SOURCES CONFIGURE_DEPENDS "*.cpp") | ||
|
||
foreach(source ${TEST_SOURCES}) | ||
serenity_test(${source} LibSQL LIBS LibSQL) | ||
serenity_test(${source} LibSQL LIBS LibSQL LibIPC) | ||
endforeach() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
/* | ||
* Copyright (c) 2021, Jan de Visser <[email protected]> | ||
* | ||
* SPDX-License-Identifier: BSD-2-Clause | ||
*/ | ||
|
||
#include <LibSQL/SQLClient.h> | ||
|
||
namespace SQL { | ||
|
||
SQLClient::~SQLClient() | ||
{ | ||
} | ||
|
||
void SQLClient::connected(int connection_id) | ||
{ | ||
if (on_connected) | ||
on_connected(connection_id); | ||
} | ||
|
||
void SQLClient::disconnected(int connection_id) | ||
{ | ||
if (on_disconnected) | ||
on_disconnected(connection_id); | ||
} | ||
|
||
void SQLClient::connection_error(int connection_id, int code, String const& message) | ||
{ | ||
if (on_connection_error) | ||
on_connection_error(connection_id, code, message); | ||
else | ||
warnln("Connection error for connection_id {}: {} ({})", connection_id, message, code); | ||
} | ||
|
||
void SQLClient::execution_error(int statement_id, int code, String const& message) | ||
{ | ||
if (on_execution_error) | ||
on_execution_error(statement_id, code, message); | ||
else | ||
warnln("Execution error for statement_id {}: {} ({})", statement_id, message, code); | ||
} | ||
|
||
void SQLClient::execution_success(int statement_id, bool has_results, int created, int updated, int deleted) | ||
{ | ||
if (on_execution_success) | ||
on_execution_success(statement_id, has_results, created, updated, deleted); | ||
else | ||
outln("{} row(s) created, {} updated, {} deleted", created, updated, deleted); | ||
} | ||
|
||
void SQLClient::next_result(int statement_id, Vector<String> const& row) | ||
{ | ||
if (on_next_result) { | ||
on_next_result(statement_id, row); | ||
return; | ||
} | ||
bool first = true; | ||
for (auto& column : row) { | ||
if (!first) | ||
out(", "); | ||
out("\"{}\"", column); | ||
first = false; | ||
} | ||
outln(); | ||
} | ||
|
||
void SQLClient::results_exhausted(int statement_id, int total_rows) | ||
{ | ||
if (on_results_exhausted) | ||
on_results_exhausted(statement_id, total_rows); | ||
else | ||
outln("{} total row(s)", total_rows); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
/* | ||
* Copyright (c) 2021, Jan de Visser <[email protected]> | ||
* | ||
* SPDX-License-Identifier: BSD-2-Clause | ||
*/ | ||
|
||
#pragma once | ||
|
||
#include <LibIPC/ServerConnection.h> | ||
#include <SQLServer/SQLClientEndpoint.h> | ||
#include <SQLServer/SQLServerEndpoint.h> | ||
|
||
namespace SQL { | ||
|
||
class SQLClient | ||
: public IPC::ServerConnection<SQLClientEndpoint, SQLServerEndpoint> | ||
, public SQLClientEndpoint { | ||
C_OBJECT(SQLClient); | ||
virtual ~SQLClient(); | ||
|
||
Function<void(int)> on_connected; | ||
Function<void(int)> on_disconnected; | ||
Function<void(int, int, String const&)> on_connection_error; | ||
Function<void(int, int, String const&)> on_execution_error; | ||
Function<void(int, bool, int, int, int)> on_execution_success; | ||
Function<void(int, Vector<String> const&)> on_next_result; | ||
Function<void(int, int)> on_results_exhausted; | ||
|
||
private: | ||
SQLClient() | ||
: IPC::ServerConnection<SQLClientEndpoint, SQLServerEndpoint>(*this, "/tmp/portal/sql") | ||
{ | ||
} | ||
|
||
virtual void connected(int connection_id) override; | ||
virtual void connection_error(int connection_id, int code, String const& message) override; | ||
virtual void execution_success(int statement_id, bool has_results, int created, int updated, int deleted) override; | ||
virtual void next_result(int statement_id, Vector<String> const&) override; | ||
virtual void results_exhausted(int statement_id, int total_rows) override; | ||
virtual void execution_error(int statement_id, int code, String const& message) override; | ||
virtual void disconnected(int connection_id) override; | ||
}; | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
serenity_component( | ||
SQLServer | ||
REQUIRED | ||
TARGETS SQLServer | ||
) | ||
|
||
compile_ipc(SQLServer.ipc SQLServerEndpoint.h) | ||
compile_ipc(SQLClient.ipc SQLClientEndpoint.h) | ||
|
||
set(SOURCES | ||
ClientConnection.cpp | ||
DatabaseConnection.cpp | ||
main.cpp | ||
SQLClientEndpoint.h | ||
SQLServerEndpoint.h | ||
SQLStatement.cpp | ||
) | ||
|
||
serenity_bin(SQLServer) | ||
target_link_libraries(SQLServer LibCore LibIPC LibSQL) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
/* | ||
* Copyright (c) 2021, Jan de Visser <[email protected]> | ||
* | ||
* SPDX-License-Identifier: BSD-2-Clause | ||
*/ | ||
|
||
#include <AK/String.h> | ||
#include <AK/Vector.h> | ||
#include <LibSQL/SQLResult.h> | ||
#include <SQLServer/ClientConnection.h> | ||
#include <SQLServer/DatabaseConnection.h> | ||
#include <SQLServer/SQLStatement.h> | ||
|
||
namespace SQLServer { | ||
|
||
static HashMap<int, RefPtr<ClientConnection>> s_connections; | ||
|
||
RefPtr<ClientConnection> ClientConnection::client_connection_for(int client_id) | ||
{ | ||
if (s_connections.contains(client_id)) | ||
return *s_connections.get(client_id).value(); | ||
dbgln_if(SQLSERVER_DEBUG, "Invalid client_id {}", client_id); | ||
return nullptr; | ||
} | ||
|
||
ClientConnection::ClientConnection(AK::NonnullRefPtr<Core::LocalSocket> socket, int client_id) | ||
: IPC::ClientConnection<SQLClientEndpoint, SQLServerEndpoint>(*this, move(socket), client_id) | ||
{ | ||
s_connections.set(client_id, *this); | ||
} | ||
|
||
ClientConnection::~ClientConnection() | ||
{ | ||
} | ||
|
||
void ClientConnection::die() | ||
{ | ||
s_connections.remove(client_id()); | ||
} | ||
|
||
Messages::SQLServer::ConnectResponse ClientConnection::connect(String const& database_name) | ||
{ | ||
dbgln_if(SQLSERVER_DEBUG, "ClientConnection::connect(database_name: {})", database_name); | ||
auto database_connection = DatabaseConnection::construct(database_name, client_id()); | ||
return { database_connection->connection_id() }; | ||
} | ||
|
||
void ClientConnection::disconnect(int connection_id) | ||
{ | ||
dbgln_if(SQLSERVER_DEBUG, "ClientConnection::disconnect(connection_id: {})", connection_id); | ||
auto database_connection = DatabaseConnection::connection_for(connection_id); | ||
if (database_connection) | ||
database_connection->disconnect(); | ||
else | ||
dbgln("Database connection has disappeared"); | ||
} | ||
|
||
Messages::SQLServer::SqlStatementResponse ClientConnection::sql_statement(int connection_id, String const& sql) | ||
{ | ||
dbgln_if(SQLSERVER_DEBUG, "ClientConnection::sql_statement(connection_id: {}, sql: '{}')", connection_id, sql); | ||
auto database_connection = DatabaseConnection::connection_for(connection_id); | ||
if (database_connection) { | ||
auto statement_id = database_connection->sql_statement(sql); | ||
dbgln_if(SQLSERVER_DEBUG, "ClientConnection::sql_statement -> statement_id = {}", statement_id); | ||
return { statement_id }; | ||
} else { | ||
dbgln("Database connection has disappeared"); | ||
return { -1 }; | ||
} | ||
} | ||
|
||
void ClientConnection::statement_execute(int statement_id) | ||
{ | ||
dbgln_if(SQLSERVER_DEBUG, "ClientConnection::statement_execute_query(statement_id: {})", statement_id); | ||
auto statement = SQLStatement::statement_for(statement_id); | ||
if (statement && statement->connection()->client_id() == client_id()) { | ||
statement->execute(); | ||
} else { | ||
dbgln_if(SQLSERVER_DEBUG, "Statement has disappeared"); | ||
async_execution_error(statement_id, (int)SQL::SQLErrorCode::StatementUnavailable, String::formatted("{}", statement_id)); | ||
} | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
/* | ||
* Copyright (c) 2021, Jan de Visser <[email protected]> | ||
* | ||
* SPDX-License-Identifier: BSD-2-Clause | ||
*/ | ||
|
||
#pragma once | ||
|
||
#include <AK/HashMap.h> | ||
#include <LibIPC/ClientConnection.h> | ||
#include <SQLServer/SQLClientEndpoint.h> | ||
#include <SQLServer/SQLServerEndpoint.h> | ||
|
||
namespace SQLServer { | ||
|
||
class ClientConnection final | ||
: public IPC::ClientConnection<SQLClientEndpoint, SQLServerEndpoint> { | ||
C_OBJECT(ClientConnection); | ||
|
||
public: | ||
explicit ClientConnection(NonnullRefPtr<Core::LocalSocket>, int client_id); | ||
virtual ~ClientConnection() override; | ||
|
||
virtual void die() override; | ||
|
||
static RefPtr<ClientConnection> client_connection_for(int client_id); | ||
|
||
private: | ||
virtual Messages::SQLServer::ConnectResponse connect(String const&) override; | ||
virtual Messages::SQLServer::SqlStatementResponse sql_statement(int, String const&) override; | ||
virtual void statement_execute(int) override; | ||
virtual void disconnect(int) override; | ||
}; | ||
|
||
} |
Oops, something went wrong.