From 5ef2d20133734f343a77d69e307ea08063d9f7b1 Mon Sep 17 00:00:00 2001 From: florijan Date: Thu, 23 Nov 2017 14:26:53 +0100 Subject: [PATCH] Add single query manual test Summary: Practical for debugging trivial queries: ``` ~ gdb --args ./tests/manual/single_query "RETURN 2 + 1" Reviewers: mislav.bradac Reviewed By: mislav.bradac Differential Revision: https://phabricator.memgraph.io/D1003 --- src/communication/result_stream_faker.hpp | 67 ++++++++++++++++++++ src/query/console.cpp | 75 +---------------------- src/query/console.hpp | 3 - tests/manual/single_query.cpp | 21 +++++++ 4 files changed, 90 insertions(+), 76 deletions(-) create mode 100644 tests/manual/single_query.cpp diff --git a/src/communication/result_stream_faker.hpp b/src/communication/result_stream_faker.hpp index a53dc5178..d8194f9ec 100644 --- a/src/communication/result_stream_faker.hpp +++ b/src/communication/result_stream_faker.hpp @@ -50,6 +50,73 @@ class ResultStreamFaker { return summary_; } + friend std::ostream &operator<<(std::ostream &os, + const ResultStreamFaker &results) { + auto typed_value_to_string = [](const query::TypedValue &value) { + std::stringstream ss; + ss << value; + return ss.str(); + }; + const std::vector &header = results.GetHeader(); + std::vector column_widths(header.size()); + std::transform(header.begin(), header.end(), column_widths.begin(), + [](const auto &s) { return s.size(); }); + + // convert all the results into strings, and track max column width + auto &results_data = results.GetResults(); + std::vector> result_strings( + results_data.size(), std::vector(column_widths.size())); + for (int row_ind = 0; row_ind < static_cast(results_data.size()); + ++row_ind) { + for (int col_ind = 0; col_ind < static_cast(column_widths.size()); + ++col_ind) { + std::string string_val = + typed_value_to_string(results_data[row_ind][col_ind]); + column_widths[col_ind] = + std::max(column_widths[col_ind], (int)string_val.size()); + result_strings[row_ind][col_ind] = string_val; + } + } + + // output a results table + // first define some helper functions + auto emit_horizontal_line = [&]() { + os << "+"; + for (auto col_width : column_widths) + os << std::string((unsigned long)col_width + 2, '-') << "+"; + os << std::endl; + }; + + auto emit_result_vec = [&](const std::vector result_vec) { + os << "| "; + for (int col_ind = 0; col_ind < static_cast(column_widths.size()); + ++col_ind) { + const std::string &res = result_vec[col_ind]; + os << res << std::string(column_widths[col_ind] - res.size(), ' '); + os << " | "; + } + os << std::endl; + }; + + // final output of results + emit_horizontal_line(); + emit_result_vec(results.GetHeader()); + emit_horizontal_line(); + for (const auto &result_vec : result_strings) emit_result_vec(result_vec); + emit_horizontal_line(); + os << "Found " << results_data.size() << " matching results" << std::endl; + + // output the summary + os << "Query summary: {"; + utils::PrintIterable(os, results.GetSummary(), ", ", + [&](auto &stream, const auto &kv) { + stream << kv.first << ": " << kv.second; + }); + os << "}" << std::endl; + + return os; + } + private: /** * Possible states of the Mocker. Used for checking if calls to diff --git a/src/query/console.cpp b/src/query/console.cpp index d0161c9e2..6ac1aaebe 100644 --- a/src/query/console.cpp +++ b/src/query/console.cpp @@ -10,6 +10,7 @@ #include #include +#include "communication/result_stream_faker.hpp" #include "query/exceptions.hpp" #include "query/interpreter.hpp" #include "query/typed_value.hpp" @@ -51,78 +52,6 @@ std::string ReadLine(const char *prompt) { #endif // HAS_READLINE -/** - * Converts the given TypedValue into a string (single line). - */ -std::string TypedValueToString(const query::TypedValue &value) { - std::stringstream ss; - ss << value; - return ss.str(); -} - -/** - * Prints out all the given results to standard out. - */ -void PrintResults(const ResultStreamFaker &results) { - const std::vector &header = results.GetHeader(); - std::vector column_widths(header.size()); - std::transform(header.begin(), header.end(), column_widths.begin(), - [](const auto &s) { return s.size(); }); - - // convert all the results into strings, and track max column width - auto &results_data = results.GetResults(); - std::vector> result_strings( - results_data.size(), std::vector(column_widths.size())); - for (int row_ind = 0; row_ind < static_cast(results_data.size()); - ++row_ind) { - for (int col_ind = 0; col_ind < static_cast(column_widths.size()); - ++col_ind) { - std::string string_val = - TypedValueToString(results_data[row_ind][col_ind]); - column_widths[col_ind] = - std::max(column_widths[col_ind], (int)string_val.size()); - result_strings[row_ind][col_ind] = string_val; - } - } - - // output a results table - // first define some helper functions - auto emit_horizontal_line = [&]() { - std::cout << "+"; - for (auto col_width : column_widths) - std::cout << std::string((unsigned long)col_width + 2, '-') << "+"; - std::cout << std::endl; - }; - - auto emit_result_vec = [&](const std::vector result_vec) { - std::cout << "| "; - for (int col_ind = 0; col_ind < static_cast(column_widths.size()); - ++col_ind) { - const std::string &res = result_vec[col_ind]; - std::cout << res << std::string(column_widths[col_ind] - res.size(), ' '); - std::cout << " | "; - } - std::cout << std::endl; - }; - - // final output of results - emit_horizontal_line(); - emit_result_vec(results.GetHeader()); - emit_horizontal_line(); - for (const auto &result_vec : result_strings) emit_result_vec(result_vec); - emit_horizontal_line(); - std::cout << "Found " << results_data.size() << " matching results" - << std::endl; - - // output the summary - std::cout << "Query summary: {"; - utils::PrintIterable(std::cout, results.GetSummary(), ", ", - [&](auto &stream, const auto &kv) { - stream << kv.first << ": " << kv.second; - }); - std::cout << "}" << std::endl; -} - void query::Repl(GraphDb &db) { std::cout << "Welcome to *Awesome* Memgraph Read Evaluate Print Loop (AM-REPL)" @@ -141,7 +70,7 @@ void query::Repl(GraphDb &db) { GraphDbAccessor dba(db); ResultStreamFaker results; interpeter.Interpret(command, dba, results, {}, false); - PrintResults(results); + std::cout << results; dba.Commit(); } catch (const query::SyntaxException &e) { std::cout << "SYNTAX EXCEPTION: " << e.what() << std::endl; diff --git a/src/query/console.hpp b/src/query/console.hpp index 703717feb..e4d7fb37c 100644 --- a/src/query/console.hpp +++ b/src/query/console.hpp @@ -5,9 +5,6 @@ #pragma once -#include - -#include "communication/result_stream_faker.hpp" #include "database/graph_db.hpp" namespace query { diff --git a/tests/manual/single_query.cpp b/tests/manual/single_query.cpp new file mode 100644 index 000000000..a2eca6b82 --- /dev/null +++ b/tests/manual/single_query.cpp @@ -0,0 +1,21 @@ +#include "communication/result_stream_faker.hpp" +#include "database/graph_db.hpp" +#include "database/graph_db_accessor.hpp" +#include "query/interpreter.hpp" + +int main(int argc, char *argv[]) { + gflags::ParseCommandLineFlags(&argc, &argv, true); + + // parse the first cmd line argument as the query + if (argc < 2) { + std::cout << "Usage: ./single_query 'RETURN \"query here\"'" << std::endl; + exit(1); + } + GraphDb db; + GraphDbAccessor dba(db); + ResultStreamFaker results; + query::Interpreter interpeter; + interpeter.Interpret(argv[1], dba, results, {}, false); + std::cout << results; + return 0; +}