Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ else()
message(STATUS "ghidrasql: Fetching libxsql from GitHub (shallow clone)...")
FetchContent_Declare(libxsql
GIT_REPOSITORY https://github.com/0xeb/libxsql.git
GIT_TAG v1.0.7
GIT_TAG v1.0.8
GIT_SHALLOW TRUE
)
FetchContent_MakeAvailable(libxsql)
Expand Down
39 changes: 24 additions & 15 deletions src/cli/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -574,11 +574,14 @@ int run_repl(
return "HTTP already running at " + http.url();
}
int port = http.start(
[&](const std::string& sql) {
std::vector<ghidrasql::QueryResult> results;
std::string error;
const bool ok = engine.execute_script(sql, results, error);
return ghidrasql::script_results_to_json(results, ok, error).dump();
[&](const std::string& sql, xsql::ScriptStatementResult& out) {
const ghidrasql::QueryResult r = engine.query(sql);
out.columns = r.columns;
out.rows.reserve(r.rows.size());
for (const auto& row : r.rows) out.rows.push_back(row.values);
out.success = r.success;
out.error = r.error;
out.elapsed_ms = r.elapsed_ms;
},
[&]() { return engine.info(); },
http_options,
Expand Down Expand Up @@ -871,11 +874,14 @@ int run_headless_live_server(const Args& args) {
http_options.auth_token = args.auth_token;

const int started_port = http.start(
[&](const std::string& sql) {
std::vector<ghidrasql::QueryResult> results;
std::string error;
const bool ok = engine.execute_script(sql, results, error);
return ghidrasql::script_results_to_json(results, ok, error).dump();
[&](const std::string& sql, xsql::ScriptStatementResult& out) {
const ghidrasql::QueryResult r = engine.query(sql);
out.columns = r.columns;
out.rows.reserve(r.rows.size());
for (const auto& row : r.rows) out.rows.push_back(row.values);
out.success = r.success;
out.error = r.error;
out.elapsed_ms = r.elapsed_ms;
},
[&]() { return engine.info(); },
http_options,
Expand Down Expand Up @@ -1043,11 +1049,14 @@ int main(int argc, char** argv) {

if (args.serve) {
int started_port = http.start(
[&](const std::string& sql) {
std::vector<ghidrasql::QueryResult> results;
std::string error;
const bool ok = engine.execute_script(sql, results, error);
return ghidrasql::script_results_to_json(results, ok, error).dump();
[&](const std::string& sql, xsql::ScriptStatementResult& out) {
const ghidrasql::QueryResult r = engine.query(sql);
out.columns = r.columns;
out.rows.reserve(r.rows.size());
for (const auto& row : r.rows) out.rows.push_back(row.values);
out.success = r.success;
out.error = r.error;
out.elapsed_ms = r.elapsed_ms;
},
[&]() { return engine.info(); },
http_options,
Expand Down
5 changes: 4 additions & 1 deletion src/lib/include/ghidrasql/ghidrasql.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,10 @@ class HttpServer {
kForceKilled = 4,
};

using QueryFn = std::function<std::string(const std::string&)>;
// Single-statement executor: runs one SQL statement and fills `out`.
// The thinclient owns multi-statement orchestration + output formatting.
using QueryFn = std::function<void(const std::string& sql,
xsql::ScriptStatementResult& out)>;
using InfoFn = std::function<std::string()>;
using RefreshFn = std::function<bool()>;

Expand Down
5 changes: 3 additions & 2 deletions src/lib/src/http.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,8 @@ int HttpServer::start(QueryFn query_fn, InfoFn info_fn, Options options, Refresh
// a worker is currently busy and how long the oldest in-flight call has
// been running. The wrapper does not change the response body; it only
// brackets the call with two atomic updates.
cfg.query_fn = [this, fn = std::move(query_fn)](const std::string& sql) -> std::string {
cfg.statement_executor = [this, fn = std::move(query_fn)](
const std::string& sql, xsql::ScriptStatementResult& out) {
const auto now_ms = std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::steady_clock::now().time_since_epoch()).count();
latest_query_started_at_ms_.store(now_ms, std::memory_order_relaxed);
Expand All @@ -139,7 +140,7 @@ int HttpServer::start(QueryFn query_fn, InfoFn info_fn, Options options, Refresh
std::atomic<int>* counter;
~CountGuard() { counter->fetch_sub(1, std::memory_order_relaxed); }
} guard{&active_queries_};
return fn(sql);
fn(sql, out);
};

cfg.status_fn = [this]() -> xsql::json {
Expand Down
Loading