From 061525282f9f58d6b0005490c8d4cda821fafb70 Mon Sep 17 00:00:00 2001 From: martinfalisse Date: Sun, 5 Jun 2022 17:58:35 +0200 Subject: [PATCH] SQLStudio: Execute statements in SQL server Make the link between SQLStudio and the SQLServer so that statements written in the editor window are executed by LibSQL when the 'Run' button is clicked. --- Userland/DevTools/SQLStudio/MainWidget.cpp | 83 +++++++++++++++++++++- Userland/DevTools/SQLStudio/MainWidget.h | 9 +++ 2 files changed, 91 insertions(+), 1 deletion(-) diff --git a/Userland/DevTools/SQLStudio/MainWidget.cpp b/Userland/DevTools/SQLStudio/MainWidget.cpp index 564761b273..9f113c33f0 100644 --- a/Userland/DevTools/SQLStudio/MainWidget.cpp +++ b/Userland/DevTools/SQLStudio/MainWidget.cpp @@ -19,6 +19,9 @@ #include #include #include +#include +#include +#include #include "MainWidget.h" #include "ScriptEditor.h" @@ -138,7 +141,10 @@ MainWidget::MainWidget() }); m_run_script_action = GUI::Action::create("Run script", { Mod_Alt, Key_F9 }, Gfx::Bitmap::try_load_from_file("/res/icons/16x16/play.png").release_value_but_fixme_should_propagate_errors(), [&](auto&) { - TODO(); + m_current_line_for_parsing = 0; + // TODO select the database to use in UI. + m_connection_id = m_sql_client->connect("test"); + read_next_sql_statement_of_editor(); }); auto& toolbar_container = add(); @@ -194,6 +200,11 @@ MainWidget::MainWidget() m_query_results_widget->set_layout(); m_query_results_widget->layout()->set_margins(6); m_query_results_table_view = m_query_results_widget->add(); + + m_sql_client = SQL::SQLClient::try_create().release_value_but_fixme_should_propagate_errors(); + m_sql_client->on_execution_success = [this](int, bool, int, int, int) { + read_next_sql_statement_of_editor(); + }; } void MainWidget::initialize_menu(GUI::Window* window) @@ -363,4 +374,74 @@ void MainWidget::drop_event(GUI::DropEvent& drop_event) } } +String MainWidget::read_next_sql_statement_of_editor() +{ + StringBuilder piece; + do { + if (!piece.is_empty()) + piece.append('\n'); + + auto line_maybe = read_next_line_of_editor(); + + if (!line_maybe.has_value()) + return {}; + + auto& line = line_maybe.value(); + auto lexer = SQL::AST::Lexer(line); + + piece.append(line); + + bool is_first_token = true; + bool is_command = false; + bool last_token_ended_statement = false; + bool tokens_found = false; + + for (SQL::AST::Token token = lexer.next(); token.type() != SQL::AST::TokenType::Eof; token = lexer.next()) { + tokens_found = true; + switch (token.type()) { + case SQL::AST::TokenType::ParenOpen: + ++m_editor_line_level; + break; + case SQL::AST::TokenType::ParenClose: + --m_editor_line_level; + break; + case SQL::AST::TokenType::SemiColon: + last_token_ended_statement = true; + break; + case SQL::AST::TokenType::Period: + if (is_first_token) + is_command = true; + break; + default: + last_token_ended_statement = is_command; + break; + } + + is_first_token = false; + } + + if (tokens_found) + m_editor_line_level = last_token_ended_statement ? 0 : (m_editor_line_level > 0 ? m_editor_line_level : 1); + } while ((m_editor_line_level > 0) || piece.is_empty()); + + auto statement_id = m_sql_client->sql_statement(m_connection_id, piece.to_string()); + m_sql_client->async_statement_execute(statement_id); + + return piece.to_string(); +} + +Optional MainWidget::read_next_line_of_editor() +{ + auto editor = dynamic_cast(m_tab_widget->active_widget()); + if (!editor) + return {}; + if (m_current_line_for_parsing < editor->document().line_count()) { + String result = editor->document().line(m_current_line_for_parsing).to_utf8(); + m_current_line_for_parsing++; + return result; + } else { + return {}; + } +} + } diff --git a/Userland/DevTools/SQLStudio/MainWidget.h b/Userland/DevTools/SQLStudio/MainWidget.h index 4d484c59c0..4698a9c5c1 100644 --- a/Userland/DevTools/SQLStudio/MainWidget.h +++ b/Userland/DevTools/SQLStudio/MainWidget.h @@ -9,6 +9,7 @@ #include #include #include +#include namespace SQLStudio { @@ -54,6 +55,14 @@ private: RefPtr m_statusbar; RefPtr m_query_results_widget; RefPtr m_query_results_table_view; + + RefPtr m_sql_client; + + String read_next_sql_statement_of_editor(); + Optional read_next_line_of_editor(); + size_t m_current_line_for_parsing { 0 }; + int m_editor_line_level { 0 }; + int m_connection_id { 0 }; }; }