mirror of
https://github.com/getml/sqlgen.git
synced 2026-05-01 12:39:41 -05:00
Added tests for postgres
This commit is contained in:
@@ -8,6 +8,8 @@ option(SQLGEN_SQLITE3 "Enable SQLite3 support" ON) # enabled by default
|
||||
|
||||
option(SQLGEN_BUILD_TESTS "Build tests" OFF)
|
||||
|
||||
option(SQLGEN_BUILD_DRY_TESTS_ONLY "Build 'dry' tests only (those that do not require a database connection)" OFF)
|
||||
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
if (NOT DEFINED CMAKE_CXX_STANDARD)
|
||||
set(CMAKE_CXX_STANDARD 20)
|
||||
|
||||
@@ -225,7 +225,7 @@ std::string insert_to_sql(const dynamic::Insert& _stmt) noexcept {
|
||||
", ",
|
||||
internal::collect::vector(_stmt.columns | transform(wrap_in_quotes)));
|
||||
return "COPY " + schema + "." + table + "(" + colnames +
|
||||
") FROM STDIN WITH DELIMITER '\t' NULL '\e' QUOTE '\a';";
|
||||
") FROM STDIN WITH DELIMITER '\t' NULL '\e' CSV QUOTE '\a';";
|
||||
}
|
||||
|
||||
std::string select_from_to_sql(const dynamic::SelectFrom& _stmt) noexcept {
|
||||
|
||||
+3
-18
@@ -1,27 +1,12 @@
|
||||
project(sqlgen-tests)
|
||||
|
||||
file(GLOB_RECURSE SOURCES CONFIGURE_DEPENDS "*.cpp")
|
||||
|
||||
add_executable(
|
||||
sqlgen-tests
|
||||
${SOURCES}
|
||||
)
|
||||
target_precompile_headers(sqlgen-tests PRIVATE [["sqlgen.hpp"]] <iostream> <string> <functional> <gtest/gtest.h>)
|
||||
|
||||
if (MSVC)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std:c++20")
|
||||
else()
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3 -Wall -Werror -ggdb -fconcepts-diagnostics-depth=5")
|
||||
endif()
|
||||
|
||||
target_link_libraries(
|
||||
sqlgen-tests
|
||||
PRIVATE
|
||||
"${SQLGEN_GTEST_LIB}"
|
||||
)
|
||||
|
||||
find_package(GTest)
|
||||
gtest_discover_tests(sqlgen-tests)
|
||||
if (SQLGEN_BUILD_DRY_TESTS_ONLY)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSQLGEN_BUILD_DRY_TESTS_ONLY")
|
||||
endif()
|
||||
|
||||
if(SQLGEN_POSTGRES)
|
||||
add_subdirectory(postgres)
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
#ifndef SQLGEN_BUILD_DRY_TESTS_ONLY
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <rfl.hpp>
|
||||
#include <rfl/json.hpp>
|
||||
#include <sqlgen.hpp>
|
||||
#include <sqlgen/postgres.hpp>
|
||||
#include <vector>
|
||||
|
||||
namespace test_delete_from {
|
||||
|
||||
struct Person {
|
||||
sqlgen::PrimaryKey<uint32_t> id;
|
||||
std::string first_name;
|
||||
std::string last_name;
|
||||
int age;
|
||||
};
|
||||
|
||||
TEST(postgres, test_delete_from) {
|
||||
const auto people1 = std::vector<Person>(
|
||||
{Person{
|
||||
.id = 0, .first_name = "Homer", .last_name = "Simpson", .age = 45},
|
||||
Person{.id = 1, .first_name = "Bart", .last_name = "Simpson", .age = 10},
|
||||
Person{.id = 2, .first_name = "Lisa", .last_name = "Simpson", .age = 8},
|
||||
Person{
|
||||
.id = 3, .first_name = "Maggie", .last_name = "Simpson", .age = 0},
|
||||
Person{
|
||||
.id = 4, .first_name = "Hugo", .last_name = "Simpson", .age = 10}});
|
||||
|
||||
const auto credentials = sqlgen::postgres::Credentials{.user = "postgres",
|
||||
.password = "password",
|
||||
.host = "localhost",
|
||||
.dbname = "postgres"};
|
||||
|
||||
using namespace sqlgen;
|
||||
|
||||
const auto conn =
|
||||
sqlgen::postgres::connect(credentials).and_then(drop<Person> | if_exists);
|
||||
|
||||
sqlgen::write(conn, people1).value();
|
||||
|
||||
const auto delete_hugo =
|
||||
delete_from<Person> | where("first_name"_c == "Hugo");
|
||||
|
||||
const auto people2 =
|
||||
conn.and_then(delete_hugo)
|
||||
.and_then(sqlgen::read<std::vector<Person>> | order_by("id"_c))
|
||||
.value();
|
||||
|
||||
const std::string expected =
|
||||
R"([{"id":0,"first_name":"Homer","last_name":"Simpson","age":45},{"id":1,"first_name":"Bart","last_name":"Simpson","age":10},{"id":2,"first_name":"Lisa","last_name":"Simpson","age":8},{"id":3,"first_name":"Maggie","last_name":"Simpson","age":0}])";
|
||||
|
||||
EXPECT_EQ(rfl::json::write(people2), expected);
|
||||
}
|
||||
|
||||
} // namespace test_delete_from
|
||||
|
||||
#endif
|
||||
@@ -17,7 +17,7 @@ TEST(postgres, test_insert_dry) {
|
||||
|
||||
const auto expected =
|
||||
"COPY \"public\".\"TestTable\"(\"field1\", \"field2\", \"id\", "
|
||||
"\"nullable\") FROM STDIN WITH DELIMITER '\t' NULL '\e' QUOTE '\a';";
|
||||
"\"nullable\") FROM STDIN WITH DELIMITER '\t' NULL '\e' CSV QUOTE '\a';";
|
||||
|
||||
EXPECT_EQ(sqlgen::postgres::to_sql(query), expected);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
#ifndef SQLGEN_BUILD_DRY_TESTS_ONLY
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <rfl.hpp>
|
||||
#include <rfl/json.hpp>
|
||||
#include <sqlgen.hpp>
|
||||
#include <sqlgen/postgres.hpp>
|
||||
#include <vector>
|
||||
|
||||
namespace test_limit {
|
||||
|
||||
struct Person {
|
||||
sqlgen::PrimaryKey<uint32_t> id;
|
||||
std::string first_name;
|
||||
std::string last_name;
|
||||
int age;
|
||||
};
|
||||
|
||||
TEST(postgres, test_limit) {
|
||||
const auto people1 = std::vector<Person>(
|
||||
{Person{
|
||||
.id = 0, .first_name = "Homer", .last_name = "Simpson", .age = 45},
|
||||
Person{.id = 1, .first_name = "Bart", .last_name = "Simpson", .age = 10},
|
||||
Person{.id = 2, .first_name = "Lisa", .last_name = "Simpson", .age = 8},
|
||||
Person{
|
||||
.id = 3, .first_name = "Maggie", .last_name = "Simpson", .age = 0},
|
||||
Person{
|
||||
.id = 4, .first_name = "Hugo", .last_name = "Simpson", .age = 10}});
|
||||
|
||||
const auto credentials = sqlgen::postgres::Credentials{.user = "postgres",
|
||||
.password = "password",
|
||||
.host = "localhost",
|
||||
.dbname = "postgres"};
|
||||
|
||||
using namespace sqlgen;
|
||||
|
||||
const auto conn =
|
||||
sqlgen::postgres::connect(credentials).and_then(drop<Person> | if_exists);
|
||||
|
||||
sqlgen::write(conn, people1).value();
|
||||
|
||||
const auto query =
|
||||
sqlgen::read<std::vector<Person>> | order_by("age"_c) | limit(2);
|
||||
|
||||
const auto people2 = query(conn).value();
|
||||
|
||||
const std::string expected =
|
||||
R"([{"id":3,"first_name":"Maggie","last_name":"Simpson","age":0},{"id":2,"first_name":"Lisa","last_name":"Simpson","age":8}])";
|
||||
|
||||
EXPECT_EQ(rfl::json::write(people2), expected);
|
||||
}
|
||||
|
||||
} // namespace test_limit
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,63 @@
|
||||
#ifndef SQLGEN_BUILD_DRY_TESTS_ONLY
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <ranges>
|
||||
#include <rfl.hpp>
|
||||
#include <rfl/json.hpp>
|
||||
#include <sqlgen.hpp>
|
||||
#include <sqlgen/postgres.hpp>
|
||||
#include <vector>
|
||||
|
||||
namespace test_range {
|
||||
|
||||
struct Person {
|
||||
sqlgen::PrimaryKey<uint32_t> id;
|
||||
std::string first_name;
|
||||
std::string last_name;
|
||||
int age;
|
||||
};
|
||||
|
||||
TEST(postgres, test_range) {
|
||||
static_assert(std::ranges::input_range<sqlgen::Range<Person>>,
|
||||
"Must be an input range.");
|
||||
|
||||
const auto people1 = std::vector<Person>(
|
||||
{Person{
|
||||
.id = 0, .first_name = "Homer", .last_name = "Simpson", .age = 45},
|
||||
Person{.id = 1, .first_name = "Bart", .last_name = "Simpson", .age = 10},
|
||||
Person{.id = 2, .first_name = "Lisa", .last_name = "Simpson", .age = 8},
|
||||
Person{
|
||||
.id = 3, .first_name = "Maggie", .last_name = "Simpson", .age = 0}});
|
||||
|
||||
const auto credentials = sqlgen::postgres::Credentials{.user = "postgres",
|
||||
.password = "password",
|
||||
.host = "localhost",
|
||||
.dbname = "postgres"};
|
||||
|
||||
using namespace sqlgen;
|
||||
|
||||
const auto conn =
|
||||
sqlgen::postgres::connect(credentials).and_then(drop<Person> | if_exists);
|
||||
|
||||
const auto people2 =
|
||||
sqlgen::write(conn, people1)
|
||||
.and_then(sqlgen::read<sqlgen::Range<Person>> | order_by("id"_c))
|
||||
.value();
|
||||
|
||||
using namespace std::ranges::views;
|
||||
|
||||
const auto first_names =
|
||||
internal::collect::vector(people2 | transform([](const auto& _r) {
|
||||
return _r.value().first_name;
|
||||
}));
|
||||
|
||||
EXPECT_EQ(first_names.at(0), "Homer");
|
||||
EXPECT_EQ(first_names.at(1), "Bart");
|
||||
EXPECT_EQ(first_names.at(2), "Lisa");
|
||||
EXPECT_EQ(first_names.at(3), "Maggie");
|
||||
}
|
||||
|
||||
} // namespace test_range
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,47 @@
|
||||
#ifndef SQLGEN_BUILD_DRY_TESTS_ONLY
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <rfl/json.hpp>
|
||||
#include <sqlgen.hpp>
|
||||
#include <sqlgen/postgres.hpp>
|
||||
|
||||
namespace test_timestamp {
|
||||
|
||||
struct Person {
|
||||
sqlgen::PrimaryKey<uint32_t> id;
|
||||
std::string first_name;
|
||||
std::string last_name;
|
||||
sqlgen::Timestamp<"%Y-%m-%d %H:%M:%S"> ts;
|
||||
};
|
||||
|
||||
TEST(postgres, test_timestamp) {
|
||||
const auto people1 =
|
||||
std::vector<Person>({Person{.id = 0,
|
||||
.first_name = "Homer",
|
||||
.last_name = "Simpson",
|
||||
.ts = "2000-01-01 01:00:00"}});
|
||||
|
||||
using namespace sqlgen;
|
||||
|
||||
const auto credentials = sqlgen::postgres::Credentials{.user = "postgres",
|
||||
.password = "password",
|
||||
.host = "localhost",
|
||||
.dbname = "postgres"};
|
||||
|
||||
const auto conn =
|
||||
sqlgen::postgres::connect(credentials).and_then(drop<Person> | if_exists);
|
||||
|
||||
const auto people2 = sqlgen::write(conn, people1)
|
||||
.and_then(sqlgen::read<std::vector<Person>>)
|
||||
.value();
|
||||
|
||||
const auto json1 = rfl::json::write(people1);
|
||||
const auto json2 = rfl::json::write(people2);
|
||||
|
||||
EXPECT_EQ(json1, json2);
|
||||
}
|
||||
|
||||
} // namespace test_timestamp
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,47 @@
|
||||
#ifndef SQLGEN_BUILD_DRY_TESTS_ONLY
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <rfl/json.hpp>
|
||||
#include <sqlgen.hpp>
|
||||
#include <sqlgen/postgres.hpp>
|
||||
|
||||
namespace test_timestamp_with_tz {
|
||||
|
||||
struct Person {
|
||||
sqlgen::PrimaryKey<uint32_t> id;
|
||||
std::string first_name;
|
||||
std::string last_name;
|
||||
sqlgen::Timestamp<"%Y-%m-%d %H:%M:%S%z"> ts;
|
||||
};
|
||||
|
||||
TEST(postgres, test_timestamp_with_tz) {
|
||||
const auto people1 =
|
||||
std::vector<Person>({Person{.id = 0,
|
||||
.first_name = "Homer",
|
||||
.last_name = "Simpson",
|
||||
.ts = "2000-01-01 01:00:00+0100"}});
|
||||
|
||||
using namespace sqlgen;
|
||||
|
||||
const auto credentials = postgres::Credentials{.user = "postgres",
|
||||
.password = "password",
|
||||
.host = "localhost",
|
||||
.dbname = "postgres"};
|
||||
|
||||
const auto conn =
|
||||
postgres::connect(credentials).and_then(drop<Person> | if_exists);
|
||||
|
||||
const auto people2 = sqlgen::write(conn, people1)
|
||||
.and_then(sqlgen::read<std::vector<Person>>)
|
||||
.value();
|
||||
|
||||
const auto json1 = rfl::json::write(people1);
|
||||
const auto json2 = rfl::json::write(people2);
|
||||
|
||||
EXPECT_EQ(json1, json2);
|
||||
}
|
||||
|
||||
} // namespace test_timestamp_with_tz
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,62 @@
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <rfl.hpp>
|
||||
#include <rfl/json.hpp>
|
||||
#include <sqlgen.hpp>
|
||||
#include <sqlgen/postgres.hpp>
|
||||
#include <vector>
|
||||
|
||||
namespace test_update {
|
||||
|
||||
struct Person {
|
||||
sqlgen::PrimaryKey<uint32_t> id;
|
||||
std::string first_name;
|
||||
std::string last_name;
|
||||
int age;
|
||||
};
|
||||
|
||||
TEST(postgres, test_transaction) {
|
||||
const auto people1 = std::vector<Person>(
|
||||
{Person{
|
||||
.id = 0, .first_name = "Homer", .last_name = "Simpson", .age = 45},
|
||||
Person{.id = 1, .first_name = "Bart", .last_name = "Simpson", .age = 10},
|
||||
Person{.id = 2, .first_name = "Lisa", .last_name = "Simpson", .age = 8},
|
||||
Person{
|
||||
.id = 3, .first_name = "Maggie", .last_name = "Simpson", .age = 0},
|
||||
Person{
|
||||
.id = 4, .first_name = "Hugo", .last_name = "Simpson", .age = 10}});
|
||||
|
||||
const auto credentials = sqlgen::postgres::Credentials{.user = "postgres",
|
||||
.password = "password",
|
||||
.host = "localhost",
|
||||
.dbname = "postgres"};
|
||||
|
||||
using namespace sqlgen;
|
||||
|
||||
const auto conn =
|
||||
postgres::connect(credentials).and_then(drop<Person> | if_exists);
|
||||
|
||||
sqlgen::write(conn, people1).value();
|
||||
|
||||
const auto delete_hugo =
|
||||
delete_from<Person> | where("first_name"_c == "Hugo");
|
||||
|
||||
const auto update_homers_age =
|
||||
update<Person>("age"_c.set(46)) | where("first_name"_c == "Homer");
|
||||
|
||||
const auto get_data = sqlgen::read<std::vector<Person>> | order_by("id"_c);
|
||||
|
||||
const auto people2 = begin_transaction(conn)
|
||||
.and_then(delete_hugo)
|
||||
.and_then(update_homers_age)
|
||||
.and_then(commit)
|
||||
.and_then(get_data)
|
||||
.value();
|
||||
|
||||
const std::string expected =
|
||||
R"([{"id":0,"first_name":"Homer","last_name":"Simpson","age":46},{"id":1,"first_name":"Bart","last_name":"Simpson","age":10},{"id":2,"first_name":"Lisa","last_name":"Simpson","age":8},{"id":3,"first_name":"Maggie","last_name":"Simpson","age":0}])";
|
||||
|
||||
EXPECT_EQ(rfl::json::write(people2), expected);
|
||||
}
|
||||
|
||||
} // namespace test_update
|
||||
@@ -0,0 +1,60 @@
|
||||
#ifndef SQLGEN_BUILD_DRY_TESTS_ONLY
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <rfl.hpp>
|
||||
#include <rfl/json.hpp>
|
||||
#include <sqlgen.hpp>
|
||||
#include <sqlgen/postgres.hpp>
|
||||
#include <vector>
|
||||
|
||||
namespace test_update {
|
||||
|
||||
struct Person {
|
||||
sqlgen::PrimaryKey<uint32_t> id;
|
||||
std::string first_name;
|
||||
std::string last_name;
|
||||
int age;
|
||||
};
|
||||
|
||||
TEST(postgres, test_update) {
|
||||
const auto people1 = std::vector<Person>(
|
||||
{Person{
|
||||
.id = 0, .first_name = "Homer", .last_name = "Simpson", .age = 45},
|
||||
Person{.id = 1, .first_name = "Bart", .last_name = "Simpson", .age = 10},
|
||||
Person{.id = 2, .first_name = "Lisa", .last_name = "Simpson", .age = 8},
|
||||
Person{
|
||||
.id = 3, .first_name = "Maggie", .last_name = "Simpson", .age = 0},
|
||||
Person{
|
||||
.id = 4, .first_name = "Hugo", .last_name = "Simpson", .age = 10}});
|
||||
|
||||
const auto credentials = sqlgen::postgres::Credentials{.user = "postgres",
|
||||
.password = "password",
|
||||
.host = "localhost",
|
||||
.dbname = "postgres"};
|
||||
|
||||
using namespace sqlgen;
|
||||
|
||||
const auto conn =
|
||||
sqlgen::postgres::connect(credentials).and_then(drop<Person> | if_exists);
|
||||
|
||||
sqlgen::write(conn, people1).value();
|
||||
|
||||
const auto update_hugos_age =
|
||||
update<Person>("first_name"_c.set("last_name"_c), "age"_c.set(100)) |
|
||||
where("first_name"_c == "Hugo");
|
||||
|
||||
const auto people2 =
|
||||
conn.and_then(update_hugos_age)
|
||||
.and_then(sqlgen::read<std::vector<Person>> | order_by("id"_c))
|
||||
.value();
|
||||
|
||||
const std::string expected =
|
||||
R"([{"id":0,"first_name":"Homer","last_name":"Simpson","age":45},{"id":1,"first_name":"Bart","last_name":"Simpson","age":10},{"id":2,"first_name":"Lisa","last_name":"Simpson","age":8},{"id":3,"first_name":"Maggie","last_name":"Simpson","age":0},{"id":4,"first_name":"Simpson","last_name":"Simpson","age":100}])";
|
||||
|
||||
EXPECT_EQ(rfl::json::write(people2), expected);
|
||||
}
|
||||
|
||||
} // namespace test_update
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,52 @@
|
||||
|
||||
#ifndef SQLGEN_BUILD_DRY_TESTS_ONLY
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <rfl.hpp>
|
||||
#include <rfl/json.hpp>
|
||||
#include <sqlgen.hpp>
|
||||
#include <sqlgen/postgres.hpp>
|
||||
#include <vector>
|
||||
|
||||
namespace test_varchar {
|
||||
|
||||
struct Person {
|
||||
sqlgen::PrimaryKey<uint32_t> id;
|
||||
sqlgen::Varchar<6> first_name;
|
||||
sqlgen::Varchar<7> last_name;
|
||||
int age;
|
||||
};
|
||||
|
||||
TEST(postgres, test_varchar) {
|
||||
const auto people1 = std::vector<Person>(
|
||||
{Person{
|
||||
.id = 0, .first_name = "Homer", .last_name = "Simpson", .age = 45},
|
||||
Person{.id = 1, .first_name = "Bart", .last_name = "Simpson", .age = 10},
|
||||
Person{.id = 2, .first_name = "Lisa", .last_name = "Simpson", .age = 8},
|
||||
Person{
|
||||
.id = 3, .first_name = "Maggie", .last_name = "Simpson", .age = 0}});
|
||||
|
||||
const auto credentials = sqlgen::postgres::Credentials{.user = "postgres",
|
||||
.password = "password",
|
||||
.host = "localhost",
|
||||
.dbname = "postgres"};
|
||||
|
||||
using namespace sqlgen;
|
||||
|
||||
const auto conn =
|
||||
sqlgen::postgres::connect(credentials).and_then(drop<Person> | if_exists);
|
||||
|
||||
sqlgen::write(conn, people1).value();
|
||||
|
||||
const auto people2 = sqlgen::read<std::vector<Person>>(conn).value();
|
||||
|
||||
const auto json1 = rfl::json::write(people1);
|
||||
const auto json2 = rfl::json::write(people2);
|
||||
|
||||
EXPECT_EQ(json1, json2);
|
||||
}
|
||||
|
||||
} // namespace test_varchar
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,57 @@
|
||||
#ifndef SQLGEN_BUILD_DRY_TESTS_ONLY
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <rfl.hpp>
|
||||
#include <rfl/json.hpp>
|
||||
#include <sqlgen.hpp>
|
||||
#include <sqlgen/postgres.hpp>
|
||||
#include <vector>
|
||||
|
||||
namespace test_where {
|
||||
|
||||
struct Person {
|
||||
sqlgen::PrimaryKey<uint32_t> id;
|
||||
std::string first_name;
|
||||
std::string last_name;
|
||||
int age;
|
||||
};
|
||||
|
||||
TEST(postgres, test_where) {
|
||||
const auto people1 = std::vector<Person>(
|
||||
{Person{
|
||||
.id = 0, .first_name = "Homer", .last_name = "Simpson", .age = 45},
|
||||
Person{.id = 1, .first_name = "Bart", .last_name = "Simpson", .age = 10},
|
||||
Person{.id = 2, .first_name = "Lisa", .last_name = "Simpson", .age = 8},
|
||||
Person{
|
||||
.id = 3, .first_name = "Maggie", .last_name = "Simpson", .age = 0},
|
||||
Person{
|
||||
.id = 4, .first_name = "Hugo", .last_name = "Simpson", .age = 10}});
|
||||
|
||||
const auto credentials = sqlgen::postgres::Credentials{.user = "postgres",
|
||||
.password = "password",
|
||||
.host = "localhost",
|
||||
.dbname = "postgres"};
|
||||
|
||||
using namespace sqlgen;
|
||||
|
||||
const auto conn =
|
||||
sqlgen::postgres::connect(credentials).and_then(drop<Person> | if_exists);
|
||||
|
||||
sqlgen::write(conn, people1).value();
|
||||
|
||||
const auto query = sqlgen::read<std::vector<Person>> |
|
||||
where("age"_c < 18 and "first_name"_c != "Hugo") |
|
||||
order_by("age"_c);
|
||||
|
||||
const auto people2 = query(conn).value();
|
||||
|
||||
const std::string expected =
|
||||
R"([{"id":3,"first_name":"Maggie","last_name":"Simpson","age":0},{"id":2,"first_name":"Lisa","last_name":"Simpson","age":8},{"id":1,"first_name":"Bart","last_name":"Simpson","age":10}])";
|
||||
|
||||
EXPECT_EQ(rfl::json::write(people2), expected);
|
||||
}
|
||||
|
||||
} // namespace test_where
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,51 @@
|
||||
#ifndef SQLGEN_BUILD_DRY_TESTS_ONLY
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <rfl.hpp>
|
||||
#include <rfl/json.hpp>
|
||||
#include <sqlgen.hpp>
|
||||
#include <sqlgen/postgres.hpp>
|
||||
#include <vector>
|
||||
|
||||
namespace test_write_and_read {
|
||||
|
||||
struct Person {
|
||||
sqlgen::PrimaryKey<uint32_t> id;
|
||||
std::string first_name;
|
||||
std::string last_name;
|
||||
int age;
|
||||
};
|
||||
|
||||
TEST(postgres, test_write_and_read) {
|
||||
const auto people1 = std::vector<Person>(
|
||||
{Person{
|
||||
.id = 0, .first_name = "Homer", .last_name = "Simpson", .age = 45},
|
||||
Person{.id = 1, .first_name = "Bart", .last_name = "Simpson", .age = 10},
|
||||
Person{.id = 2, .first_name = "Lisa", .last_name = "Simpson", .age = 8},
|
||||
Person{
|
||||
.id = 3, .first_name = "Maggie", .last_name = "Simpson", .age = 0}});
|
||||
|
||||
const auto credentials = sqlgen::postgres::Credentials{.user = "postgres",
|
||||
.password = "password",
|
||||
.host = "localhost",
|
||||
.dbname = "postgres"};
|
||||
|
||||
using namespace sqlgen;
|
||||
|
||||
const auto conn =
|
||||
postgres::connect(credentials).and_then(drop<Person> | if_exists);
|
||||
|
||||
const auto people2 = sqlgen::write(conn, people1)
|
||||
.and_then(sqlgen::read<std::vector<Person>>)
|
||||
.value();
|
||||
|
||||
const auto json1 = rfl::json::write(people1);
|
||||
const auto json2 = rfl::json::write(people2);
|
||||
|
||||
EXPECT_EQ(json1, json2);
|
||||
}
|
||||
|
||||
} // namespace test_write_and_read
|
||||
|
||||
#endif
|
||||
@@ -15,7 +15,7 @@ struct Person {
|
||||
sqlgen::Timestamp<"%Y-%m-%d %H:%M:%S"> birthdate;
|
||||
};
|
||||
|
||||
TEST(sqlite, test_birthdate) {
|
||||
TEST(sqlite, test_timestamp) {
|
||||
const auto people1 =
|
||||
std::vector<Person>({Person{.id = 0,
|
||||
.first_name = "Homer",
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <sqlgen.hpp>
|
||||
#include <sqlgen/transpilation/to_create_table.hpp>
|
||||
|
||||
namespace test_schema {
|
||||
|
||||
struct TestTable {
|
||||
static constexpr const char* schema = "test";
|
||||
|
||||
std::string field1;
|
||||
int32_t field2;
|
||||
sqlgen::PrimaryKey<uint32_t> id;
|
||||
std::optional<std::string> nullable;
|
||||
};
|
||||
|
||||
TEST(general, test_schema) {
|
||||
const auto create_table_stmt =
|
||||
sqlgen::transpilation::to_create_table<TestTable>();
|
||||
|
||||
EXPECT_EQ(create_table_stmt.table.schema, "test");
|
||||
}
|
||||
} // namespace test_schema
|
||||
@@ -1,23 +0,0 @@
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <sqlgen.hpp>
|
||||
#include <sqlgen/transpilation/to_create_table.hpp>
|
||||
|
||||
namespace test_tablename {
|
||||
|
||||
struct TestTable {
|
||||
static constexpr const char* tablename = "TEST_TABLE";
|
||||
|
||||
std::string field1;
|
||||
int32_t field2;
|
||||
sqlgen::PrimaryKey<uint32_t> id;
|
||||
std::optional<std::string> nullable;
|
||||
};
|
||||
|
||||
TEST(general, test_tablename) {
|
||||
const auto create_table_stmt =
|
||||
sqlgen::transpilation::to_create_table<TestTable>();
|
||||
|
||||
EXPECT_EQ(create_table_stmt.table.name, "TEST_TABLE");
|
||||
}
|
||||
} // namespace test_tablename
|
||||
@@ -1,27 +0,0 @@
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <rfl/json.hpp>
|
||||
#include <sqlgen.hpp>
|
||||
#include <sqlgen/transpilation/to_create_table.hpp>
|
||||
|
||||
namespace test_to_create_table {
|
||||
|
||||
struct TestTable {
|
||||
std::string field1;
|
||||
int32_t field2;
|
||||
sqlgen::PrimaryKey<uint32_t> id;
|
||||
std::optional<std::string> nullable;
|
||||
};
|
||||
|
||||
TEST(general, test_to_create_table) {
|
||||
const auto create_table_stmt =
|
||||
sqlgen::transpilation::to_create_table<TestTable>();
|
||||
|
||||
const std::string expected =
|
||||
R"({"table":{"name":"TestTable"},"columns":[{"name":"field1","type":{"type":"Text","properties":{"primary":false,"nullable":false}}},{"name":"field2","type":{"type":"Int32","properties":{"primary":false,"nullable":false}}},{"name":"id","type":{"type":"UInt32","properties":{"primary":true,"nullable":false}}},{"name":"nullable","type":{"type":"Text","properties":{"primary":false,"nullable":true}}}],"if_not_exists":true})";
|
||||
|
||||
const auto json_str = rfl::json::write(create_table_stmt);
|
||||
|
||||
EXPECT_EQ(json_str, expected);
|
||||
}
|
||||
} // namespace test_to_create_table
|
||||
@@ -1,26 +0,0 @@
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <rfl/json.hpp>
|
||||
#include <sqlgen.hpp>
|
||||
#include <sqlgen/transpilation/to_insert.hpp>
|
||||
|
||||
namespace test_to_insert {
|
||||
|
||||
struct TestTable {
|
||||
std::string field1;
|
||||
int32_t field2;
|
||||
sqlgen::PrimaryKey<uint32_t> id;
|
||||
std::optional<std::string> nullable;
|
||||
};
|
||||
|
||||
TEST(general, test_to_insert) {
|
||||
const auto insert_stmt = sqlgen::transpilation::to_insert<TestTable>();
|
||||
|
||||
const std::string expected =
|
||||
R"({"table":{"name":"TestTable"},"columns":["field1","field2","id","nullable"]})";
|
||||
|
||||
const auto json_str = rfl::json::write(insert_stmt);
|
||||
|
||||
EXPECT_EQ(json_str, expected);
|
||||
}
|
||||
} // namespace test_to_insert
|
||||
@@ -1,27 +0,0 @@
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <rfl/json.hpp>
|
||||
#include <sqlgen.hpp>
|
||||
#include <sqlgen/transpilation/to_select_from.hpp>
|
||||
|
||||
namespace test_to_select_from {
|
||||
|
||||
struct TestTable {
|
||||
std::string field1;
|
||||
int32_t field2;
|
||||
sqlgen::PrimaryKey<uint32_t> id;
|
||||
std::optional<std::string> nullable;
|
||||
};
|
||||
|
||||
TEST(general, test_to_select_from) {
|
||||
const auto select_from_stmt =
|
||||
sqlgen::transpilation::to_select_from<TestTable>();
|
||||
|
||||
const std::string expected =
|
||||
R"({"table":{"name":"TestTable"},"columns":[{"name":"field1","type":{"type":"Text","properties":{"primary":false,"nullable":false}}},{"name":"field2","type":{"type":"Int32","properties":{"primary":false,"nullable":false}}},{"name":"id","type":{"type":"UInt32","properties":{"primary":true,"nullable":false}}},{"name":"nullable","type":{"type":"Text","properties":{"primary":false,"nullable":true}}}]})";
|
||||
|
||||
const auto json_str = rfl::json::write(select_from_stmt);
|
||||
|
||||
EXPECT_EQ(json_str, expected);
|
||||
}
|
||||
} // namespace test_to_select_from
|
||||
Reference in New Issue
Block a user