From 3b7c88c73b45349b84df2f85a5da2a4c65e9826c Mon Sep 17 00:00:00 2001 From: "Dr. Patrick Urbanke" Date: Wed, 9 Apr 2025 09:20:54 +0200 Subject: [PATCH] Added to_select_from --- include/sqlgen/dynamic/Statement.hpp | 3 ++- include/sqlgen/sqlite/Connection.hpp | 3 +++ src/sqlgen/sqlite/Connection.cpp | 24 ++++++++++++++++++++++++ tests/sqlite/test_to_select_from.cpp | 24 ++++++++++++++++++++++++ 4 files changed, 53 insertions(+), 1 deletion(-) create mode 100644 tests/sqlite/test_to_select_from.cpp diff --git a/include/sqlgen/dynamic/Statement.hpp b/include/sqlgen/dynamic/Statement.hpp index f9803ab..20ed123 100644 --- a/include/sqlgen/dynamic/Statement.hpp +++ b/include/sqlgen/dynamic/Statement.hpp @@ -5,10 +5,11 @@ #include "CreateTable.hpp" #include "Insert.hpp" +#include "SelectFrom.hpp" namespace sqlgen::dynamic { -using Statement = rfl::TaggedUnion<"stmt", CreateTable, Insert>; +using Statement = rfl::TaggedUnion<"stmt", CreateTable, Insert, SelectFrom>; } // namespace sqlgen::dynamic diff --git a/include/sqlgen/sqlite/Connection.hpp b/include/sqlgen/sqlite/Connection.hpp index 53f9e57..51fc971 100644 --- a/include/sqlgen/sqlite/Connection.hpp +++ b/include/sqlgen/sqlite/Connection.hpp @@ -64,6 +64,9 @@ class Connection : public sqlgen::Connection { /// Expresses the properies as SQL. std::string properties_to_sql(const dynamic::types::Properties& _p) noexcept; + /// Transforms an Insert Statement to an SQL string. + std::string select_from_to_sql(const dynamic::SelectFrom& _stmt) noexcept; + /// Expresses the type as SQL. std::string type_to_sql(const dynamic::Type& _type) noexcept; diff --git a/src/sqlgen/sqlite/Connection.cpp b/src/sqlgen/sqlite/Connection.cpp index efe5da0..1be50dd 100644 --- a/src/sqlgen/sqlite/Connection.cpp +++ b/src/sqlgen/sqlite/Connection.cpp @@ -119,12 +119,36 @@ std::string Connection::to_sql(const dynamic::Statement& _stmt) noexcept { return create_table_to_sql(_s); } else if constexpr (std::is_same_v) { return insert_to_sql(_s); + } else if constexpr (std::is_same_v) { + return select_from_to_sql(_s); } else { static_assert(rfl::always_false_v, "Unsupported type."); } }); } +std::string Connection::select_from_to_sql( + const dynamic::SelectFrom& _stmt) noexcept { + using namespace std::ranges::views; + + const auto to_str = [](const auto& _col) -> std::string { + return "\"" + _col.name + "\""; + }; + + std::stringstream stream; + stream << "SELECT "; + stream << internal::strings::join( + ", ", internal::collect::vector(_stmt.columns | transform(to_str))); + + stream << " FROM "; + if (_stmt.table.schema) { + stream << "\"" << *_stmt.table.schema << "\"."; + } + stream << "\"" << _stmt.table.name << "\";"; + + return stream.str(); +} + Result Connection::start_write(const dynamic::Insert& _stmt) { if (stmt_) { return error( diff --git a/tests/sqlite/test_to_select_from.cpp b/tests/sqlite/test_to_select_from.cpp new file mode 100644 index 0000000..af64058 --- /dev/null +++ b/tests/sqlite/test_to_select_from.cpp @@ -0,0 +1,24 @@ +#include + +#include +#include +#include + +namespace test_to_select_from { + +struct TestTable { + std::string field1; + int32_t field2; + sqlgen::PrimaryKey id; + std::optional nullable; +}; + +TEST(sqlite, test_to_select_from) { + const auto select_from_stmt = sqlgen::parsing::to_select_from(); + const auto conn = sqlgen::sqlite::connect().value(); + const auto expected = + R"(SELECT "field1", "field2", "id", "nullable" FROM "TestTable";)"; + + EXPECT_EQ(conn->to_sql(select_from_stmt), expected); +} +} // namespace test_to_select_from