diff --git a/cpp/functions/core/sql_workbench.cpp b/cpp/functions/core/sql_workbench.cpp index ded12b54..7513051c 100644 --- a/cpp/functions/core/sql_workbench.cpp +++ b/cpp/functions/core/sql_workbench.cpp @@ -1,5 +1,6 @@ #include "core/sql_workbench.h" +#include "core/sql_parse.h" #include "core/text_editor.h" #include "core/tokens.h" #include "core/button.h" @@ -25,24 +26,19 @@ namespace fn { namespace { -std::string ltrim(const std::string& s) { - size_t i = 0; - while (i < s.size() && std::isspace(static_cast(s[i]))) ++i; - return s.substr(i); -} - -std::string upper_first_token(const std::string& sql) { - std::string t = ltrim(sql); - size_t end = 0; - while (end < t.size() && !std::isspace(static_cast(t[end]))) ++end; - std::string tok = t.substr(0, end); - for (auto& c : tok) c = static_cast(std::toupper(static_cast(c))); - return tok; +// Clasifica el primer statement con sql_parse pure. Si el input no contiene +// statements (todo whitespace/comentarios), devuelve Unknown. +fn_ui::SqlStmtKind first_stmt_kind(const std::string& sql) { + auto stmts = fn_ui::sql_parse(sql); + if (stmts.empty()) return fn_ui::SqlStmtKind::Unknown; + return stmts.front().kind; } bool is_readonly_stmt(const std::string& sql) { - const std::string head = upper_first_token(sql); - return head == "SELECT" || head == "PRAGMA" || head == "EXPLAIN" || head == "WITH"; + using K = fn_ui::SqlStmtKind; + K k = first_stmt_kind(sql); + // sql_parse clasifica WITH como Select; Pragma y Explain son readonly. + return k == K::Select || k == K::Pragma || k == K::Explain; } TextEditorState* editor_of(SqlWorkbenchState& state) { diff --git a/cpp/functions/core/sql_workbench.md b/cpp/functions/core/sql_workbench.md index 2b4d219e..64a3ccc5 100644 --- a/cpp/functions/core/sql_workbench.md +++ b/cpp/functions/core/sql_workbench.md @@ -8,7 +8,7 @@ purity: impure signature: "void fn::sql_workbench(const char* id, sqlite3* db, fn::SqlWorkbenchState& state, ImVec2 size); bool fn::sql_workbench_run_query(sqlite3*, const char*, fn::SqlWorkbenchState&); void fn::sql_workbench_load_schema(sqlite3*, fn::SqlWorkbenchState&); void fn::sql_workbench_destroy(fn::SqlWorkbenchState&)" description: "Workbench SQL embebido en ImGui: editor con highlighting (text_editor + CodeLang::SQL), tabla de resultados (table_view), sidebar de schema (sqlite_master) e historial. Ejecuta queries contra una sqlite3* del caller (no abre/cierra la DB)." tags: [imgui, sql, sqlite, editor, table, dashboard, registry, debug] -uses_functions: ["button_cpp_core", "table_view_cpp_viz", "text_editor_cpp_core", "tokens_cpp_core"] +uses_functions: ["button_cpp_core", "sql_parse_cpp_core", "table_view_cpp_viz", "text_editor_cpp_core", "tokens_cpp_core"] uses_types: [] returns: [] returns_optional: false