From 8fcb8c30c68b6167a6b49a4144afe8ec6633f27f Mon Sep 17 00:00:00 2001 From: Timothy Flynn Date: Fri, 2 Dec 2022 08:17:50 -0500 Subject: [PATCH] SQLServer+SQLStudio+sql: Allow sending placeholder values to SQLServer --- Userland/DevTools/SQLStudio/MainWidget.cpp | 2 +- Userland/Services/SQLServer/ConnectionFromClient.cpp | 5 +++-- Userland/Services/SQLServer/ConnectionFromClient.h | 3 ++- Userland/Services/SQLServer/SQLServer.ipc | 4 +++- Userland/Services/SQLServer/SQLStatement.cpp | 7 ++++--- Userland/Services/SQLServer/SQLStatement.h | 3 ++- Userland/Utilities/sql.cpp | 2 +- 7 files changed, 16 insertions(+), 10 deletions(-) diff --git a/Userland/DevTools/SQLStudio/MainWidget.cpp b/Userland/DevTools/SQLStudio/MainWidget.cpp index 2547e724a4..a292d0d55c 100644 --- a/Userland/DevTools/SQLStudio/MainWidget.cpp +++ b/Userland/DevTools/SQLStudio/MainWidget.cpp @@ -479,7 +479,7 @@ DeprecatedString MainWidget::read_next_sql_statement_of_editor() } while ((m_editor_line_level > 0) || piece.is_empty()); auto statement_id = m_sql_client->prepare_statement(m_connection_id, piece.to_deprecated_string()); - m_sql_client->async_execute_statement(statement_id); + m_sql_client->async_execute_statement(statement_id, {}); return piece.to_deprecated_string(); } diff --git a/Userland/Services/SQLServer/ConnectionFromClient.cpp b/Userland/Services/SQLServer/ConnectionFromClient.cpp index fddcb1576e..c22045d610 100644 --- a/Userland/Services/SQLServer/ConnectionFromClient.cpp +++ b/Userland/Services/SQLServer/ConnectionFromClient.cpp @@ -71,12 +71,13 @@ Messages::SQLServer::PrepareStatementResponse ConnectionFromClient::prepare_stat return { result.value() }; } -void ConnectionFromClient::execute_statement(int statement_id) +void ConnectionFromClient::execute_statement(int statement_id, Vector const& placeholder_values) { dbgln_if(SQLSERVER_DEBUG, "ConnectionFromClient::execute_query_statement(statement_id: {})", statement_id); auto statement = SQLStatement::statement_for(statement_id); if (statement && statement->connection()->client_id() == client_id()) { - statement->execute(); + // FIXME: Support taking parameters from IPC requests. + statement->execute(move(const_cast&>(placeholder_values))); } else { dbgln_if(SQLSERVER_DEBUG, "Statement has disappeared"); async_execution_error(statement_id, (int)SQL::SQLErrorCode::StatementUnavailable, DeprecatedString::formatted("{}", statement_id)); diff --git a/Userland/Services/SQLServer/ConnectionFromClient.h b/Userland/Services/SQLServer/ConnectionFromClient.h index 227d207d6f..1c6f612d83 100644 --- a/Userland/Services/SQLServer/ConnectionFromClient.h +++ b/Userland/Services/SQLServer/ConnectionFromClient.h @@ -7,6 +7,7 @@ #pragma once #include +#include #include #include #include @@ -29,7 +30,7 @@ private: virtual Messages::SQLServer::ConnectResponse connect(DeprecatedString const&) override; virtual Messages::SQLServer::PrepareStatementResponse prepare_statement(int, DeprecatedString const&) override; - virtual void execute_statement(int) override; + virtual void execute_statement(int, Vector const& placeholder_values) override; virtual void disconnect(int) override; }; diff --git a/Userland/Services/SQLServer/SQLServer.ipc b/Userland/Services/SQLServer/SQLServer.ipc index 233387a5f4..9c67f134d8 100644 --- a/Userland/Services/SQLServer/SQLServer.ipc +++ b/Userland/Services/SQLServer/SQLServer.ipc @@ -1,7 +1,9 @@ +#include + endpoint SQLServer { connect(DeprecatedString name) => (int connection_id) prepare_statement(int connection_id, DeprecatedString statement) => (int statement_id) - execute_statement(int statement_id) =| + execute_statement(int statement_id, Vector placeholder_values) =| disconnect(int connection_id) =| } diff --git a/Userland/Services/SQLServer/SQLStatement.cpp b/Userland/Services/SQLServer/SQLStatement.cpp index 6e33444b48..3bd03dc89b 100644 --- a/Userland/Services/SQLServer/SQLStatement.cpp +++ b/Userland/Services/SQLServer/SQLStatement.cpp @@ -61,19 +61,20 @@ void SQLStatement::report_error(SQL::Result result) m_result = {}; } -void SQLStatement::execute() +void SQLStatement::execute(Vector placeholder_values) { dbgln_if(SQLSERVER_DEBUG, "SQLStatement::execute(statement_id {}", statement_id()); + auto client_connection = ConnectionFromClient::client_connection_for(connection()->client_id()); if (!client_connection) { warnln("Cannot yield next result. Client disconnected"); return; } - deferred_invoke([this] { + deferred_invoke([this, placeholder_values = move(placeholder_values)] { VERIFY(!connection()->database().is_null()); - auto execution_result = m_statement->execute(connection()->database().release_nonnull()); + auto execution_result = m_statement->execute(connection()->database().release_nonnull(), placeholder_values); if (execution_result.is_error()) { report_error(execution_result.release_error()); return; diff --git a/Userland/Services/SQLServer/SQLStatement.h b/Userland/Services/SQLServer/SQLStatement.h index 3088e23766..c4658599f3 100644 --- a/Userland/Services/SQLServer/SQLStatement.h +++ b/Userland/Services/SQLServer/SQLStatement.h @@ -8,6 +8,7 @@ #include #include +#include #include #include #include @@ -27,7 +28,7 @@ public: static RefPtr statement_for(int statement_id); int statement_id() const { return m_statement_id; } DatabaseConnection* connection() { return dynamic_cast(parent()); } - void execute(); + void execute(Vector placeholder_values); private: SQLStatement(DatabaseConnection&, NonnullRefPtr statement); diff --git a/Userland/Utilities/sql.cpp b/Userland/Utilities/sql.cpp index f271e2a27d..94e7050426 100644 --- a/Userland/Utilities/sql.cpp +++ b/Userland/Utilities/sql.cpp @@ -292,7 +292,7 @@ private: }); } else { auto statement_id = m_sql_client->prepare_statement(m_connection_id, piece); - m_sql_client->async_execute_statement(statement_id); + m_sql_client->async_execute_statement(statement_id, {}); } // ...But m_keep_running can also be set to false by a command handler.