1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 19:07:35 +00:00

SQLServer+SQLStudio+sql: Allow sending placeholder values to SQLServer

This commit is contained in:
Timothy Flynn 2022-12-02 08:17:50 -05:00 committed by Andreas Kling
parent b13527b8b2
commit 8fcb8c30c6
7 changed files with 16 additions and 10 deletions

View file

@ -479,7 +479,7 @@ DeprecatedString MainWidget::read_next_sql_statement_of_editor()
} while ((m_editor_line_level > 0) || piece.is_empty()); } while ((m_editor_line_level > 0) || piece.is_empty());
auto statement_id = m_sql_client->prepare_statement(m_connection_id, piece.to_deprecated_string()); 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(); return piece.to_deprecated_string();
} }

View file

@ -71,12 +71,13 @@ Messages::SQLServer::PrepareStatementResponse ConnectionFromClient::prepare_stat
return { result.value() }; return { result.value() };
} }
void ConnectionFromClient::execute_statement(int statement_id) void ConnectionFromClient::execute_statement(int statement_id, Vector<SQL::Value> const& placeholder_values)
{ {
dbgln_if(SQLSERVER_DEBUG, "ConnectionFromClient::execute_query_statement(statement_id: {})", statement_id); dbgln_if(SQLSERVER_DEBUG, "ConnectionFromClient::execute_query_statement(statement_id: {})", statement_id);
auto statement = SQLStatement::statement_for(statement_id); auto statement = SQLStatement::statement_for(statement_id);
if (statement && statement->connection()->client_id() == client_id()) { if (statement && statement->connection()->client_id() == client_id()) {
statement->execute(); // FIXME: Support taking parameters from IPC requests.
statement->execute(move(const_cast<Vector<SQL::Value>&>(placeholder_values)));
} else { } else {
dbgln_if(SQLSERVER_DEBUG, "Statement has disappeared"); dbgln_if(SQLSERVER_DEBUG, "Statement has disappeared");
async_execution_error(statement_id, (int)SQL::SQLErrorCode::StatementUnavailable, DeprecatedString::formatted("{}", statement_id)); async_execution_error(statement_id, (int)SQL::SQLErrorCode::StatementUnavailable, DeprecatedString::formatted("{}", statement_id));

View file

@ -7,6 +7,7 @@
#pragma once #pragma once
#include <AK/HashMap.h> #include <AK/HashMap.h>
#include <AK/Vector.h>
#include <LibIPC/ConnectionFromClient.h> #include <LibIPC/ConnectionFromClient.h>
#include <SQLServer/SQLClientEndpoint.h> #include <SQLServer/SQLClientEndpoint.h>
#include <SQLServer/SQLServerEndpoint.h> #include <SQLServer/SQLServerEndpoint.h>
@ -29,7 +30,7 @@ private:
virtual Messages::SQLServer::ConnectResponse connect(DeprecatedString const&) override; virtual Messages::SQLServer::ConnectResponse connect(DeprecatedString const&) override;
virtual Messages::SQLServer::PrepareStatementResponse prepare_statement(int, 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<SQL::Value> const& placeholder_values) override;
virtual void disconnect(int) override; virtual void disconnect(int) override;
}; };

View file

@ -1,7 +1,9 @@
#include <LibSQL/Value.h>
endpoint SQLServer endpoint SQLServer
{ {
connect(DeprecatedString name) => (int connection_id) connect(DeprecatedString name) => (int connection_id)
prepare_statement(int connection_id, DeprecatedString statement) => (int statement_id) prepare_statement(int connection_id, DeprecatedString statement) => (int statement_id)
execute_statement(int statement_id) =| execute_statement(int statement_id, Vector<SQL::Value> placeholder_values) =|
disconnect(int connection_id) =| disconnect(int connection_id) =|
} }

View file

@ -61,19 +61,20 @@ void SQLStatement::report_error(SQL::Result result)
m_result = {}; m_result = {};
} }
void SQLStatement::execute() void SQLStatement::execute(Vector<SQL::Value> placeholder_values)
{ {
dbgln_if(SQLSERVER_DEBUG, "SQLStatement::execute(statement_id {}", statement_id()); dbgln_if(SQLSERVER_DEBUG, "SQLStatement::execute(statement_id {}", statement_id());
auto client_connection = ConnectionFromClient::client_connection_for(connection()->client_id()); auto client_connection = ConnectionFromClient::client_connection_for(connection()->client_id());
if (!client_connection) { if (!client_connection) {
warnln("Cannot yield next result. Client disconnected"); warnln("Cannot yield next result. Client disconnected");
return; return;
} }
deferred_invoke([this] { deferred_invoke([this, placeholder_values = move(placeholder_values)] {
VERIFY(!connection()->database().is_null()); 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()) { if (execution_result.is_error()) {
report_error(execution_result.release_error()); report_error(execution_result.release_error());
return; return;

View file

@ -8,6 +8,7 @@
#include <AK/DeprecatedString.h> #include <AK/DeprecatedString.h>
#include <AK/NonnullRefPtr.h> #include <AK/NonnullRefPtr.h>
#include <AK/Vector.h>
#include <LibCore/Object.h> #include <LibCore/Object.h>
#include <LibSQL/AST/AST.h> #include <LibSQL/AST/AST.h>
#include <LibSQL/Result.h> #include <LibSQL/Result.h>
@ -27,7 +28,7 @@ public:
static RefPtr<SQLStatement> statement_for(int statement_id); static RefPtr<SQLStatement> statement_for(int statement_id);
int statement_id() const { return m_statement_id; } int statement_id() const { return m_statement_id; }
DatabaseConnection* connection() { return dynamic_cast<DatabaseConnection*>(parent()); } DatabaseConnection* connection() { return dynamic_cast<DatabaseConnection*>(parent()); }
void execute(); void execute(Vector<SQL::Value> placeholder_values);
private: private:
SQLStatement(DatabaseConnection&, NonnullRefPtr<SQL::AST::Statement> statement); SQLStatement(DatabaseConnection&, NonnullRefPtr<SQL::AST::Statement> statement);

View file

@ -292,7 +292,7 @@ private:
}); });
} else { } else {
auto statement_id = m_sql_client->prepare_statement(m_connection_id, piece); 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. // ...But m_keep_running can also be set to false by a command handler.