Added sqlite support for the insert statement

This commit is contained in:
Dr. Patrick Urbanke
2025-04-05 07:06:07 +02:00
parent 1cd9f01a1e
commit 0a3d965944
4 changed files with 63 additions and 1 deletions
+2 -1
View File
@@ -4,10 +4,11 @@
#include <rfl.hpp>
#include "CreateTable.hpp"
#include "Insert.hpp"
namespace sqlgen::dynamic {
using Statement = rfl::TaggedUnion<"stmt", CreateTable>;
using Statement = rfl::TaggedUnion<"stmt", CreateTable, Insert>;
} // namespace sqlgen::dynamic
+3
View File
@@ -64,6 +64,9 @@ class Connection : public sqlgen::Connection {
/// Transforms a CreateTable Statement to an SQL string.
std::string create_table_to_sql(const dynamic::CreateTable& _stmt) noexcept;
/// Transforms an Insert Statement to an SQL string.
std::string insert_to_sql(const dynamic::Insert& _stmt) noexcept;
/// Generates the underlying connection.
static sqlite3* make_conn(const std::string& _fname);
+34
View File
@@ -68,6 +68,38 @@ Result<Nothing> Connection::execute(const std::string& _sql) noexcept {
return Nothing{};
}
std::string Connection::insert_to_sql(const dynamic::Insert& _stmt) noexcept {
using namespace std::ranges::views;
const auto in_quotes = [](const std::string& _str) -> std::string {
return "\"" + _str + "\"";
};
const auto to_questionmark = [](const std::string&) -> std::string {
return "?";
};
std::stringstream stream;
stream << "INSERT INTO ";
if (_stmt.table.schema) {
stream << "\"" << *_stmt.table.schema << "\".";
}
stream << "\"" << _stmt.table.name << "\" ";
stream << "(";
stream << internal::strings::join(
", ", internal::collect::vector(_stmt.columns | transform(in_quotes)));
stream << ")";
stream << " VALUES (";
stream << internal::strings::join(
", ",
internal::collect::vector(_stmt.columns | transform(to_questionmark)));
stream << ");";
return stream.str();
}
sqlite3* Connection::make_conn(const std::string& _fname) {
sqlite3* conn = nullptr;
const auto err = sqlite3_open(_fname.c_str(), &conn);
@@ -99,6 +131,8 @@ std::string Connection::to_sql(const dynamic::Statement& _stmt) noexcept {
using S = std::remove_cvref_t<decltype(_s)>;
if constexpr (std::is_same_v<S, dynamic::CreateTable>) {
return create_table_to_sql(_s);
} else if constexpr (std::is_same_v<S, dynamic::Insert>) {
return insert_to_sql(_s);
} else {
static_assert(rfl::always_false_v<S>, "Unsupported type.");
}
+24
View File
@@ -0,0 +1,24 @@
#include <gtest/gtest.h>
#include <sqlgen.hpp>
#include <sqlgen/parsing/to_insert.hpp>
#include <sqlgen/sqlite.hpp>
namespace test_to_insert {
struct TestTable {
std::string field1;
int32_t field2;
sqlgen::PrimaryKey<uint32_t> id;
std::optional<std::string> nullable;
};
TEST(sqlite, test_to_insert) {
const auto insert_stmt = sqlgen::parsing::to_insert<TestTable>();
const auto conn = sqlgen::sqlite::connect().value();
const auto expected =
R"(INSERT INTO "TestTable" ("field1", "field2", "id", "nullable") VALUES (?, ?, ?, ?);)";
EXPECT_EQ(conn->to_sql(insert_stmt), expected);
}
} // namespace test_to_insert