1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 17:37:37 +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());
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();
}

View file

@ -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<SQL::Value> 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<Vector<SQL::Value>&>(placeholder_values)));
} else {
dbgln_if(SQLSERVER_DEBUG, "Statement has disappeared");
async_execution_error(statement_id, (int)SQL::SQLErrorCode::StatementUnavailable, DeprecatedString::formatted("{}", statement_id));

View file

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

View file

@ -1,7 +1,9 @@
#include <LibSQL/Value.h>
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<SQL::Value> placeholder_values) =|
disconnect(int connection_id) =|
}

View file

@ -61,19 +61,20 @@ void SQLStatement::report_error(SQL::Result result)
m_result = {};
}
void SQLStatement::execute()
void SQLStatement::execute(Vector<SQL::Value> 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;

View file

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

View file

@ -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.